",
+ "MacAlgorithm": "HMAC_SHA_384",
+ "Message": "Hello World"
+ },
+ "output": {
+ "KeyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
+ "MacAlgorithm": "HMAC_SHA_384",
+ "MacValid": true
+ },
+ "comments": {
+ "input": {
+ "KeyId": "The HMAC KMS key input to the HMAC algorithm.",
+ "Mac": "The HMAC to be verified.",
+ "MacAlgorithm": "The HMAC algorithm requested for the operation.",
+ "Message": "The message input to the HMAC algorithm."
+ },
+ "output": {
+ "KeyId": "The key ARN of the HMAC key used in the operation.",
+ "MacAlgorithm": "The HMAC algorithm used in the operation.",
+ "MacValid": "A value of 'true' indicates that verification succeeded. If verification fails, the call to VerifyMac fails."
+ }
+ },
+ "description": "This example verifies an HMAC for a particular message, HMAC KMS keys, and MAC algorithm. A value of 'true' in the MacValid value in the response indicates that the HMAC is valid.",
+ "id": "to-verify-an-hmac-1631570863401",
+ "title": "To verify an HMAC"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/kms/2014-11-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/kms/2014-11-01/paginators-1.json
new file mode 100644
index 0000000000..dc6690f5eb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/kms/2014-11-01/paginators-1.json
@@ -0,0 +1,53 @@
+{
+ "pagination": {
+ "ListAliases": {
+ "limit_key": "Limit",
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "more_results": "Truncated",
+ "result_key": "Aliases"
+ },
+ "ListGrants": {
+ "limit_key": "Limit",
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "more_results": "Truncated",
+ "result_key": "Grants"
+ },
+ "ListKeyPolicies": {
+ "limit_key": "Limit",
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "more_results": "Truncated",
+ "result_key": "PolicyNames"
+ },
+ "ListKeys": {
+ "limit_key": "Limit",
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "more_results": "Truncated",
+ "result_key": "Keys"
+ },
+ "DescribeCustomKeyStores": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "more_results": "Truncated",
+ "output_token": "NextMarker",
+ "result_key": "CustomKeyStores"
+ },
+ "ListResourceTags": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "more_results": "Truncated",
+ "output_token": "NextMarker",
+ "result_key": "Tags"
+ },
+ "ListRetirableGrants": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "more_results": "Truncated",
+ "output_token": "NextMarker",
+ "result_key": "Grants"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/kms/2014-11-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/kms/2014-11-01/service-2.json.gz
new file mode 100644
index 0000000000..35c211c93c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/kms/2014-11-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..950dd692dc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/paginators-1.json
new file mode 100644
index 0000000000..006a98c89f
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "GetWorkUnits": {
+ "input_token": "NextToken",
+ "limit_key": "PageSize",
+ "output_token": "NextToken",
+ "result_key": "WorkUnitRanges"
+ },
+ "ListDataCellsFilter": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DataCellsFilters"
+ },
+ "ListLFTags": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LFTags"
+ },
+ "SearchDatabasesByLFTags": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DatabaseList"
+ },
+ "SearchTablesByLFTags": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "TableList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..aea980d66c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/paginators-1.sdk-extras.json
@@ -0,0 +1,12 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "GetWorkUnits": {
+ "non_aggregate_keys": [
+ "QueryId"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/service-2.json.gz
new file mode 100644
index 0000000000..4f976c6cbb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lakeformation/2017-03-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2014-11-11/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2014-11-11/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..24e0aebe4e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2014-11-11/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2014-11-11/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2014-11-11/service-2.json.gz
new file mode 100644
index 0000000000..a9c0fb53b4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2014-11-11/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..aab35f9b67
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/examples-1.json
new file mode 100644
index 0000000000..c33c1bbef1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/examples-1.json
@@ -0,0 +1,1513 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AddLayerVersionPermission": [
+ {
+ "input": {
+ "Action": "lambda:GetLayerVersion",
+ "LayerName": "my-layer",
+ "Principal": "223456789012",
+ "StatementId": "xaccount",
+ "VersionNumber": 1
+ },
+ "output": {
+ "RevisionId": "35d87451-f796-4a3f-a618-95a3671b0a0c",
+ "Statement": "{\"Sid\":\"xaccount\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::223456789012:root\"},\"Action\":\"lambda:GetLayerVersion\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:layer:my-layer:1\"}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example grants permission for the account 223456789012 to use version 1 of a layer named my-layer.",
+ "id": "to-add-permissions-to-a-layer-version-1586479797163",
+ "title": "To add permissions to a layer version"
+ }
+ ],
+ "AddPermission": [
+ {
+ "input": {
+ "Action": "lambda:InvokeFunction",
+ "FunctionName": "my-function",
+ "Principal": "s3.amazonaws.com",
+ "SourceAccount": "123456789012",
+ "SourceArn": "arn:aws:s3:::my-bucket-1xpuxmplzrlbh/*",
+ "StatementId": "s3"
+ },
+ "output": {
+ "Statement": "{\"Sid\":\"s3\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function\",\"Condition\":{\"StringEquals\":{\"AWS:SourceAccount\":\"123456789012\"},\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:s3:::my-bucket-1xpuxmplzrlbh\"}}}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds permission for Amazon S3 to invoke a Lambda function named my-function for notifications from a bucket named my-bucket-1xpuxmplzrlbh in account 123456789012.",
+ "id": "add-permission-1474651469455",
+ "title": "To grant Amazon S3 permission to invoke a function"
+ },
+ {
+ "input": {
+ "Action": "lambda:InvokeFunction",
+ "FunctionName": "my-function",
+ "Principal": "223456789012",
+ "StatementId": "xaccount"
+ },
+ "output": {
+ "Statement": "{\"Sid\":\"xaccount\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::223456789012:root\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function\"}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds permission for account 223456789012 invoke a Lambda function named my-function.",
+ "id": "add-permission-1474651469456",
+ "title": "To grant another account permission to invoke a function"
+ }
+ ],
+ "CreateAlias": [
+ {
+ "input": {
+ "Description": "alias for live version of function",
+ "FunctionName": "my-function",
+ "FunctionVersion": "1",
+ "Name": "LIVE"
+ },
+ "output": {
+ "AliasArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:LIVE",
+ "Description": "alias for live version of function",
+ "FunctionVersion": "1",
+ "Name": "LIVE",
+ "RevisionId": "873282ed-xmpl-4dc8-a069-d0c647e470c6"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an alias named LIVE that points to version 1 of the my-function Lambda function.",
+ "id": "to-create-an-alias-for-a-lambda-function-1586480324259",
+ "title": "To create an alias for a Lambda function"
+ }
+ ],
+ "CreateEventSourceMapping": [
+ {
+ "input": {
+ "BatchSize": 5,
+ "EventSourceArn": "arn:aws:sqs:us-west-2:123456789012:my-queue",
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "BatchSize": 5,
+ "EventSourceArn": "arn:aws:sqs:us-west-2:123456789012:my-queue",
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "LastModified": 1569284520.333,
+ "State": "Creating",
+ "StateTransitionReason": "USER_INITIATED",
+ "UUID": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a mapping between an SQS queue and the my-function Lambda function.",
+ "id": "to-create-a-mapping-between-an-event-source-and-an-aws-lambda-function-1586480555467",
+ "title": "To create a mapping between an event source and an AWS Lambda function"
+ }
+ ],
+ "CreateFunction": [
+ {
+ "input": {
+ "Code": {
+ "S3Bucket": "my-bucket-1xpuxmplzrlbh",
+ "S3Key": "function.zip"
+ },
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "MemorySize": 256,
+ "Publish": true,
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "Tags": {
+ "DEPARTMENT": "Assets"
+ },
+ "Timeout": 15,
+ "TracingConfig": {
+ "Mode": "Active"
+ }
+ },
+ "output": {
+ "CodeSha256": "YFgDgEKG3ugvF1+pX64gV6tu9qNuIYNUdgJm8nCxsm4=",
+ "CodeSize": 5797206,
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "LastModified": "2020-04-10T19:06:32.563+0000",
+ "LastUpdateStatus": "Successful",
+ "MemorySize": 256,
+ "RevisionId": "b75dcd81-xmpl-48a8-a75a-93ba8b5b9727",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "State": "Active",
+ "Timeout": 15,
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "Version": "1"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a function with a deployment package in Amazon S3 and enables X-Ray tracing and environment variable encryption.",
+ "id": "to-create-a-function-1586492061186",
+ "title": "To create a function"
+ }
+ ],
+ "DeleteAlias": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Name": "BLUE"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an alias named BLUE from a function named my-function",
+ "id": "to-delete-a-lambda-function-alias-1481660370804",
+ "title": "To delete a Lambda function alias"
+ }
+ ],
+ "DeleteEventSourceMapping": [
+ {
+ "input": {
+ "UUID": "14e0db71-xmpl-4eb5-b481-8945cf9d10c2"
+ },
+ "output": {
+ "BatchSize": 5,
+ "EventSourceArn": "arn:aws:sqs:us-west-2:123456789012:my-queue",
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
+ "LastModified": "2016-11-21T19:49:20.006+0000",
+ "State": "Enabled",
+ "StateTransitionReason": "USER_INITIATED",
+ "UUID": "14e0db71-xmpl-4eb5-b481-8945cf9d10c2"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an event source mapping. To get a mapping's UUID, use ListEventSourceMappings.",
+ "id": "to-delete-a-lambda-function-event-source-mapping-1481658973862",
+ "title": "To delete a Lambda function event source mapping"
+ }
+ ],
+ "DeleteFunction": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "1"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes version 1 of a Lambda function named my-function.",
+ "id": "to-delete-a-lambda-function-1481648553696",
+ "title": "To delete a version of a Lambda function"
+ }
+ ],
+ "DeleteFunctionConcurrency": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes the reserved concurrent execution limit from a function named my-function.",
+ "id": "to-remove-the-reserved-concurrent-execution-limit-from-a-function-1586480714680",
+ "title": "To remove the reserved concurrent execution limit from a function"
+ }
+ ],
+ "DeleteFunctionEventInvokeConfig": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "GREEN"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes the asynchronous invocation configuration for the GREEN alias of a function named my-function.",
+ "id": "to-delete-an-asynchronous-invocation-configuration-1586481102187",
+ "title": "To delete an asynchronous invocation configuration"
+ }
+ ],
+ "DeleteLayerVersion": [
+ {
+ "input": {
+ "LayerName": "my-layer",
+ "VersionNumber": 2
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes version 2 of a layer named my-layer.",
+ "id": "to-delete-a-version-of-a-lambda-layer-1586481157547",
+ "title": "To delete a version of a Lambda layer"
+ }
+ ],
+ "DeleteProvisionedConcurrencyConfig": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "GREEN"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes the provisioned concurrency configuration for the GREEN alias of a function named my-function.",
+ "id": "to-delete-a-provisioned-concurrency-configuration-1586481032551",
+ "title": "To delete a provisioned concurrency configuration"
+ }
+ ],
+ "GetAccountSettings": [
+ {
+ "input": {
+ },
+ "output": {
+ "AccountLimit": {
+ "CodeSizeUnzipped": 262144000,
+ "CodeSizeZipped": 52428800,
+ "ConcurrentExecutions": 1000,
+ "TotalCodeSize": 80530636800,
+ "UnreservedConcurrentExecutions": 1000
+ },
+ "AccountUsage": {
+ "FunctionCount": 4,
+ "TotalCodeSize": 9426
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation takes no parameters and returns details about storage and concurrency quotas in the current Region.",
+ "id": "to-get-account-settings-1481657495274",
+ "title": "To get account settings"
+ }
+ ],
+ "GetAlias": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Name": "BLUE"
+ },
+ "output": {
+ "AliasArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function:BLUE",
+ "Description": "Production environment BLUE.",
+ "FunctionVersion": "3",
+ "Name": "BLUE",
+ "RevisionId": "594f41fb-xmpl-4c20-95c7-6ca5f2a92c93"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns details about an alias named BLUE for a function named my-function",
+ "id": "to-retrieve-a-lambda-function-alias-1481648742254",
+ "title": "To get a Lambda function alias"
+ }
+ ],
+ "GetEventSourceMapping": [
+ {
+ "input": {
+ "UUID": "14e0db71-xmpl-4eb5-b481-8945cf9d10c2"
+ },
+ "output": {
+ "BatchSize": 500,
+ "BisectBatchOnFunctionError": false,
+ "DestinationConfig": {
+ },
+ "EventSourceArn": "arn:aws:sqs:us-east-2:123456789012:mySQSqueue",
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:myFunction",
+ "LastModified": "2016-11-21T19:49:20.006+0000",
+ "LastProcessingResult": "No records processed",
+ "MaximumRecordAgeInSeconds": 604800,
+ "MaximumRetryAttempts": 10000,
+ "State": "Creating",
+ "StateTransitionReason": "User action",
+ "UUID": "14e0db71-xmpl-4eb5-b481-8945cf9d10c2"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns details about an event source mapping. To get a mapping's UUID, use ListEventSourceMappings.",
+ "id": "to-get-a-lambda-functions-event-source-mapping-1481661622799",
+ "title": "To get a Lambda function's event source mapping"
+ }
+ ],
+ "GetFunction": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "1"
+ },
+ "output": {
+ "Code": {
+ "Location": "https://awslambda-us-west-2-tasks.s3.us-west-2.amazonaws.com/snapshots/123456789012/my-function-e7d9d1ed-xmpl-4f79-904a-4b87f2681f30?versionId=sH3TQwBOaUy...",
+ "RepositoryType": "S3"
+ },
+ "Configuration": {
+ "CodeSha256": "YFgDgEKG3ugvF1+pX64gV6tu9qNuIYNUdgJm8nCxsm4=",
+ "CodeSize": 5797206,
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "LastModified": "2020-04-10T19:06:32.563+0000",
+ "LastUpdateStatus": "Successful",
+ "MemorySize": 256,
+ "RevisionId": "b75dcd81-xmpl-48a8-a75a-93ba8b5b9727",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "State": "Active",
+ "Timeout": 15,
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "Version": "$LATEST"
+ },
+ "Tags": {
+ "DEPARTMENT": "Assets"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns code and configuration details for version 1 of a function named my-function.",
+ "id": "to-get-a-lambda-function-1481661622799",
+ "title": "To get a Lambda function"
+ }
+ ],
+ "GetFunctionConcurrency": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "ReservedConcurrentExecutions": 250
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the reserved concurrency setting for a function named my-function.",
+ "id": "to-get-the-reserved-concurrency-setting-for-a-function-1586481279992",
+ "title": "To get the reserved concurrency setting for a function"
+ }
+ ],
+ "GetFunctionConfiguration": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "1"
+ },
+ "output": {
+ "CodeSha256": "YFgDgEKG3ugvF1+pX64gV6tu9qNuIYNUdgJm8nCxsm4=",
+ "CodeSize": 5797206,
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "LastModified": "2020-04-10T19:06:32.563+0000",
+ "LastUpdateStatus": "Successful",
+ "MemorySize": 256,
+ "RevisionId": "b75dcd81-xmpl-48a8-a75a-93ba8b5b9727",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "State": "Active",
+ "Timeout": 15,
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "Version": "$LATEST"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns and configuration details for version 1 of a function named my-function.",
+ "id": "to-get-a-lambda-functions-event-source-mapping-1481661622799",
+ "title": "To get a Lambda function's event source mapping"
+ }
+ ],
+ "GetFunctionEventInvokeConfig": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "BLUE"
+ },
+ "output": {
+ "DestinationConfig": {
+ "OnFailure": {
+ "Destination": "arn:aws:sqs:us-east-2:123456789012:failed-invocations"
+ },
+ "OnSuccess": {
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:BLUE",
+ "LastModified": "2016-11-21T19:49:20.006+0000",
+ "MaximumEventAgeInSeconds": 3600,
+ "MaximumRetryAttempts": 0
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the asynchronous invocation configuration for the BLUE alias of a function named my-function.",
+ "id": "to-get-an-asynchronous-invocation-configuration-1586481338463",
+ "title": "To get an asynchronous invocation configuration"
+ }
+ ],
+ "GetLayerVersion": [
+ {
+ "input": {
+ "LayerName": "my-layer",
+ "VersionNumber": 1
+ },
+ "output": {
+ "CompatibleRuntimes": [
+ "python3.6",
+ "python3.7"
+ ],
+ "Content": {
+ "CodeSha256": "tv9jJO+rPbXUUXuRKi7CwHzKtLDkDRJLB3cC3Z/ouXo=",
+ "CodeSize": 169,
+ "Location": "https://awslambda-us-east-2-layers.s3.us-east-2.amazonaws.com/snapshots/123456789012/my-layer-4aaa2fbb-ff77-4b0a-ad92-5b78a716a96a?versionId=27iWyA73cCAYqyH..."
+ },
+ "CreatedDate": "2018-11-14T23:03:52.894+0000",
+ "Description": "My Python layer",
+ "LayerArn": "arn:aws:lambda:us-east-2:123456789012:layer:my-layer",
+ "LayerVersionArn": "arn:aws:lambda:us-east-2:123456789012:layer:my-layer:1",
+ "LicenseInfo": "MIT",
+ "Version": 1
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns information for version 1 of a layer named my-layer.",
+ "id": "to-get-information-about-a-lambda-layer-version-1586481457839",
+ "title": "To get information about a Lambda layer version"
+ }
+ ],
+ "GetLayerVersionByArn": [
+ {
+ "input": {
+ "Arn": "arn:aws:lambda:ca-central-1:123456789012:layer:blank-python-lib:3"
+ },
+ "output": {
+ "CompatibleRuntimes": [
+ "python3.8"
+ ],
+ "Content": {
+ "CodeSha256": "6x+xmpl/M3BnQUk7gS9sGmfeFsR/npojXoA3fZUv4eU=",
+ "CodeSize": 9529009,
+ "Location": "https://awslambda-us-east-2-layers.s3.us-east-2.amazonaws.com/snapshots/123456789012/blank-python-lib-e5212378-xmpl-44ee-8398-9d8ec5113949?versionId=WbZnvf..."
+ },
+ "CreatedDate": "2020-03-31T00:35:18.949+0000",
+ "Description": "Dependencies for the blank-python sample app.",
+ "LayerArn": "arn:aws:lambda:us-east-2:123456789012:layer:blank-python-lib",
+ "LayerVersionArn": "arn:aws:lambda:us-east-2:123456789012:layer:blank-python-lib:3",
+ "Version": 3
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns information about the layer version with the specified Amazon Resource Name (ARN).",
+ "id": "to-get-information-about-a-lambda-layer-version-1586481457839",
+ "title": "To get information about a Lambda layer version"
+ }
+ ],
+ "GetPolicy": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "1"
+ },
+ "output": {
+ "Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"default\",\"Statement\":[{\"Sid\":\"xaccount\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function:1\"}]}",
+ "RevisionId": "4843f2f6-7c59-4fda-b484-afd0bc0e22b8"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the resource-based policy for version 1 of a Lambda function named my-function.",
+ "id": "to-retrieve-a-lambda-function-policy-1481649319053",
+ "title": "To retrieve a Lambda function policy"
+ }
+ ],
+ "GetProvisionedConcurrencyConfig": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "BLUE"
+ },
+ "output": {
+ "AllocatedProvisionedConcurrentExecutions": 100,
+ "AvailableProvisionedConcurrentExecutions": 100,
+ "LastModified": "2019-12-31T20:28:49+0000",
+ "RequestedProvisionedConcurrentExecutions": 100,
+ "Status": "READY"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns details for the provisioned concurrency configuration for the BLUE alias of the specified function.",
+ "id": "to-get-a-provisioned-concurrency-configuration-1586490192690",
+ "title": "To get a provisioned concurrency configuration"
+ },
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "BLUE"
+ },
+ "output": {
+ "AllocatedProvisionedConcurrentExecutions": 100,
+ "AvailableProvisionedConcurrentExecutions": 100,
+ "LastModified": "2019-12-31T20:28:49+0000",
+ "RequestedProvisionedConcurrentExecutions": 100,
+ "Status": "READY"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example displays details for the provisioned concurrency configuration for the BLUE alias of the specified function.",
+ "id": "to-view-a-provisioned-concurrency-configuration-1586490192690",
+ "title": "To view a provisioned concurrency configuration"
+ }
+ ],
+ "Invoke": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Payload": "{}",
+ "Qualifier": "1"
+ },
+ "output": {
+ "Payload": "200 SUCCESS",
+ "StatusCode": 200
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example invokes version 1 of a function named my-function with an empty event payload.",
+ "id": "to-invoke-a-lambda-function-1481659683915",
+ "title": "To invoke a Lambda function"
+ },
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "InvocationType": "Event",
+ "Payload": "{}",
+ "Qualifier": "1"
+ },
+ "output": {
+ "Payload": "",
+ "StatusCode": 202
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example invokes version 1 of a function named my-function asynchronously.",
+ "id": "to-invoke-a-lambda-function-async-1481659683915",
+ "title": "To invoke a Lambda function asynchronously"
+ }
+ ],
+ "InvokeAsync": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "InvokeArgs": "{}"
+ },
+ "output": {
+ "Status": 202
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example invokes a Lambda function asynchronously",
+ "id": "to-invoke-a-lambda-function-asynchronously-1481649694923",
+ "title": "To invoke a Lambda function asynchronously"
+ }
+ ],
+ "ListAliases": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "Aliases": [
+ {
+ "AliasArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function:BETA",
+ "Description": "Production environment BLUE.",
+ "FunctionVersion": "2",
+ "Name": "BLUE",
+ "RevisionId": "a410117f-xmpl-494e-8035-7e204bb7933b",
+ "RoutingConfig": {
+ "AdditionalVersionWeights": {
+ "1": 0.7
+ }
+ }
+ },
+ {
+ "AliasArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function:LIVE",
+ "Description": "Production environment GREEN.",
+ "FunctionVersion": "1",
+ "Name": "GREEN",
+ "RevisionId": "21d40116-xmpl-40ba-9360-3ea284da1bb5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a list of aliases for a function named my-function.",
+ "id": "to-list-a-functions-aliases-1481650199732",
+ "title": "To list a function's aliases"
+ }
+ ],
+ "ListEventSourceMappings": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "EventSourceMappings": [
+ {
+ "BatchSize": 5,
+ "EventSourceArn": "arn:aws:sqs:us-west-2:123456789012:mySQSqueue",
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "LastModified": 1569284520.333,
+ "State": "Enabled",
+ "StateTransitionReason": "USER_INITIATED",
+ "UUID": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a list of the event source mappings for a function named my-function.",
+ "id": "to-list-the-event-source-mappings-for-a-function-1586490285906",
+ "title": "To list the event source mappings for a function"
+ }
+ ],
+ "ListFunctionEventInvokeConfigs": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "FunctionEventInvokeConfigs": [
+ {
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:GREEN",
+ "LastModified": 1577824406.719,
+ "MaximumEventAgeInSeconds": 1800,
+ "MaximumRetryAttempts": 2
+ },
+ {
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:BLUE",
+ "LastModified": 1577824396.653,
+ "MaximumEventAgeInSeconds": 3600,
+ "MaximumRetryAttempts": 0
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a list of asynchronous invocation configurations for a function named my-function.",
+ "id": "to-view-a-list-of-asynchronous-invocation-configurations-1586490355611",
+ "title": "To view a list of asynchronous invocation configurations"
+ }
+ ],
+ "ListFunctions": [
+ {
+ "input": {
+ },
+ "output": {
+ "Functions": [
+ {
+ "CodeSha256": "dBG9m8SGdmlEjw/JYXlhhvCrAv5TxvXsbL/RMr0fT/I=",
+ "CodeSize": 294,
+ "Description": "",
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:helloworld",
+ "FunctionName": "helloworld",
+ "Handler": "helloworld.handler",
+ "LastModified": "2019-09-23T18:32:33.857+0000",
+ "MemorySize": 128,
+ "RevisionId": "1718e831-badf-4253-9518-d0644210af7b",
+ "Role": "arn:aws:iam::123456789012:role/service-role/MyTestFunction-role-zgur6bf4",
+ "Runtime": "nodejs10.x",
+ "Timeout": 3,
+ "TracingConfig": {
+ "Mode": "PassThrough"
+ },
+ "Version": "$LATEST"
+ },
+ {
+ "CodeSha256": "sU0cJ2/hOZevwV/lTxCuQqK3gDZP3i8gUoqUUVRmY6E=",
+ "CodeSize": 266,
+ "Description": "",
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "LastModified": "2019-10-01T16:47:28.490+0000",
+ "MemorySize": 256,
+ "RevisionId": "93017fc9-59cb-41dc-901b-4845ce4bf668",
+ "Role": "arn:aws:iam::123456789012:role/service-role/helloWorldPython-role-uy3l9qyq",
+ "Runtime": "nodejs10.x",
+ "Timeout": 3,
+ "TracingConfig": {
+ "Mode": "PassThrough"
+ },
+ "Version": "$LATEST",
+ "VpcConfig": {
+ "SecurityGroupIds": [
+
+ ],
+ "SubnetIds": [
+
+ ],
+ "VpcId": ""
+ }
+ }
+ ],
+ "NextMarker": ""
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation returns a list of Lambda functions.",
+ "id": "to-get-a-list-of-lambda-functions-1481650507425",
+ "title": "To get a list of Lambda functions"
+ }
+ ],
+ "ListLayerVersions": [
+ {
+ "input": {
+ "LayerName": "blank-java-lib"
+ },
+ "output": {
+ "LayerVersions": [
+ {
+ "CompatibleRuntimes": [
+ "java8"
+ ],
+ "CreatedDate": "2020-03-18T23:38:42.284+0000",
+ "Description": "Dependencies for the blank-java sample app.",
+ "LayerVersionArn": "arn:aws:lambda:us-east-2:123456789012:layer:blank-java-lib:7",
+ "Version": 7
+ },
+ {
+ "CompatibleRuntimes": [
+ "java8"
+ ],
+ "CreatedDate": "2020-03-17T07:24:21.960+0000",
+ "Description": "Dependencies for the blank-java sample app.",
+ "LayerVersionArn": "arn:aws:lambda:us-east-2:123456789012:layer:blank-java-lib:6",
+ "Version": 6
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example displays information about the versions for the layer named blank-java-lib",
+ "id": "to-list-versions-of-a-layer-1586490857297",
+ "title": "To list versions of a layer"
+ }
+ ],
+ "ListLayers": [
+ {
+ "input": {
+ "CompatibleRuntime": "python3.7"
+ },
+ "output": {
+ "Layers": [
+ {
+ "LatestMatchingVersion": {
+ "CompatibleRuntimes": [
+ "python3.6",
+ "python3.7"
+ ],
+ "CreatedDate": "2018-11-15T00:37:46.592+0000",
+ "Description": "My layer",
+ "LayerVersionArn": "arn:aws:lambda:us-east-2:123456789012:layer:my-layer:2",
+ "Version": 2
+ },
+ "LayerArn": "arn:aws:lambda:us-east-2:123456789012:layer:my-layer",
+ "LayerName": "my-layer"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns information about layers that are compatible with the Python 3.7 runtime.",
+ "id": "to-list-the-layers-that-are-compatible-with-your-functions-runtime-1586490857297",
+ "title": "To list the layers that are compatible with your function's runtime"
+ }
+ ],
+ "ListProvisionedConcurrencyConfigs": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "ProvisionedConcurrencyConfigs": [
+ {
+ "AllocatedProvisionedConcurrentExecutions": 100,
+ "AvailableProvisionedConcurrentExecutions": 100,
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:GREEN",
+ "LastModified": "2019-12-31T20:29:00+0000",
+ "RequestedProvisionedConcurrentExecutions": 100,
+ "Status": "READY"
+ },
+ {
+ "AllocatedProvisionedConcurrentExecutions": 100,
+ "AvailableProvisionedConcurrentExecutions": 100,
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:BLUE",
+ "LastModified": "2019-12-31T20:28:49+0000",
+ "RequestedProvisionedConcurrentExecutions": 100,
+ "Status": "READY"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a list of provisioned concurrency configurations for a function named my-function.",
+ "id": "to-get-a-list-of-provisioned-concurrency-configurations-1586491032592",
+ "title": "To get a list of provisioned concurrency configurations"
+ }
+ ],
+ "ListTags": [
+ {
+ "input": {
+ "Resource": "arn:aws:lambda:us-west-2:123456789012:function:my-function"
+ },
+ "output": {
+ "Tags": {
+ "Category": "Web Tools",
+ "Department": "Sales"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example displays the tags attached to the my-function Lambda function.",
+ "id": "to-retrieve-the-list-of-tags-for-a-lambda-function-1586491111498",
+ "title": "To retrieve the list of tags for a Lambda function"
+ }
+ ],
+ "ListVersionsByFunction": [
+ {
+ "input": {
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "Versions": [
+ {
+ "CodeSha256": "YFgDgEKG3ugvF1+pX64gV6tu9qNuIYNUdgJm8nCxsm4=",
+ "CodeSize": 5797206,
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "LastModified": "2020-04-10T19:06:32.563+0000",
+ "MemorySize": 256,
+ "RevisionId": "850ca006-2d98-4ff4-86db-8766e9d32fe9",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "Timeout": 15,
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "Version": "$LATEST"
+ },
+ {
+ "CodeSha256": "YFgDgEKG3ugvF1+pX64gV6tu9qNuIYNUdgJm8nCxsm4=",
+ "CodeSize": 5797206,
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "LastModified": "2020-04-10T19:06:32.563+0000",
+ "MemorySize": 256,
+ "RevisionId": "b75dcd81-xmpl-48a8-a75a-93ba8b5b9727",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "Timeout": 5,
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "Version": "1"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a list of versions of a function named my-function",
+ "id": "to-list-versions-1481650603750",
+ "title": "To list versions of a function"
+ }
+ ],
+ "PublishLayerVersion": [
+ {
+ "input": {
+ "CompatibleRuntimes": [
+ "python3.6",
+ "python3.7"
+ ],
+ "Content": {
+ "S3Bucket": "lambda-layers-us-west-2-123456789012",
+ "S3Key": "layer.zip"
+ },
+ "Description": "My Python layer",
+ "LayerName": "my-layer",
+ "LicenseInfo": "MIT"
+ },
+ "output": {
+ "CompatibleRuntimes": [
+ "python3.6",
+ "python3.7"
+ ],
+ "Content": {
+ "CodeSha256": "tv9jJO+rPbXUUXuRKi7CwHzKtLDkDRJLB3cC3Z/ouXo=",
+ "CodeSize": 169,
+ "Location": "https://awslambda-us-west-2-layers.s3.us-west-2.amazonaws.com/snapshots/123456789012/my-layer-4aaa2fbb-ff77-4b0a-ad92-5b78a716a96a?versionId=27iWyA73cCAYqyH..."
+ },
+ "CreatedDate": "2018-11-14T23:03:52.894+0000",
+ "Description": "My Python layer",
+ "LayerArn": "arn:aws:lambda:us-west-2:123456789012:layer:my-layer",
+ "LayerVersionArn": "arn:aws:lambda:us-west-2:123456789012:layer:my-layer:1",
+ "LicenseInfo": "MIT",
+ "Version": 1
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a new Python library layer version. The command retrieves the layer content a file named layer.zip in the specified S3 bucket.",
+ "id": "to-create-a-lambda-layer-version-1586491213595",
+ "title": "To create a Lambda layer version"
+ }
+ ],
+ "PublishVersion": [
+ {
+ "input": {
+ "CodeSha256": "",
+ "Description": "",
+ "FunctionName": "myFunction"
+ },
+ "output": {
+ "CodeSha256": "YFgDgEKG3ugvF1+pX64gV6tu9qNuIYNUdgJm8nCxsm4=",
+ "CodeSize": 5797206,
+ "Description": "Process image objects from Amazon S3.",
+ "Environment": {
+ "Variables": {
+ "BUCKET": "my-bucket-1xpuxmplzrlbh",
+ "PREFIX": "inbound"
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "KMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966",
+ "LastModified": "2020-04-10T19:06:32.563+0000",
+ "LastUpdateStatus": "Successful",
+ "MemorySize": 256,
+ "RevisionId": "b75dcd81-xmpl-48a8-a75a-93ba8b5b9727",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "State": "Active",
+ "Timeout": 5,
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "Version": "1"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation publishes a version of a Lambda function",
+ "id": "to-publish-a-version-of-a-lambda-function-1481650704986",
+ "title": "To publish a version of a Lambda function"
+ }
+ ],
+ "PutFunctionConcurrency": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "ReservedConcurrentExecutions": 100
+ },
+ "output": {
+ "ReservedConcurrentExecutions": 100
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example configures 100 reserved concurrent executions for the my-function function.",
+ "id": "to-configure-a-reserved-concurrency-limit-for-a-function-1586491405956",
+ "title": "To configure a reserved concurrency limit for a function"
+ }
+ ],
+ "PutFunctionEventInvokeConfig": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "MaximumEventAgeInSeconds": 3600,
+ "MaximumRetryAttempts": 0
+ },
+ "output": {
+ "DestinationConfig": {
+ "OnFailure": {
+ },
+ "OnSuccess": {
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:$LATEST",
+ "LastModified": "2016-11-21T19:49:20.006+0000",
+ "MaximumEventAgeInSeconds": 3600,
+ "MaximumRetryAttempts": 0
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets a maximum event age of one hour and disables retries for the specified function.",
+ "id": "to-configure-error-handling-for-asynchronous-invocation-1586491524021",
+ "title": "To configure error handling for asynchronous invocation"
+ }
+ ],
+ "PutProvisionedConcurrencyConfig": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "ProvisionedConcurrentExecutions": 100,
+ "Qualifier": "BLUE"
+ },
+ "output": {
+ "AllocatedProvisionedConcurrentExecutions": 0,
+ "LastModified": "2019-11-21T19:32:12+0000",
+ "RequestedProvisionedConcurrentExecutions": 100,
+ "Status": "IN_PROGRESS"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example allocates 100 provisioned concurrency for the BLUE alias of the specified function.",
+ "id": "to-allocate-provisioned-concurrency-1586491651377",
+ "title": "To allocate provisioned concurrency"
+ }
+ ],
+ "RemoveLayerVersionPermission": [
+ {
+ "input": {
+ "LayerName": "my-layer",
+ "StatementId": "xaccount",
+ "VersionNumber": 1
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes permission for an account to configure a layer version.",
+ "id": "to-delete-layer-version-permissions-1586491829416",
+ "title": "To delete layer-version permissions"
+ }
+ ],
+ "RemovePermission": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "Qualifier": "PROD",
+ "StatementId": "xaccount"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example removes a permissions statement named xaccount from the PROD alias of a function named my-function.",
+ "id": "to-remove-a-lambda-functions-permissions-1481661337021",
+ "title": "To remove a Lambda function's permissions"
+ }
+ ],
+ "TagResource": [
+ {
+ "input": {
+ "Resource": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "Tags": {
+ "DEPARTMENT": "Department A"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds a tag with the key name DEPARTMENT and a value of 'Department A' to the specified Lambda function.",
+ "id": "to-add-tags-to-an-existing-lambda-function-1586491890446",
+ "title": "To add tags to an existing Lambda function"
+ }
+ ],
+ "UntagResource": [
+ {
+ "input": {
+ "Resource": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
+ "TagKeys": [
+ "DEPARTMENT"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example removes the tag with the key name DEPARTMENT tag from the my-function Lambda function.",
+ "id": "to-remove-tags-from-an-existing-lambda-function-1586491956425",
+ "title": "To remove tags from an existing Lambda function"
+ }
+ ],
+ "UpdateAlias": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "FunctionVersion": "2",
+ "Name": "BLUE",
+ "RoutingConfig": {
+ "AdditionalVersionWeights": {
+ "1": 0.7
+ }
+ }
+ },
+ "output": {
+ "AliasArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function:BLUE",
+ "Description": "Production environment BLUE.",
+ "FunctionVersion": "2",
+ "Name": "BLUE",
+ "RevisionId": "594f41fb-xmpl-4c20-95c7-6ca5f2a92c93",
+ "RoutingConfig": {
+ "AdditionalVersionWeights": {
+ "1": 0.7
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example updates the alias named BLUE to send 30% of traffic to version 2 and 70% to version 1.",
+ "id": "to-update-a-function-alias-1481650817950",
+ "title": "To update a function alias"
+ }
+ ],
+ "UpdateEventSourceMapping": [
+ {
+ "input": {
+ "BatchSize": 123,
+ "Enabled": true,
+ "FunctionName": "myFunction",
+ "UUID": "1234xCy789012"
+ },
+ "output": {
+ "BatchSize": 123,
+ "EventSourceArn": "arn:aws:s3:::examplebucket/*",
+ "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:myFunction",
+ "LastModified": "2016-11-21T19:49:20.006+0000",
+ "LastProcessingResult": "",
+ "State": "",
+ "StateTransitionReason": "",
+ "UUID": "1234xCy789012"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation updates a Lambda function event source mapping",
+ "id": "to-update-a-lambda-function-event-source-mapping-1481650907413",
+ "title": "To update a Lambda function event source mapping"
+ }
+ ],
+ "UpdateFunctionCode": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "S3Bucket": "my-bucket-1xpuxmplzrlbh",
+ "S3Key": "function.zip"
+ },
+ "output": {
+ "CodeSha256": "PFn4S+er27qk+UuZSTKEQfNKG/XNn7QJs90mJgq6oH8=",
+ "CodeSize": 308,
+ "Description": "",
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "LastModified": "2019-08-14T22:26:11.234+0000",
+ "MemorySize": 128,
+ "RevisionId": "873282ed-xmpl-4dc8-a069-d0c647e470c6",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "Timeout": 3,
+ "TracingConfig": {
+ "Mode": "PassThrough"
+ },
+ "Version": "$LATEST"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example replaces the code of the unpublished ($LATEST) version of a function named my-function with the contents of the specified zip file in Amazon S3.",
+ "id": "to-update-a-lambda-functions-code-1481650992672",
+ "title": "To update a Lambda function's code"
+ }
+ ],
+ "UpdateFunctionConfiguration": [
+ {
+ "input": {
+ "FunctionName": "my-function",
+ "MemorySize": 256
+ },
+ "output": {
+ "CodeSha256": "PFn4S+er27qk+UuZSTKEQfNKG/XNn7QJs90mJgq6oH8=",
+ "CodeSize": 308,
+ "Description": "",
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
+ "FunctionName": "my-function",
+ "Handler": "index.handler",
+ "LastModified": "2019-08-14T22:26:11.234+0000",
+ "MemorySize": 256,
+ "RevisionId": "873282ed-xmpl-4dc8-a069-d0c647e470c6",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Runtime": "nodejs12.x",
+ "Timeout": 3,
+ "TracingConfig": {
+ "Mode": "PassThrough"
+ },
+ "Version": "$LATEST"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example modifies the memory size to be 256 MB for the unpublished ($LATEST) version of a function named my-function.",
+ "id": "to-update-a-lambda-functions-configuration-1481651096447",
+ "title": "To update a Lambda function's configuration"
+ }
+ ],
+ "UpdateFunctionEventInvokeConfig": [
+ {
+ "input": {
+ "DestinationConfig": {
+ "OnFailure": {
+ "Destination": "arn:aws:sqs:us-east-2:123456789012:destination"
+ }
+ },
+ "FunctionName": "my-function"
+ },
+ "output": {
+ "DestinationConfig": {
+ "OnFailure": {
+ "Destination": "arn:aws:sqs:us-east-2:123456789012:destination"
+ },
+ "OnSuccess": {
+ }
+ },
+ "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:$LATEST",
+ "LastModified": 1573687896.493,
+ "MaximumEventAgeInSeconds": 3600,
+ "MaximumRetryAttempts": 0
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds an on-failure destination to the existing asynchronous invocation configuration for a function named my-function.",
+ "id": "to-update-an-asynchronous-invocation-configuration-1586492061186",
+ "title": "To update an asynchronous invocation configuration"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/paginators-1.json
new file mode 100644
index 0000000000..7ae81bfda7
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/paginators-1.json
@@ -0,0 +1,70 @@
+{
+ "pagination": {
+ "ListEventSourceMappings": {
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "limit_key": "MaxItems",
+ "result_key": "EventSourceMappings"
+ },
+ "ListFunctions": {
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "limit_key": "MaxItems",
+ "result_key": "Functions"
+ },
+ "ListAliases": {
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "limit_key": "MaxItems",
+ "result_key": "Aliases"
+ },
+ "ListLayerVersions": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "LayerVersions"
+ },
+ "ListLayers": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "Layers"
+ },
+ "ListVersionsByFunction": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "Versions"
+ },
+ "ListFunctionEventInvokeConfigs": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "FunctionEventInvokeConfigs"
+ },
+ "ListProvisionedConcurrencyConfigs": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "ProvisionedConcurrencyConfigs"
+ },
+ "ListCodeSigningConfigs": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "CodeSigningConfigs"
+ },
+ "ListFunctionsByCodeSigningConfig": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "FunctionArns"
+ },
+ "ListFunctionUrlConfigs": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextMarker",
+ "result_key": "FunctionUrlConfigs"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/service-2.json.gz
new file mode 100644
index 0000000000..612f57bf7a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/waiters-2.json
new file mode 100644
index 0000000000..86e24b0cb9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lambda/2015-03-31/waiters-2.json
@@ -0,0 +1,152 @@
+{
+ "version": 2,
+ "waiters": {
+ "FunctionExists": {
+ "delay": 1,
+ "operation": "GetFunction",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "status",
+ "expected": 200
+ },
+ {
+ "state": "retry",
+ "matcher": "error",
+ "expected": "ResourceNotFoundException"
+ }
+ ]
+ },
+ "FunctionActive": {
+ "delay": 5,
+ "maxAttempts": 60,
+ "operation": "GetFunctionConfiguration",
+ "description": "Waits for the function's State to be Active. This waiter uses GetFunctionConfiguration API. This should be used after new function creation.",
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "Active"
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "Failed"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "Pending"
+ }
+ ]
+ },
+ "FunctionUpdated": {
+ "delay": 5,
+ "maxAttempts": 60,
+ "operation": "GetFunctionConfiguration",
+ "description": "Waits for the function's LastUpdateStatus to be Successful. This waiter uses GetFunctionConfiguration API. This should be used after function updates.",
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "LastUpdateStatus",
+ "expected": "Successful"
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "LastUpdateStatus",
+ "expected": "Failed"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "LastUpdateStatus",
+ "expected": "InProgress"
+ }
+ ]
+ },
+ "FunctionActiveV2": {
+ "delay": 1,
+ "maxAttempts": 300,
+ "operation": "GetFunction",
+ "description": "Waits for the function's State to be Active. This waiter uses GetFunction API. This should be used after new function creation.",
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "Configuration.State",
+ "expected": "Active"
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "Configuration.State",
+ "expected": "Failed"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Configuration.State",
+ "expected": "Pending"
+ }
+ ]
+ },
+ "FunctionUpdatedV2": {
+ "delay": 1,
+ "maxAttempts": 300,
+ "operation": "GetFunction",
+ "description": "Waits for the function's LastUpdateStatus to be Successful. This waiter uses GetFunction API. This should be used after function updates.",
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "Configuration.LastUpdateStatus",
+ "expected": "Successful"
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "Configuration.LastUpdateStatus",
+ "expected": "Failed"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Configuration.LastUpdateStatus",
+ "expected": "InProgress"
+ }
+ ]
+ },
+ "PublishedVersionActive": {
+ "delay": 5,
+ "maxAttempts": 312,
+ "operation": "GetFunctionConfiguration",
+ "description": "Waits for the published version's State to be Active. This waiter uses GetFunctionConfiguration API. This should be used after new version is published.",
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "Active"
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "Failed"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "Pending"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..023a6a08e0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..7f6109538b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListDeploymentEvents": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "deploymentEvents"
+ },
+ "ListDeployments": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "deployments"
+ },
+ "ListWorkloadDeploymentPatterns": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "workloadDeploymentPatterns"
+ },
+ "ListWorkloads": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "workloads"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..1b1b6f1dbd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/launch-wizard/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..7c3438c8e1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/examples-1.json
new file mode 100644
index 0000000000..0982d973b5
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/examples-1.json
@@ -0,0 +1,758 @@
+{
+ "version": "1.0",
+ "examples": {
+ "GetBot": [
+ {
+ "input": {
+ "name": "DocOrderPizza",
+ "versionOrAlias": "$LATEST"
+ },
+ "output": {
+ "version": "$LATEST",
+ "name": "DocOrderPizzaBot",
+ "abortStatement": {
+ "messages": [
+ {
+ "content": "I don't understand. Can you try again?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I'm sorry, I don't understand.",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "checksum": "20172ee3-fa06-49b2-bbc5-667c090303e9",
+ "childDirected": true,
+ "clarificationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "I'm sorry, I didn't hear that. Can you repeate what you just said?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Can you say that again?",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "createdDate": 1494360160.133,
+ "description": "Orders a pizza from a local pizzeria.",
+ "idleSessionTTLInSeconds": 300,
+ "intents": [
+ {
+ "intentName": "DocOrderPizza",
+ "intentVersion": "$LATEST"
+ }
+ ],
+ "lastUpdatedDate": 1494360160.133,
+ "locale": "en-US",
+ "status": "NOT_BUILT"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to get configuration information for a bot.",
+ "id": "to-get-information-about-a-bot-1494431724188",
+ "title": "To get information about a bot"
+ }
+ ],
+ "GetBots": [
+ {
+ "input": {
+ "maxResults": 5,
+ "nextToken": ""
+ },
+ "output": {
+ "bots": [
+ {
+ "version": "$LATEST",
+ "name": "DocOrderPizzaBot",
+ "createdDate": 1494360160.133,
+ "description": "Orders a pizza from a local pizzeria.",
+ "lastUpdatedDate": 1494360160.133,
+ "status": "NOT_BUILT"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to get a list of all of the bots in your account.",
+ "id": "to-get-a-list-of-bots-1494432220036",
+ "title": "To get a list of bots"
+ }
+ ],
+ "GetIntent": [
+ {
+ "input": {
+ "version": "$LATEST",
+ "name": "DocOrderPizza"
+ },
+ "output": {
+ "version": "$LATEST",
+ "name": "DocOrderPizza",
+ "checksum": "ca9bc13d-afc8-4706-bbaf-091f7a5935d6",
+ "conclusionStatement": {
+ "messages": [
+ {
+ "content": "All right, I ordered you a {Crust} crust {Type} pizza with {Sauce} sauce.",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "OK, your {Crust} crust {Type} pizza with {Sauce} sauce is on the way.",
+ "contentType": "PlainText"
+ }
+ ],
+ "responseCard": "foo"
+ },
+ "confirmationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "Should I order your {Crust} crust {Type} pizza with {Sauce} sauce?",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "createdDate": 1494359783.453,
+ "description": "Order a pizza from a local pizzeria.",
+ "fulfillmentActivity": {
+ "type": "ReturnIntent"
+ },
+ "lastUpdatedDate": 1494359783.453,
+ "rejectionStatement": {
+ "messages": [
+ {
+ "content": "Ok, I'll cancel your order.",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I cancelled your order.",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "sampleUtterances": [
+ "Order me a pizza.",
+ "Order me a {Type} pizza.",
+ "I want a {Crust} crust {Type} pizza",
+ "I want a {Crust} crust {Type} pizza with {Sauce} sauce."
+ ],
+ "slots": [
+ {
+ "name": "Type",
+ "description": "The type of pizza to order.",
+ "priority": 1,
+ "sampleUtterances": [
+ "Get me a {Type} pizza.",
+ "A {Type} pizza please.",
+ "I'd like a {Type} pizza."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "What type of pizza would you like?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Vegie or cheese pizza?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I can get you a vegie or a cheese pizza.",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Crust",
+ "description": "The type of pizza crust to order.",
+ "priority": 2,
+ "sampleUtterances": [
+ "Make it a {Crust} crust.",
+ "I'd like a {Crust} crust."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaCrustType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "What type of crust would you like?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Thick or thin crust?",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Sauce",
+ "description": "The type of sauce to use on the pizza.",
+ "priority": 3,
+ "sampleUtterances": [
+ "Make it {Sauce} sauce.",
+ "I'd like {Sauce} sauce."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaSauceType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "White or red sauce?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Garlic or tomato sauce?",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to get information about an intent.",
+ "id": "to-get-a-information-about-an-intent-1494432574147",
+ "title": "To get a information about an intent"
+ }
+ ],
+ "GetIntents": [
+ {
+ "input": {
+ "maxResults": 10,
+ "nextToken": ""
+ },
+ "output": {
+ "intents": [
+ {
+ "version": "$LATEST",
+ "name": "DocOrderPizza",
+ "createdDate": 1494359783.453,
+ "description": "Order a pizza from a local pizzeria.",
+ "lastUpdatedDate": 1494359783.453
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to get a list of all of the intents in your account.",
+ "id": "to-get-a-list-of-intents-1494432416363",
+ "title": "To get a list of intents"
+ }
+ ],
+ "GetSlotType": [
+ {
+ "input": {
+ "version": "$LATEST",
+ "name": "DocPizzaCrustType"
+ },
+ "output": {
+ "version": "$LATEST",
+ "name": "DocPizzaCrustType",
+ "checksum": "210b3d5a-90a3-4b22-ac7e-f50c2c71095f",
+ "createdDate": 1494359274.403,
+ "description": "Available crust types",
+ "enumerationValues": [
+ {
+ "value": "thick"
+ },
+ {
+ "value": "thin"
+ }
+ ],
+ "lastUpdatedDate": 1494359274.403
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to get information about a slot type.",
+ "id": "to-get-information-about-a-slot-type-1494432961004",
+ "title": "To get information about a slot type"
+ }
+ ],
+ "GetSlotTypes": [
+ {
+ "input": {
+ "maxResults": 10,
+ "nextToken": ""
+ },
+ "output": {
+ "slotTypes": [
+ {
+ "version": "$LATEST",
+ "name": "DocPizzaCrustType",
+ "createdDate": 1494359274.403,
+ "description": "Available crust types",
+ "lastUpdatedDate": 1494359274.403
+ },
+ {
+ "version": "$LATEST",
+ "name": "DocPizzaSauceType",
+ "createdDate": 1494356442.23,
+ "description": "Available pizza sauces",
+ "lastUpdatedDate": 1494356442.23
+ },
+ {
+ "version": "$LATEST",
+ "name": "DocPizzaType",
+ "createdDate": 1494359198.656,
+ "description": "Available pizzas",
+ "lastUpdatedDate": 1494359198.656
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to get a list of all of the slot types in your account.",
+ "id": "to-get-a-list-of-slot-types-1494432757458",
+ "title": "To get a list of slot types"
+ }
+ ],
+ "PutBot": [
+ {
+ "input": {
+ "name": "DocOrderPizzaBot",
+ "abortStatement": {
+ "messages": [
+ {
+ "content": "I don't understand. Can you try again?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I'm sorry, I don't understand.",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "childDirected": true,
+ "clarificationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "I'm sorry, I didn't hear that. Can you repeat what you just said?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Can you say that again?",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "description": "Orders a pizza from a local pizzeria.",
+ "idleSessionTTLInSeconds": 300,
+ "intents": [
+ {
+ "intentName": "DocOrderPizza",
+ "intentVersion": "$LATEST"
+ }
+ ],
+ "locale": "en-US",
+ "processBehavior": "SAVE"
+ },
+ "output": {
+ "version": "$LATEST",
+ "name": "DocOrderPizzaBot",
+ "abortStatement": {
+ "messages": [
+ {
+ "content": "I don't understand. Can you try again?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I'm sorry, I don't understand.",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "checksum": "20172ee3-fa06-49b2-bbc5-667c090303e9",
+ "childDirected": true,
+ "clarificationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "I'm sorry, I didn't hear that. Can you repeate what you just said?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Can you say that again?",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "createdDate": 1494360160.133,
+ "description": "Orders a pizza from a local pizzeria.",
+ "idleSessionTTLInSeconds": 300,
+ "intents": [
+ {
+ "intentName": "DocOrderPizza",
+ "intentVersion": "$LATEST"
+ }
+ ],
+ "lastUpdatedDate": 1494360160.133,
+ "locale": "en-US",
+ "status": "NOT_BUILT"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to create a bot for ordering pizzas.",
+ "id": "to-create-a-bot-1494360003886",
+ "title": "To create a bot"
+ }
+ ],
+ "PutIntent": [
+ {
+ "input": {
+ "name": "DocOrderPizza",
+ "conclusionStatement": {
+ "messages": [
+ {
+ "content": "All right, I ordered you a {Crust} crust {Type} pizza with {Sauce} sauce.",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "OK, your {Crust} crust {Type} pizza with {Sauce} sauce is on the way.",
+ "contentType": "PlainText"
+ }
+ ],
+ "responseCard": "foo"
+ },
+ "confirmationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "Should I order your {Crust} crust {Type} pizza with {Sauce} sauce?",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "description": "Order a pizza from a local pizzeria.",
+ "fulfillmentActivity": {
+ "type": "ReturnIntent"
+ },
+ "rejectionStatement": {
+ "messages": [
+ {
+ "content": "Ok, I'll cancel your order.",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I cancelled your order.",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "sampleUtterances": [
+ "Order me a pizza.",
+ "Order me a {Type} pizza.",
+ "I want a {Crust} crust {Type} pizza",
+ "I want a {Crust} crust {Type} pizza with {Sauce} sauce."
+ ],
+ "slots": [
+ {
+ "name": "Type",
+ "description": "The type of pizza to order.",
+ "priority": 1,
+ "sampleUtterances": [
+ "Get me a {Type} pizza.",
+ "A {Type} pizza please.",
+ "I'd like a {Type} pizza."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "What type of pizza would you like?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Vegie or cheese pizza?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I can get you a vegie or a cheese pizza.",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Crust",
+ "description": "The type of pizza crust to order.",
+ "priority": 2,
+ "sampleUtterances": [
+ "Make it a {Crust} crust.",
+ "I'd like a {Crust} crust."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaCrustType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "What type of crust would you like?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Thick or thin crust?",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Sauce",
+ "description": "The type of sauce to use on the pizza.",
+ "priority": 3,
+ "sampleUtterances": [
+ "Make it {Sauce} sauce.",
+ "I'd like {Sauce} sauce."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaSauceType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "White or red sauce?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Garlic or tomato sauce?",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "output": {
+ "version": "$LATEST",
+ "name": "DocOrderPizza",
+ "checksum": "ca9bc13d-afc8-4706-bbaf-091f7a5935d6",
+ "conclusionStatement": {
+ "messages": [
+ {
+ "content": "All right, I ordered you a {Crust} crust {Type} pizza with {Sauce} sauce.",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "OK, your {Crust} crust {Type} pizza with {Sauce} sauce is on the way.",
+ "contentType": "PlainText"
+ }
+ ],
+ "responseCard": "foo"
+ },
+ "confirmationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "Should I order your {Crust} crust {Type} pizza with {Sauce} sauce?",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "createdDate": 1494359783.453,
+ "description": "Order a pizza from a local pizzeria.",
+ "fulfillmentActivity": {
+ "type": "ReturnIntent"
+ },
+ "lastUpdatedDate": 1494359783.453,
+ "rejectionStatement": {
+ "messages": [
+ {
+ "content": "Ok, I'll cancel your order.",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I cancelled your order.",
+ "contentType": "PlainText"
+ }
+ ]
+ },
+ "sampleUtterances": [
+ "Order me a pizza.",
+ "Order me a {Type} pizza.",
+ "I want a {Crust} crust {Type} pizza",
+ "I want a {Crust} crust {Type} pizza with {Sauce} sauce."
+ ],
+ "slots": [
+ {
+ "name": "Sauce",
+ "description": "The type of sauce to use on the pizza.",
+ "priority": 3,
+ "sampleUtterances": [
+ "Make it {Sauce} sauce.",
+ "I'd like {Sauce} sauce."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaSauceType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "White or red sauce?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Garlic or tomato sauce?",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Type",
+ "description": "The type of pizza to order.",
+ "priority": 1,
+ "sampleUtterances": [
+ "Get me a {Type} pizza.",
+ "A {Type} pizza please.",
+ "I'd like a {Type} pizza."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "What type of pizza would you like?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Vegie or cheese pizza?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "I can get you a vegie or a cheese pizza.",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Crust",
+ "description": "The type of pizza crust to order.",
+ "priority": 2,
+ "sampleUtterances": [
+ "Make it a {Crust} crust.",
+ "I'd like a {Crust} crust."
+ ],
+ "slotConstraint": "Required",
+ "slotType": "DocPizzaCrustType",
+ "slotTypeVersion": "$LATEST",
+ "valueElicitationPrompt": {
+ "maxAttempts": 1,
+ "messages": [
+ {
+ "content": "What type of crust would you like?",
+ "contentType": "PlainText"
+ },
+ {
+ "content": "Thick or thin crust?",
+ "contentType": "PlainText"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to create an intent for ordering pizzas.",
+ "id": "to-create-an-intent-1494358144659",
+ "title": "To create an intent"
+ }
+ ],
+ "PutSlotType": [
+ {
+ "input": {
+ "name": "PizzaSauceType",
+ "description": "Available pizza sauces",
+ "enumerationValues": [
+ {
+ "value": "red"
+ },
+ {
+ "value": "white"
+ }
+ ]
+ },
+ "output": {
+ "version": "$LATEST",
+ "name": "DocPizzaSauceType",
+ "checksum": "cfd00ed1-775d-4357-947c-aca7e73b44ba",
+ "createdDate": 1494356442.23,
+ "description": "Available pizza sauces",
+ "enumerationValues": [
+ {
+ "value": "red"
+ },
+ {
+ "value": "white"
+ }
+ ],
+ "lastUpdatedDate": 1494356442.23
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to create a slot type that describes pizza sauces.",
+ "id": "to-create-a-slot-type-1494357262258",
+ "title": "To Create a Slot Type"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/paginators-1.json
new file mode 100644
index 0000000000..02d2308283
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/paginators-1.json
@@ -0,0 +1,64 @@
+{
+ "pagination": {
+ "GetSlotTypeVersions": {
+ "result_key": "slotTypes",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetSlotTypes": {
+ "result_key": "slotTypes",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetIntents": {
+ "result_key": "intents",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetBotChannelAssociations": {
+ "result_key": "botChannelAssociations",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetBots": {
+ "result_key": "bots",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetBuiltinSlotTypes": {
+ "result_key": "slotTypes",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetIntentVersions": {
+ "result_key": "intents",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetBotAliases": {
+ "result_key": "BotAliases",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetBuiltinIntents": {
+ "result_key": "intents",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "GetBotVersions": {
+ "result_key": "bots",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/service-2.json.gz
new file mode 100644
index 0000000000..60157cde2c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-models/2017-04-19/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..ce4406c278
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/service-2.json.gz
new file mode 100644
index 0000000000..8ae7bf4265
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lex-runtime/2016-11-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..14ea4d37eb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/service-2.json.gz
new file mode 100644
index 0000000000..ef1b670fe5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/waiters-2.json
new file mode 100644
index 0000000000..1ec96048ec
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-models/2020-08-07/waiters-2.json
@@ -0,0 +1,255 @@
+{
+ "version":2,
+ "waiters":{
+ "BotAvailable":{
+ "delay":10,
+ "operation":"DescribeBot",
+ "maxAttempts":35,
+ "description":"Wait until a bot is available",
+ "acceptors":[
+ {
+ "expected":"Available",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botStatus"
+ },
+ {
+ "expected":"Inactive",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botStatus"
+ }
+ ]
+ },
+ "BotAliasAvailable":{
+ "delay":10,
+ "operation":"DescribeBotAlias",
+ "maxAttempts":35,
+ "description":"Wait until a bot alias is available",
+ "acceptors":[
+ {
+ "expected":"Available",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botAliasStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botAliasStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botAliasStatus"
+ }
+ ]
+ },
+ "BotExportCompleted":{
+ "delay":10,
+ "operation":"DescribeExport",
+ "maxAttempts":35,
+ "description":"Wait until a bot has been exported",
+ "acceptors":[
+ {
+ "expected":"Completed",
+ "matcher":"path",
+ "state":"success",
+ "argument":"exportStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"exportStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"exportStatus"
+ }
+ ]
+ },
+ "BotImportCompleted":{
+ "delay":10,
+ "operation":"DescribeImport",
+ "maxAttempts":35,
+ "description":"Wait until a bot has been imported",
+ "acceptors":[
+ {
+ "expected":"Completed",
+ "matcher":"path",
+ "state":"success",
+ "argument":"importStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"importStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"importStatus"
+ }
+ ]
+ },
+ "BotLocaleBuilt":{
+ "delay":10,
+ "operation":"DescribeBotLocale",
+ "maxAttempts":35,
+ "description":"Wait until a bot locale is built",
+ "acceptors":[
+ {
+ "expected":"Built",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"NotBuilt",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ }
+ ]
+ },
+ "BotLocaleExpressTestingAvailable":{
+ "delay":10,
+ "operation":"DescribeBotLocale",
+ "maxAttempts":35,
+ "description":"Wait until a bot locale build is ready for express testing",
+ "acceptors":[
+ {
+ "expected":"Built",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"ReadyExpressTesting",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"NotBuilt",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ }
+ ]
+ },
+ "BotVersionAvailable":{
+ "delay":10,
+ "operation":"DescribeBotVersion",
+ "maxAttempts":35,
+ "description":"Wait until a bot version is available",
+ "acceptors":[
+ {
+ "expected":"Available",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botStatus"
+ },
+ {
+ "state":"retry",
+ "matcher":"status",
+ "expected":404
+ }
+ ]
+ },
+ "BotLocaleCreated":{
+ "delay":10,
+ "operation":"DescribeBotLocale",
+ "maxAttempts":35,
+ "description":"Wait unit a bot locale is created",
+ "acceptors":[
+ {
+ "expected":"Built",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"ReadyExpressTesting",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"NotBuilt",
+ "matcher":"path",
+ "state":"success",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"Deleting",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ },
+ {
+ "expected":"Failed",
+ "matcher":"path",
+ "state":"failure",
+ "argument":"botLocaleStatus"
+ }
+ ]
+ }
+ }
+}
+
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a6d519305f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/service-2.json.gz
new file mode 100644
index 0000000000..e959949483
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lexv2-runtime/2020-08-07/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..f50bb17ec9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..1dc8f4d827
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListLinuxSubscriptionInstances": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Instances"
+ },
+ "ListLinuxSubscriptions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Subscriptions"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..7466066214
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-linux-subscriptions/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e3b109ae04
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..a212681a98
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListIdentityProviders": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "IdentityProviderSummaries"
+ },
+ "ListInstances": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InstanceSummaries"
+ },
+ "ListProductSubscriptions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ProductUserSummaries"
+ },
+ "ListUserAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InstanceUserSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..d5363a1948
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager-user-subscriptions/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..bb29555a54
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/paginators-1.json
new file mode 100644
index 0000000000..03a3ca4d58
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListAssociationsForLicenseConfiguration": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LicenseConfigurationAssociations"
+ },
+ "ListLicenseConfigurations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LicenseConfigurations"
+ },
+ "ListLicenseSpecificationsForResource": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LicenseSpecifications"
+ },
+ "ListResourceInventory": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ResourceInventoryList"
+ },
+ "ListUsageForLicenseConfiguration": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LicenseConfigurationUsageList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/service-2.json.gz
new file mode 100644
index 0000000000..19e304df21
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/license-manager/2018-08-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..16886e1f35
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/paginators-1.json
new file mode 100644
index 0000000000..fbea9383a8
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/paginators-1.json
@@ -0,0 +1,104 @@
+{
+ "pagination": {
+ "GetActiveNames": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "activeNames"
+ },
+ "GetBlueprints": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "blueprints"
+ },
+ "GetBundles": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "bundles"
+ },
+ "GetDomains": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "domains"
+ },
+ "GetInstanceSnapshots": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "instanceSnapshots"
+ },
+ "GetInstances": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "instances"
+ },
+ "GetKeyPairs": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "keyPairs"
+ },
+ "GetOperations": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "operations"
+ },
+ "GetStaticIps": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "staticIps"
+ },
+ "GetCloudFormationStackRecords": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "cloudFormationStackRecords"
+ },
+ "GetDiskSnapshots": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "diskSnapshots"
+ },
+ "GetDisks": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "disks"
+ },
+ "GetExportSnapshotRecords": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "exportSnapshotRecords"
+ },
+ "GetLoadBalancers": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "loadBalancers"
+ },
+ "GetRelationalDatabaseBlueprints": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "blueprints"
+ },
+ "GetRelationalDatabaseBundles": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "bundles"
+ },
+ "GetRelationalDatabaseEvents": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "relationalDatabaseEvents"
+ },
+ "GetRelationalDatabaseParameters": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "parameters"
+ },
+ "GetRelationalDatabaseSnapshots": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "relationalDatabaseSnapshots"
+ },
+ "GetRelationalDatabases": {
+ "input_token": "pageToken",
+ "output_token": "nextPageToken",
+ "result_key": "relationalDatabases"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/service-2.json.gz
new file mode 100644
index 0000000000..2ca2e74d37
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lightsail/2016-11-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..d3e4f54956
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/paginators-1.json
new file mode 100644
index 0000000000..eaa2797564
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/paginators-1.json
@@ -0,0 +1,64 @@
+{
+ "pagination": {
+ "GetDevicePositionHistory": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "DevicePositions",
+ "limit_key": "MaxResults"
+ },
+ "ListGeofenceCollections": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ },
+ "ListGeofences": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Entries",
+ "limit_key": "MaxResults"
+ },
+ "ListMaps": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ },
+ "ListPlaceIndexes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ },
+ "ListTrackerConsumers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ConsumerArns"
+ },
+ "ListTrackers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ },
+ "ListDevicePositions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ },
+ "ListRouteCalculators": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ },
+ "ListKeys": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/service-2.json.gz
new file mode 100644
index 0000000000..468de8fbed
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/location/2020-11-19/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..fea08548b0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/service-2.json.gz
new file mode 100644
index 0000000000..73b6ea836a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutequipment/2020-12-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8e8543a061
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/service-2.json.gz
new file mode 100644
index 0000000000..adca468225
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutmetrics/2017-07-25/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..ab76088198
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/paginators-1.json
new file mode 100644
index 0000000000..14c4ce7390
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListDatasetEntries": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DatasetEntries"
+ },
+ "ListModels": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Models"
+ },
+ "ListProjects": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Projects"
+ },
+ "ListModelPackagingJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ModelPackagingJobs"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/service-2.json.gz
new file mode 100644
index 0000000000..1fe48c56d7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/lookoutvision/2020-11-20/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..f5a458e5b9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/paginators-1.json
new file mode 100644
index 0000000000..e7cd269f30
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/paginators-1.json
@@ -0,0 +1,58 @@
+{
+ "pagination": {
+ "ListApplicationVersions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "applicationVersions"
+ },
+ "ListApplications": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "applications"
+ },
+ "ListBatchJobDefinitions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "batchJobDefinitions"
+ },
+ "ListBatchJobExecutions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "batchJobExecutions"
+ },
+ "ListDataSetImportHistory": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "dataSetImportTasks"
+ },
+ "ListDataSets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "dataSets"
+ },
+ "ListDeployments": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "deployments"
+ },
+ "ListEngineVersions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "engineVersions"
+ },
+ "ListEnvironments": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "environments"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/service-2.json.gz
new file mode 100644
index 0000000000..1ffc95dc65
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/m2/2021-04-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2c18f026b7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/paginators-1.json
new file mode 100644
index 0000000000..c13ce65af5
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "DescribeBatchPredictions": {
+ "limit_key": "Limit",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "result_key": "Results"
+ },
+ "DescribeDataSources": {
+ "limit_key": "Limit",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "result_key": "Results"
+ },
+ "DescribeEvaluations": {
+ "limit_key": "Limit",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "result_key": "Results"
+ },
+ "DescribeMLModels": {
+ "limit_key": "Limit",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "result_key": "Results"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/service-2.json.gz
new file mode 100644
index 0000000000..07439249cc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/waiters-2.json
new file mode 100644
index 0000000000..da6b1c951a
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/machinelearning/2014-12-12/waiters-2.json
@@ -0,0 +1,81 @@
+{
+ "version": 2,
+ "waiters": {
+ "DataSourceAvailable": {
+ "delay": 30,
+ "operation": "DescribeDataSources",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "COMPLETED",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Results[].Status"
+ },
+ {
+ "expected": "FAILED",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Results[].Status"
+ }
+ ]
+ },
+ "MLModelAvailable": {
+ "delay": 30,
+ "operation": "DescribeMLModels",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "COMPLETED",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Results[].Status"
+ },
+ {
+ "expected": "FAILED",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Results[].Status"
+ }
+ ]
+ },
+ "EvaluationAvailable": {
+ "delay": 30,
+ "operation": "DescribeEvaluations",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "COMPLETED",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Results[].Status"
+ },
+ {
+ "expected": "FAILED",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Results[].Status"
+ }
+ ]
+ },
+ "BatchPredictionAvailable": {
+ "delay": 30,
+ "operation": "DescribeBatchPredictions",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "COMPLETED",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Results[].Status"
+ },
+ {
+ "expected": "FAILED",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Results[].Status"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..9079ce310a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/paginators-1.json
new file mode 100644
index 0000000000..56d8f702f8
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/paginators-1.json
@@ -0,0 +1,100 @@
+{
+ "pagination": {
+ "DescribeBuckets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "buckets"
+ },
+ "GetUsageStatistics": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "records",
+ "non_aggregate_keys": [
+ "timeRange"
+ ]
+ },
+ "ListClassificationJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListCustomDataIdentifiers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListFindings": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "findingIds"
+ },
+ "ListFindingsFilters": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "findingsFilterListItems"
+ },
+ "ListInvitations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "invitations"
+ },
+ "ListMembers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "members"
+ },
+ "ListOrganizationAdminAccounts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "adminAccounts"
+ },
+ "SearchResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "matchingResources"
+ },
+ "ListClassificationScopes": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "classificationScopes"
+ },
+ "ListAllowLists": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "allowLists"
+ },
+ "ListManagedDataIdentifiers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "items"
+ },
+ "ListResourceProfileDetections": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "detections"
+ },
+ "ListSensitivityInspectionTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "sensitivityInspectionTemplates"
+ },
+ "ListResourceProfileArtifacts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "artifacts"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/service-2.json.gz
new file mode 100644
index 0000000000..474364f832
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/waiters-2.json
new file mode 100644
index 0000000000..12c4a4a83d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/macie2/2020-01-01/waiters-2.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "waiters": {
+ "FindingRevealed": {
+ "description": "Wait until the sensitive data occurrences are ready.",
+ "delay": 2,
+ "maxAttempts": 60,
+ "operation": "GetSensitiveDataOccurrences",
+ "acceptors": [
+ {
+ "matcher": "path",
+ "argument": "status",
+ "state": "success",
+ "expected": "SUCCESS"
+ },
+ {
+ "matcher": "path",
+ "argument": "status",
+ "state": "success",
+ "expected": "ERROR"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..faf7992833
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/paginators-1.json
new file mode 100644
index 0000000000..e1cd5ba8f2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListTokenBalances": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "tokenBalances"
+ },
+ "ListTransactionEvents": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "events"
+ },
+ "ListTransactions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "transactions"
+ },
+ "ListAssetContracts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "contracts"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/service-2.json.gz
new file mode 100644
index 0000000000..f3198c3c97
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain-query/2023-05-04/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..1a8399e916
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/paginators-1.json
new file mode 100644
index 0000000000..8d30a03f85
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListAccessors": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Accessors"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/service-2.json.gz
new file mode 100644
index 0000000000..adeebedb1b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/managedblockchain/2018-09-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..04104977c5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/paginators-1.json
new file mode 100644
index 0000000000..8bbef9687d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListChangeSets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ChangeSetSummaryList"
+ },
+ "ListEntities": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EntitySummaryList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/service-2.json.gz
new file mode 100644
index 0000000000..fc557139ad
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-catalog/2018-09-17/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..d6cb18dab8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/paginators-1.json
new file mode 100644
index 0000000000..8dbf525ed1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "GetEntitlements": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Entitlements"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/service-2.json.gz
new file mode 100644
index 0000000000..73b4fcae7c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplace-entitlement/2017-01-11/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..94cabf71a0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/service-2.json.gz
new file mode 100644
index 0000000000..35ce8c1e04
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/marketplacecommerceanalytics/2015-07-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..c90a3a315d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/paginators-1.json
new file mode 100644
index 0000000000..65df623e53
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/paginators-1.json
@@ -0,0 +1,46 @@
+{
+ "pagination": {
+ "ListFlows": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Flows"
+ },
+ "ListEntitlements": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Entitlements"
+ },
+ "ListOfferings": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Offerings"
+ },
+ "ListReservations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Reservations"
+ },
+ "ListBridges": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Bridges"
+ },
+ "ListGatewayInstances": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Instances"
+ },
+ "ListGateways": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Gateways"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/service-2.json.gz
new file mode 100644
index 0000000000..a6dac61190
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/waiters-2.json
new file mode 100644
index 0000000000..75581d6a94
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconnect/2018-11-14/waiters-2.json
@@ -0,0 +1,118 @@
+{
+ "version": 2,
+ "waiters": {
+ "FlowActive": {
+ "description": "Wait until a flow is active",
+ "operation": "DescribeFlow",
+ "delay": 3,
+ "maxAttempts": 40,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "ACTIVE"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "STARTING"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "UPDATING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 503
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "ERROR"
+ }
+ ]
+ },
+ "FlowStandby": {
+ "description": "Wait until a flow is in standby mode",
+ "operation": "DescribeFlow",
+ "delay": 3,
+ "maxAttempts": 40,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "STANDBY"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "STOPPING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 503
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "ERROR"
+ }
+ ]
+ },
+ "FlowDeleted": {
+ "description": "Wait until a flow is deleted",
+ "operation": "DescribeFlow",
+ "delay": 3,
+ "maxAttempts": 40,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "status",
+ "expected": 404
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "DELETING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 503
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "Flow.Status",
+ "expected": "ERROR"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..39099dc6ca
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/paginators-1.json
new file mode 100644
index 0000000000..5588b9e677
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "DescribeEndpoints": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Endpoints"
+ },
+ "ListJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Jobs"
+ },
+ "ListPresets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Presets"
+ },
+ "ListJobTemplates": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobTemplates"
+ },
+ "ListQueues": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Queues"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/service-2.json.gz
new file mode 100644
index 0000000000..becf935c6b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediaconvert/2017-08-29/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..7ec3026da3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/paginators-1.json
new file mode 100644
index 0000000000..eb679fff4e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/paginators-1.json
@@ -0,0 +1,64 @@
+{
+ "pagination": {
+ "ListInputs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Inputs"
+ },
+ "ListChannels": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Channels"
+ },
+ "ListInputSecurityGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InputSecurityGroups"
+ },
+ "ListOfferings": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Offerings"
+ },
+ "ListReservations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Reservations"
+ },
+ "DescribeSchedule": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ScheduleActions"
+ },
+ "ListMultiplexPrograms": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MultiplexPrograms"
+ },
+ "ListMultiplexes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Multiplexes"
+ },
+ "ListInputDevices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InputDevices"
+ },
+ "ListInputDeviceTransfers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InputDeviceTransfers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/service-2.json.gz
new file mode 100644
index 0000000000..d9488c2074
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/waiters-2.json
new file mode 100644
index 0000000000..c0e618d7b0
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medialive/2017-10-14/waiters-2.json
@@ -0,0 +1,298 @@
+{
+ "version": 2,
+ "waiters": {
+ "ChannelCreated": {
+ "description": "Wait until a channel has been created",
+ "operation": "DescribeChannel",
+ "delay": 3,
+ "maxAttempts": 5,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "IDLE"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "CREATING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "CREATE_FAILED"
+ }
+ ]
+ },
+ "ChannelRunning": {
+ "description": "Wait until a channel is running",
+ "operation": "DescribeChannel",
+ "delay": 5,
+ "maxAttempts": 120,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "RUNNING"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "STARTING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "ChannelStopped": {
+ "description": "Wait until a channel has is stopped",
+ "operation": "DescribeChannel",
+ "delay": 5,
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "IDLE"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "STOPPING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "ChannelDeleted": {
+ "description": "Wait until a channel has been deleted",
+ "operation": "DescribeChannel",
+ "delay": 5,
+ "maxAttempts": 84,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DELETED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DELETING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "InputAttached": {
+ "description": "Wait until an input has been attached",
+ "operation": "DescribeInput",
+ "delay": 5,
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "ATTACHED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DETACHED"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "InputDetached": {
+ "description": "Wait until an input has been detached",
+ "operation": "DescribeInput",
+ "delay": 5,
+ "maxAttempts": 84,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DETACHED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "CREATING"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "ATTACHED"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "InputDeleted": {
+ "description": "Wait until an input has been deleted",
+ "operation": "DescribeInput",
+ "delay": 5,
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DELETED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DELETING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "MultiplexCreated": {
+ "description": "Wait until a multiplex has been created",
+ "operation": "DescribeMultiplex",
+ "delay": 3,
+ "maxAttempts": 5,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "IDLE"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "CREATING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ },
+ {
+ "state": "failure",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "CREATE_FAILED"
+ }
+ ]
+ },
+ "MultiplexRunning": {
+ "description": "Wait until a multiplex is running",
+ "operation": "DescribeMultiplex",
+ "delay": 5,
+ "maxAttempts": 120,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "RUNNING"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "STARTING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "MultiplexStopped": {
+ "description": "Wait until a multiplex has is stopped",
+ "operation": "DescribeMultiplex",
+ "delay": 5,
+ "maxAttempts": 28,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "IDLE"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "STOPPING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "MultiplexDeleted": {
+ "description": "Wait until a multiplex has been deleted",
+ "operation": "DescribeMultiplex",
+ "delay": 5,
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DELETED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "State",
+ "expected": "DELETING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0736cbe60d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/paginators-1.json
new file mode 100644
index 0000000000..df498b9fa4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListAssets": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Assets"
+ },
+ "ListPackagingConfigurations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PackagingConfigurations"
+ },
+ "ListPackagingGroups": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PackagingGroups"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/service-2.json.gz
new file mode 100644
index 0000000000..959bf944cf
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage-vod/2018-11-07/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0efe714e4d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/paginators-1.json
new file mode 100644
index 0000000000..24e44104b1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListChannels": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Channels"
+ },
+ "ListOriginEndpoints": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "OriginEndpoints"
+ },
+ "ListHarvestJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "HarvestJobs"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/service-2.json.gz
new file mode 100644
index 0000000000..32851c5ce3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackage/2017-10-12/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..3d0a7e9d3f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/paginators-1.json
new file mode 100644
index 0000000000..92079806f5
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListChannelGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Items"
+ },
+ "ListChannels": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Items"
+ },
+ "ListOriginEndpoints": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/service-2.json.gz
new file mode 100644
index 0000000000..ff50cd99fd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediapackagev2/2022-12-25/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..7ad7a0a0cb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/paginators-1.json
new file mode 100644
index 0000000000..7b1c0f7ed4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListItems": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/service-2.json.gz
new file mode 100644
index 0000000000..264793e923
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore-data/2017-09-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..ee0e6ac288
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/paginators-1.json
new file mode 100644
index 0000000000..ed3ece022c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListContainers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Containers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/service-2.json.gz
new file mode 100644
index 0000000000..7cdd4e5e11
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediastore/2017-09-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4f67e399ec
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/paginators-1.json
new file mode 100644
index 0000000000..fe39ff81f7
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/paginators-1.json
@@ -0,0 +1,52 @@
+{
+ "pagination": {
+ "ListPlaybackConfigurations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "GetChannelSchedule": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "ListChannels": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "ListSourceLocations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "ListVodSources": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "ListAlerts": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "ListPrefetchSchedules": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ },
+ "ListLiveSources": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/service-2.json.gz
new file mode 100644
index 0000000000..d037f9b0df
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mediatailor/2018-04-23/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..c29c0b2c33
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/paginators-1.json
new file mode 100644
index 0000000000..807d05276f
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListDICOMImportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "jobSummaries"
+ },
+ "ListDatastores": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "datastoreSummaries"
+ },
+ "ListImageSetVersions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "imageSetPropertiesList"
+ },
+ "SearchImageSets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "imageSetsMetadataSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/service-2.json.gz
new file mode 100644
index 0000000000..48129c4223
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/medical-imaging/2023-07-19/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..123fa77247
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/paginators-1.json
new file mode 100644
index 0000000000..672949b0b6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/paginators-1.json
@@ -0,0 +1,76 @@
+{
+ "pagination": {
+ "DescribeACLs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ACLs"
+ },
+ "DescribeClusters": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Clusters"
+ },
+ "DescribeEngineVersions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "EngineVersions"
+ },
+ "DescribeEvents": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Events"
+ },
+ "DescribeParameterGroups": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ParameterGroups"
+ },
+ "DescribeParameters": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Parameters"
+ },
+ "DescribeReservedNodes": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ReservedNodes"
+ },
+ "DescribeReservedNodesOfferings": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ReservedNodesOfferings"
+ },
+ "DescribeServiceUpdates": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ServiceUpdates"
+ },
+ "DescribeSnapshots": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Snapshots"
+ },
+ "DescribeSubnetGroups": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "SubnetGroups"
+ },
+ "DescribeUsers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Users"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/service-2.json.gz
new file mode 100644
index 0000000000..be38dc5e24
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/memorydb/2021-01-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..92f571501e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/service-2.json.gz
new file mode 100644
index 0000000000..7232db92a1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/meteringmarketplace/2016-01-14/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..3041d7e516
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/paginators-1.json
new file mode 100644
index 0000000000..97efd0a5a9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListCreatedArtifacts": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CreatedArtifactList"
+ },
+ "ListDiscoveredResources": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DiscoveredResourceList"
+ },
+ "ListMigrationTasks": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "MigrationTaskSummaryList"
+ },
+ "ListProgressUpdateStreams": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ProgressUpdateStreamSummaryList"
+ },
+ "ListApplicationStates": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ApplicationStateList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/service-2.json.gz
new file mode 100644
index 0000000000..5bea858151
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgh/2017-05-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a3f0c1125d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/paginators-1.json
new file mode 100644
index 0000000000..6cdc06a7ad
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/paginators-1.json
@@ -0,0 +1,100 @@
+{
+ "pagination": {
+ "DescribeJobLogItems": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "DescribeJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "DescribeReplicationConfigurationTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "DescribeSourceServers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "DescribeVcenterClients": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "DescribeLaunchConfigurationTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListApplications": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListSourceServerActions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListTemplateActions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListWaves": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListExportErrors": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListExports": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListImportErrors": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListImports": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListManagedAccounts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListConnectors": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/service-2.json.gz
new file mode 100644
index 0000000000..766a325790
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mgn/2020-02-26/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a30623eed3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/paginators-1.json
new file mode 100644
index 0000000000..79ae0ffa13
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListApplications": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ApplicationSummaryList"
+ },
+ "ListEnvironmentVpcs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EnvironmentVpcList"
+ },
+ "ListEnvironments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EnvironmentSummaryList"
+ },
+ "ListRoutes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RouteSummaryList"
+ },
+ "ListServices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ServiceSummaryList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/service-2.json.gz
new file mode 100644
index 0000000000..849b8972b8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migration-hub-refactor-spaces/2021-10-26/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..077c645f21
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/service-2.json.gz
new file mode 100644
index 0000000000..4f89e78749
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhub-config/2019-06-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a6f9537619
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/paginators-1.json
new file mode 100644
index 0000000000..4c452221fb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/paginators-1.json
@@ -0,0 +1,46 @@
+{
+ "pagination": {
+ "ListPlugins": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "plugins"
+ },
+ "ListTemplateStepGroups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templateStepGroupSummary"
+ },
+ "ListTemplateSteps": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templateStepSummaryList"
+ },
+ "ListTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templateSummary"
+ },
+ "ListWorkflowStepGroups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "workflowStepGroupsSummary"
+ },
+ "ListWorkflowSteps": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "workflowStepsSummary"
+ },
+ "ListWorkflows": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "migrationWorkflowSummary"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/service-2.json.gz
new file mode 100644
index 0000000000..93dae3c6b9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhuborchestrator/2021-08-28/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e243bf58c8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.json
new file mode 100644
index 0000000000..889a45ef3b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "GetServerDetails": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "associatedApplications"
+ },
+ "ListApplicationComponents": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "applicationComponentInfos"
+ },
+ "ListCollectors": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "Collectors"
+ },
+ "ListImportFileTask": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "taskInfos"
+ },
+ "ListServers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "serverInfos"
+ },
+ "ListAnalyzableServers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "analyzableServers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..2524463ac8
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.sdk-extras.json
@@ -0,0 +1,12 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "GetServerDetails": {
+ "non_aggregate_keys": [
+ "serverDetail"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/service-2.json.gz
new file mode 100644
index 0000000000..2b5ab7f0e0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/migrationhubstrategy/2020-02-19/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..60973ef154
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/paginators-1.json
new file mode 100644
index 0000000000..e86bb7d02b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListBundles": {
+ "result_key": "bundleList",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ },
+ "ListProjects": {
+ "result_key": "projects",
+ "output_token": "nextToken",
+ "input_token": "nextToken",
+ "limit_key": "maxResults"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/service-2.json.gz
new file mode 100644
index 0000000000..f1cacba123
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mobile/2017-07-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8685fb52c9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/paginators-1.json
new file mode 100644
index 0000000000..55160732c0
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListBrokers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "BrokerSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/service-2.json.gz
new file mode 100644
index 0000000000..c04e355237
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mq/2017-11-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2a9129ba50
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/paginators-1.json
new file mode 100644
index 0000000000..ea50caccaa
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/paginators-1.json
@@ -0,0 +1,58 @@
+{
+ "pagination": {
+ "ListAssignmentsForHIT": {
+ "result_key": "Assignments",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListQualificationTypes": {
+ "result_key": "QualificationTypes",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListHITs": {
+ "result_key": "HITs",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListWorkerBlocks": {
+ "result_key": "WorkerBlocks",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListReviewableHITs": {
+ "result_key": "HITs",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListHITsForQualificationType": {
+ "result_key": "HITs",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListQualificationRequests": {
+ "result_key": "QualificationRequests",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListWorkersWithQualificationType": {
+ "result_key": "Qualifications",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListBonusPayments": {
+ "result_key": "BonusPayments",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/service-2.json.gz
new file mode 100644
index 0000000000..eff7d63071
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mturk/2017-01-17/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..69b5e170cd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/paginators-1.json
new file mode 100644
index 0000000000..5e218e4616
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListEnvironments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Environments"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/service-2.json.gz
new file mode 100644
index 0000000000..8f0f596eea
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/mwaa/2020-07-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e25b9ffdb9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/paginators-1.json
new file mode 100644
index 0000000000..1de13039c3
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/paginators-1.json
@@ -0,0 +1,100 @@
+{
+ "pagination": {
+ "DescribeDBEngineVersions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBEngineVersions"
+ },
+ "DescribeDBInstances": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBInstances"
+ },
+ "DescribeDBParameterGroups": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBParameterGroups"
+ },
+ "DescribeDBParameters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "Parameters"
+ },
+ "DescribeDBSubnetGroups": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBSubnetGroups"
+ },
+ "DescribeEngineDefaultParameters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "EngineDefaults.Marker",
+ "result_key": "EngineDefaults.Parameters"
+ },
+ "DescribeEventSubscriptions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "EventSubscriptionsList"
+ },
+ "DescribeEvents": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "Events"
+ },
+ "DescribeOrderableDBInstanceOptions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "OrderableDBInstanceOptions"
+ },
+ "DescribeDBClusterParameterGroups": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusterParameterGroups"
+ },
+ "DescribeDBClusterParameters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "Parameters"
+ },
+ "DescribeDBClusterSnapshots": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusterSnapshots"
+ },
+ "DescribeDBClusters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusters"
+ },
+ "DescribePendingMaintenanceActions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "PendingMaintenanceActions"
+ },
+ "DescribeDBClusterEndpoints": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusterEndpoints"
+ },
+ "DescribeGlobalClusters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "GlobalClusters"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/service-2.json.gz
new file mode 100644
index 0000000000..74e1bc28bd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/service-2.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/service-2.sdk-extras.json
new file mode 100644
index 0000000000..85e8a104c2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/service-2.sdk-extras.json
@@ -0,0 +1,23 @@
+ {
+ "version": 1.0,
+ "merge": {
+ "shapes": {
+ "CopyDBClusterSnapshotMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the snapshot to be copied.
"
+ }
+ }
+ },
+ "CreateDBClusterMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the source for the db cluster.
"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/waiters-2.json
new file mode 100644
index 0000000000..e75f03b2aa
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptune/2014-10-31/waiters-2.json
@@ -0,0 +1,90 @@
+{
+ "version": 2,
+ "waiters": {
+ "DBInstanceAvailable": {
+ "delay": 30,
+ "operation": "DescribeDBInstances",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ }
+ ]
+ },
+ "DBInstanceDeleted": {
+ "delay": 30,
+ "operation": "DescribeDBInstances",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "deleted",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "DBInstanceNotFound",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "resetting-master-credentials",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..14d60e5696
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/service-2.json.gz
new file mode 100644
index 0000000000..41a3f63f35
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/neptunedata/2023-08-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a09b4e1d1a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/paginators-1.json
new file mode 100644
index 0000000000..868d06615d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListFirewallPolicies": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FirewallPolicies"
+ },
+ "ListFirewalls": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Firewalls"
+ },
+ "ListRuleGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RuleGroups"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Tags"
+ },
+ "ListTLSInspectionConfigurations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TLSInspectionConfigurations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/service-2.json.gz
new file mode 100644
index 0000000000..f2ca642451
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/network-firewall/2020-11-12/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4ceed5e0fe
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/paginators-1.json
new file mode 100644
index 0000000000..7196ace626
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/paginators-1.json
@@ -0,0 +1,130 @@
+{
+ "pagination": {
+ "DescribeGlobalNetworks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "GlobalNetworks"
+ },
+ "GetCustomerGatewayAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CustomerGatewayAssociations"
+ },
+ "GetDevices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Devices"
+ },
+ "GetLinkAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "LinkAssociations"
+ },
+ "GetLinks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Links"
+ },
+ "GetSites": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Sites"
+ },
+ "GetTransitGatewayRegistrations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TransitGatewayRegistrations"
+ },
+ "GetConnections": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Connections"
+ },
+ "GetTransitGatewayConnectPeerAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TransitGatewayConnectPeerAssociations"
+ },
+ "GetNetworkResourceCounts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "NetworkResourceCounts"
+ },
+ "GetNetworkResourceRelationships": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Relationships"
+ },
+ "GetNetworkResources": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "NetworkResources"
+ },
+ "GetNetworkTelemetry": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "NetworkTelemetry"
+ },
+ "GetConnectPeerAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ConnectPeerAssociations"
+ },
+ "GetCoreNetworkChangeSet": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CoreNetworkChanges"
+ },
+ "ListAttachments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Attachments"
+ },
+ "ListConnectPeers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ConnectPeers"
+ },
+ "ListCoreNetworkPolicyVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CoreNetworkPolicyVersions"
+ },
+ "ListCoreNetworks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CoreNetworks"
+ },
+ "GetCoreNetworkChangeEvents": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CoreNetworkChangeEvents"
+ },
+ "ListPeerings": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Peerings"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/service-2.json.gz
new file mode 100644
index 0000000000..aa753cf986
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/networkmanager/2019-07-05/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..dd03136c38
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/paginators-1.json
new file mode 100644
index 0000000000..e11f664c7c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/paginators-1.json
@@ -0,0 +1,58 @@
+{
+ "pagination": {
+ "ListEulaAcceptances": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "eulaAcceptances"
+ },
+ "ListEulas": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "eulas"
+ },
+ "ListLaunchProfileMembers": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "members"
+ },
+ "ListLaunchProfiles": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "launchProfiles"
+ },
+ "ListStreamingImages": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "streamingImages"
+ },
+ "ListStreamingSessions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "sessions"
+ },
+ "ListStudioComponents": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "studioComponents"
+ },
+ "ListStudioMembers": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "members"
+ },
+ "ListStudios": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "studios"
+ },
+ "ListStreamingSessionBackups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "streamingSessionBackups"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/service-2.json.gz
new file mode 100644
index 0000000000..510f602e2e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/waiters-2.json
new file mode 100644
index 0000000000..2c37a115b4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/nimble/2020-08-01/waiters-2.json
@@ -0,0 +1,234 @@
+{
+ "version" : 2,
+ "waiters" : {
+ "LaunchProfileDeleted" : {
+ "description" : "Wait until a LaunchProfile is Deleted. Use this after invoking DeleteLaunchProfile",
+ "delay" : 5,
+ "maxAttempts" : 150,
+ "operation" : "GetLaunchProfile",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "launchProfile.state",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "launchProfile.state",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "LaunchProfileReady" : {
+ "description" : "Wait until a LaunchProfile is Ready. Use this after invoking CreateLaunchProfile or UpdateLaunchProfile",
+ "delay" : 5,
+ "maxAttempts" : 150,
+ "operation" : "GetLaunchProfile",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "launchProfile.state",
+ "state" : "success",
+ "expected" : "READY"
+ }, {
+ "matcher" : "path",
+ "argument" : "launchProfile.state",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "launchProfile.state",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED"
+ } ]
+ },
+ "StreamingImageDeleted" : {
+ "description" : "Wait until a StreamingImage Deleted. Use this after invoking DeleteStreamingImage",
+ "delay" : 2,
+ "maxAttempts" : 60,
+ "operation" : "GetStreamingImage",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "streamingImage.state",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "streamingImage.state",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "StreamingImageReady" : {
+ "description" : "Wait until a StreamingImage is Ready. Use this after invoking CreateStreamingImage or UpdateStreamingImage",
+ "delay" : 2,
+ "maxAttempts" : 60,
+ "operation" : "GetStreamingImage",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "streamingImage.state",
+ "state" : "success",
+ "expected" : "READY"
+ }, {
+ "matcher" : "path",
+ "argument" : "streamingImage.state",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "streamingImage.state",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED"
+ } ]
+ },
+ "StreamingSessionDeleted" : {
+ "description" : "Wait until a StreamingSessionDeleted. Use this after invoking DeleteStreamingSession",
+ "delay" : 5,
+ "maxAttempts" : 180,
+ "operation" : "GetStreamingSession",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "StreamingSessionReady" : {
+ "description" : "Wait until a StreamingSession is ready. Use this after invoking CreateStreamingSession, StartStreamingSession",
+ "delay" : 10,
+ "maxAttempts" : 180,
+ "operation" : "GetStreamingSession",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "success",
+ "expected" : "READY"
+ }, {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "failure",
+ "expected" : "START_FAILED"
+ } ]
+ },
+ "StreamingSessionStopped" : {
+ "description" : "Wait until a StreamingSessionStopped. Use this after invoking StopStreamingSession",
+ "delay" : 5,
+ "maxAttempts" : 180,
+ "operation" : "GetStreamingSession",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "success",
+ "expected" : "STOPPED"
+ }, {
+ "matcher" : "path",
+ "argument" : "session.state",
+ "state" : "failure",
+ "expected" : "STOP_FAILED"
+ } ]
+ },
+ "StreamingSessionStreamReady" : {
+ "description" : "Wait until a StreamingSessionStream is ready. Use this after invoking CreateStreamingSessionStream",
+ "delay" : 5,
+ "maxAttempts" : 30,
+ "operation" : "GetStreamingSessionStream",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "stream.state",
+ "state" : "success",
+ "expected" : "READY"
+ }, {
+ "matcher" : "path",
+ "argument" : "stream.state",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ } ]
+ },
+ "StudioComponentDeleted" : {
+ "description" : "Wait until a StudioComponent Deleted. Use this after invoking DeleteStudioComponent",
+ "delay" : 1,
+ "maxAttempts" : 120,
+ "operation" : "GetStudioComponent",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "studioComponent.state",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "studioComponent.state",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "StudioComponentReady" : {
+ "description" : "Wait until a StudioComponent is Ready. Use this after invoking CreateStudioComponent or UpdateStudioComponent",
+ "delay" : 2,
+ "maxAttempts" : 60,
+ "operation" : "GetStudioComponent",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "studioComponent.state",
+ "state" : "success",
+ "expected" : "READY"
+ }, {
+ "matcher" : "path",
+ "argument" : "studioComponent.state",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "studioComponent.state",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED"
+ } ]
+ },
+ "StudioDeleted" : {
+ "description" : "Wait until a Studio is Deleted. Use this after invoking DeleteStudio.",
+ "delay" : 2,
+ "maxAttempts" : 60,
+ "operation" : "GetStudio",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "studio.state",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "studio.state",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "StudioReady" : {
+ "description" : "Wait until a Studio is Ready. Use this after invoking CreateStudio, UpdateStudio, or StartStudioSSOConfigurationRepair",
+ "delay" : 2,
+ "maxAttempts" : 60,
+ "operation" : "GetStudio",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "studio.state",
+ "state" : "success",
+ "expected" : "READY"
+ }, {
+ "matcher" : "path",
+ "argument" : "studio.state",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "studio.state",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED"
+ } ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..c0125461b8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/paginators-1.json
new file mode 100644
index 0000000000..3595f00983
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListAttachedLinks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Items"
+ },
+ "ListLinks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Items"
+ },
+ "ListSinks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/service-2.json.gz
new file mode 100644
index 0000000000..46c2a4f218
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/oam/2022-06-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..9b63a9894f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/paginators-1.json
new file mode 100644
index 0000000000..bbb13cb116
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/paginators-1.json
@@ -0,0 +1,124 @@
+{
+ "pagination": {
+ "ListAnnotationImportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "annotationImportJobs"
+ },
+ "ListAnnotationStores": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "annotationStores"
+ },
+ "ListReadSetActivationJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "activationJobs"
+ },
+ "ListReadSetExportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "exportJobs"
+ },
+ "ListReadSetImportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "importJobs"
+ },
+ "ListReadSets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "readSets"
+ },
+ "ListReferenceImportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "importJobs"
+ },
+ "ListReferenceStores": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "referenceStores"
+ },
+ "ListReferences": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "references"
+ },
+ "ListRunGroups": {
+ "input_token": "startingToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListRunTasks": {
+ "input_token": "startingToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListRuns": {
+ "input_token": "startingToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListSequenceStores": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "sequenceStores"
+ },
+ "ListVariantImportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "variantImportJobs"
+ },
+ "ListVariantStores": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "variantStores"
+ },
+ "ListWorkflows": {
+ "input_token": "startingToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListMultipartReadSetUploads": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "uploads"
+ },
+ "ListReadSetUploadParts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "parts"
+ },
+ "ListAnnotationStoreVersions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "annotationStoreVersions"
+ },
+ "ListShares": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "shares"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/service-2.json.gz
new file mode 100644
index 0000000000..2398d65781
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/waiters-2.json
new file mode 100644
index 0000000000..9e82e101dc
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/omics/2022-11-28/waiters-2.json
@@ -0,0 +1,546 @@
+{
+ "version" : 2,
+ "waiters" : {
+ "AnnotationImportJobCreated" : {
+ "description" : "Wait until an annotation import is completed",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetAnnotationImportJob",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "SUBMITTED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "IN_PROGRESS"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "CANCELLED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ } ]
+ },
+ "AnnotationStoreCreated" : {
+ "description" : "Wait until an annotation store is created",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetAnnotationStore",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CREATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "UPDATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "AnnotationStoreDeleted" : {
+ "description" : "Wait until an annotation store is deleted.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetAnnotationStore",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "error",
+ "state" : "success",
+ "expected" : "ResourceNotFoundException"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "DELETING"
+ } ]
+ },
+ "AnnotationStoreVersionCreated" : {
+ "description" : "Wait until an annotation store version is created",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetAnnotationStoreVersion",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CREATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "UPDATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "AnnotationStoreVersionDeleted" : {
+ "description" : "Wait until an annotation store version is deleted.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetAnnotationStoreVersion",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "error",
+ "state" : "success",
+ "expected" : "ResourceNotFoundException"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "DELETING"
+ } ]
+ },
+ "ReadSetActivationJobCompleted" : {
+ "description" : "Wait until a job is completed.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetReadSetActivationJob",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "SUBMITTED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "IN_PROGRESS"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CANCELLING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "CANCELLED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "COMPLETED_WITH_FAILURES"
+ } ]
+ },
+ "ReadSetExportJobCompleted" : {
+ "description" : "Wait until a job is completed.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetReadSetExportJob",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "SUBMITTED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "IN_PROGRESS"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CANCELLING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "CANCELLED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "COMPLETED_WITH_FAILURES"
+ } ]
+ },
+ "ReadSetImportJobCompleted" : {
+ "description" : "Wait until a job is completed.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetReadSetImportJob",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "SUBMITTED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "IN_PROGRESS"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CANCELLING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "CANCELLED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "COMPLETED_WITH_FAILURES"
+ } ]
+ },
+ "ReferenceImportJobCompleted" : {
+ "description" : "Wait until a job is completed.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetReferenceImportJob",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "SUBMITTED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "IN_PROGRESS"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CANCELLING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "CANCELLED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "COMPLETED_WITH_FAILURES"
+ } ]
+ },
+ "RunCompleted" : {
+ "description" : "Wait until a run is completed.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetRun",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "PENDING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "STARTING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "RUNNING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "STOPPING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "RunRunning" : {
+ "description" : "Wait until a run is running.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetRun",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "RUNNING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "PENDING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "STARTING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "CANCELLED"
+ } ]
+ },
+ "TaskCompleted" : {
+ "description" : "Wait until a task is completed.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetRunTask",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "PENDING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "STARTING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "RUNNING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "STOPPING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "TaskRunning" : {
+ "description" : "Wait until a task is running.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetRunTask",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "RUNNING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "PENDING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "STARTING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "CANCELLED"
+ } ]
+ },
+ "VariantImportJobCreated" : {
+ "description" : "Wait until variant import is completed",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetVariantImportJob",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "SUBMITTED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "IN_PROGRESS"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "CANCELLED"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "COMPLETED"
+ } ]
+ },
+ "VariantStoreCreated" : {
+ "description" : "Wait until a variant store is created",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetVariantStore",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CREATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "UPDATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "VariantStoreDeleted" : {
+ "description" : "Wait until a variant store is deleted.",
+ "delay" : 30,
+ "maxAttempts" : 20,
+ "operation" : "GetVariantStore",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "DELETED"
+ }, {
+ "matcher" : "error",
+ "state" : "success",
+ "expected" : "ResourceNotFoundException"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "DELETING"
+ } ]
+ },
+ "WorkflowActive" : {
+ "description" : "Wait until a workflow is active.",
+ "delay" : 3,
+ "maxAttempts" : 10,
+ "operation" : "GetWorkflow",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "CREATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "retry",
+ "expected" : "UPDATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2f6bce2da9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/service-2.json.gz
new file mode 100644
index 0000000000..eae179db61
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearch/2021-01-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8ff23aee9f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/service-2.json.gz
new file mode 100644
index 0000000000..23487c327a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opensearchserverless/2021-11-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..202bb06555
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/paginators-1.json
new file mode 100644
index 0000000000..779361580d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "DescribeEcsClusters": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EcsClusters"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/service-2.json.gz
new file mode 100644
index 0000000000..55151e7e8e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/waiters-2.json
new file mode 100644
index 0000000000..1b9dfaad9d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworks/2013-02-18/waiters-2.json
@@ -0,0 +1,289 @@
+{
+ "version": 2,
+ "waiters": {
+ "AppExists": {
+ "delay": 1,
+ "operation": "DescribeApps",
+ "maxAttempts": 40,
+ "acceptors": [
+ {
+ "expected": 200,
+ "matcher": "status",
+ "state": "success"
+ },
+ {
+ "matcher": "status",
+ "expected": 400,
+ "state": "failure"
+ }
+ ]
+ },
+ "DeploymentSuccessful": {
+ "delay": 15,
+ "operation": "DescribeDeployments",
+ "maxAttempts": 40,
+ "description": "Wait until a deployment has completed successfully.",
+ "acceptors": [
+ {
+ "expected": "successful",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Deployments[].Status"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Deployments[].Status"
+ }
+ ]
+ },
+ "InstanceOnline": {
+ "delay": 15,
+ "operation": "DescribeInstances",
+ "maxAttempts": 40,
+ "description": "Wait until OpsWorks instance is online.",
+ "acceptors": [
+ {
+ "expected": "online",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "setup_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "shutting_down",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "start_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stopped",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stopping",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "terminating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "terminated",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stop_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ }
+ ]
+ },
+ "InstanceRegistered": {
+ "delay": 15,
+ "operation": "DescribeInstances",
+ "maxAttempts": 40,
+ "description": "Wait until OpsWorks instance is registered.",
+ "acceptors": [
+ {
+ "expected": "registered",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "setup_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "shutting_down",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stopped",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stopping",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "terminating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "terminated",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stop_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ }
+ ]
+ },
+ "InstanceStopped": {
+ "delay": 15,
+ "operation": "DescribeInstances",
+ "maxAttempts": 40,
+ "description": "Wait until OpsWorks instance is stopped.",
+ "acceptors": [
+ {
+ "expected": "stopped",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "booting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "pending",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "requested",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "running_setup",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "setup_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "start_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "stop_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ }
+ ]
+ },
+ "InstanceTerminated": {
+ "delay": 15,
+ "operation": "DescribeInstances",
+ "maxAttempts": 40,
+ "description": "Wait until OpsWorks instance is terminated.",
+ "acceptors": [
+ {
+ "expected": "terminated",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "ResourceNotFoundException",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "booting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "online",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "pending",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "requested",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "running_setup",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "setup_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ },
+ {
+ "expected": "start_failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Instances[].Status"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5987fcaea9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/paginators-1.json
new file mode 100644
index 0000000000..e714aab158
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "DescribeBackups": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Backups"
+ },
+ "DescribeEvents": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ServerEvents"
+ },
+ "DescribeServers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Servers"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/service-2.json.gz
new file mode 100644
index 0000000000..afcfd2078b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/waiters-2.json
new file mode 100644
index 0000000000..f37dd040b8
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/opsworkscm/2016-11-01/waiters-2.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "waiters": {
+ "NodeAssociated": {
+ "delay": 15,
+ "maxAttempts": 15,
+ "operation": "DescribeNodeAssociationStatus",
+ "description": "Wait until node is associated or disassociated.",
+ "acceptors": [
+ {
+ "expected": "SUCCESS",
+ "state": "success",
+ "matcher": "path",
+ "argument": "NodeAssociationStatus"
+ },
+ {
+ "expected": "FAILED",
+ "state": "failure",
+ "matcher": "path",
+ "argument": "NodeAssociationStatus"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..886ad16a80
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/examples-1.json
new file mode 100644
index 0000000000..8e39290e08
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/examples-1.json
@@ -0,0 +1,1409 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AcceptHandshake": [
+ {
+ "input": {
+ "HandshakeId": "h-examplehandshakeid111"
+ },
+ "output": {
+ "Handshake": {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "20170228T1215Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "juan@example.com",
+ "Type": "EMAIL"
+ }
+ ],
+ "RequestedTimestamp": "20170214T1215Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@amazon.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Org Master Account"
+ },
+ {
+ "Type": "ORGANIZATION_FEATURE_SET",
+ "Value": "ALL"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "ACCOUNT",
+ "Value": "222222222222"
+ }
+ ],
+ "State": "ACCEPTED"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Bill is the owner of an organization, and he invites Juan's account (222222222222) to join his organization. The following example shows Juan's account accepting the handshake and thus agreeing to the invitation.",
+ "id": "to-accept-a-handshake-from-another-account-1472500561150",
+ "title": "To accept a handshake from another account"
+ }
+ ],
+ "AttachPolicy": [
+ {
+ "input": {
+ "PolicyId": "p-examplepolicyid111",
+ "TargetId": "ou-examplerootid111-exampleouid111"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to attach a service control policy (SCP) to an OU:\n",
+ "id": "to-attach-a-policy-to-an-ou",
+ "title": "To attach a policy to an OU"
+ },
+ {
+ "input": {
+ "PolicyId": "p-examplepolicyid111",
+ "TargetId": "333333333333"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to attach a service control policy (SCP) to an account:\n",
+ "id": "to-attach-a-policy-to-an-account",
+ "title": "To attach a policy to an account"
+ }
+ ],
+ "CancelHandshake": [
+ {
+ "input": {
+ "HandshakeId": "h-examplehandshakeid111"
+ },
+ "output": {
+ "Handshake": {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "20170228T1215Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "susan@example.com",
+ "Type": "EMAIL"
+ }
+ ],
+ "RequestedTimestamp": "20170214T1215Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@example.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Master Account"
+ },
+ {
+ "Type": "ORGANIZATION_FEATURE_SET",
+ "Value": "CONSOLIDATED_BILLING"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "ACCOUNT",
+ "Value": "222222222222"
+ },
+ {
+ "Type": "NOTES",
+ "Value": "This is a request for Susan's account to join Bob's organization."
+ }
+ ],
+ "State": "CANCELED"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Bill previously sent an invitation to Susan's account to join his organization. He changes his mind and decides to cancel the invitation before Susan accepts it. The following example shows Bill's cancellation:\n",
+ "id": "to-cancel-a-handshake-sent-to-a-member-account-1472501320506",
+ "title": "To cancel a handshake sent to a member account"
+ }
+ ],
+ "CreateAccount": [
+ {
+ "input": {
+ "AccountName": "Production Account",
+ "Email": "susan@example.com"
+ },
+ "output": {
+ "CreateAccountStatus": {
+ "Id": "car-examplecreateaccountrequestid111",
+ "State": "IN_PROGRESS"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The owner of an organization creates a member account in the organization. The following example shows that when the organization owner creates the member account, the account is preconfigured with the name \"Production Account\" and an owner email address of susan@example.com. An IAM role is automatically created using the default name because the roleName parameter is not used. AWS Organizations sends Susan a \"Welcome to AWS\" email:\n\n",
+ "id": "to-create-a-new-account-that-is-automatically-part-of-the-organization-1472501463507",
+ "title": "To create a new account that is automatically part of the organization"
+ }
+ ],
+ "CreateOrganization": [
+ {
+ "input": {
+ },
+ "output": {
+ "Organization": {
+ "Arn": "arn:aws:organizations::111111111111:organization/o-exampleorgid",
+ "AvailablePolicyTypes": [
+ {
+ "Status": "ENABLED",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ ],
+ "FeatureSet": "ALL",
+ "Id": "o-exampleorgid",
+ "MasterAccountArn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111",
+ "MasterAccountEmail": "bill@example.com",
+ "MasterAccountId": "111111111111"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Bill wants to create an organization using credentials from account 111111111111. The following example shows that the account becomes the master account in the new organization. Because he does not specify a feature set, the new organization defaults to all features enabled and service control policies enabled on the root:\n\n",
+ "id": "to-create-a-new-organization-with-all-features enabled",
+ "title": "To create a new organization with all features enabled"
+ },
+ {
+ "input": {
+ "FeatureSet": "CONSOLIDATED_BILLING"
+ },
+ "output": {
+ "Organization": {
+ "Arn": "arn:aws:organizations::111111111111:organization/o-exampleorgid",
+ "AvailablePolicyTypes": [
+
+ ],
+ "FeatureSet": "CONSOLIDATED_BILLING",
+ "Id": "o-exampleorgid",
+ "MasterAccountArn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111",
+ "MasterAccountEmail": "bill@example.com",
+ "MasterAccountId": "111111111111"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "In the following example, Bill creates an organization using credentials from account 111111111111, and configures the organization to support only the consolidated billing feature set:\n\n",
+ "id": "to-create-a-new-organization-with-consolidated-billing-features-only",
+ "title": "To create a new organization with consolidated billing features only"
+ }
+ ],
+ "CreateOrganizationalUnit": [
+ {
+ "input": {
+ "Name": "AccountingOU",
+ "ParentId": "r-examplerootid111"
+ },
+ "output": {
+ "OrganizationalUnit": {
+ "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111",
+ "Id": "ou-examplerootid111-exampleouid111",
+ "Name": "AccountingOU"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to create an OU that is named AccountingOU. The new OU is directly under the root.:\n\n",
+ "id": "to-create-a-new-organizational-unit",
+ "title": "To create a new organization unit"
+ }
+ ],
+ "CreatePolicy": [
+ {
+ "input": {
+ "Content": "{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":{\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\":\\\"s3:*\\\"}}",
+ "Description": "Enables admins of attached accounts to delegate all S3 permissions",
+ "Name": "AllowAllS3Actions",
+ "Type": "SERVICE_CONTROL_POLICY"
+ },
+ "output": {
+ "Policy": {
+ "Content": "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\"}}",
+ "PolicySummary": {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111",
+ "Description": "Allows delegation of all S3 actions",
+ "Name": "AllowAllS3Actions",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to create a service control policy (SCP) that is named AllowAllS3Actions. The JSON string in the content parameter specifies the content in the policy. The parameter string is escaped with backslashes to ensure that the embedded double quotes in the JSON policy are treated as literals in the parameter, which itself is surrounded by double quotes:\n\n",
+ "id": "to-create-a-service-control-policy",
+ "title": "To create a service control policy"
+ }
+ ],
+ "DeclineHandshake": [
+ {
+ "input": {
+ "HandshakeId": "h-examplehandshakeid111"
+ },
+ "output": {
+ "Handshake": {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2016-12-15T19:27:58Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "222222222222",
+ "Type": "ACCOUNT"
+ },
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ }
+ ],
+ "RequestedTimestamp": "2016-11-30T19:27:58Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@example.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Master Account"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "ACCOUNT",
+ "Value": "222222222222"
+ },
+ {
+ "Type": "NOTES",
+ "Value": "This is an invitation to Susan's account to join the Bill's organization."
+ }
+ ],
+ "State": "DECLINED"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows Susan declining an invitation to join Bill's organization. The DeclineHandshake operation returns a handshake object, showing that the state is now DECLINED:",
+ "id": "to-decline-a-handshake-sent-from-the-master-account-1472502666967",
+ "title": "To decline a handshake sent from the master account"
+ }
+ ],
+ "DeleteOrganizationalUnit": [
+ {
+ "input": {
+ "OrganizationalUnitId": "ou-examplerootid111-exampleouid111"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to delete an OU. The example assumes that you previously removed all accounts and other OUs from the OU:\n\n",
+ "id": "to-delete-an-organizational-unit",
+ "title": "To delete an organization unit"
+ }
+ ],
+ "DeletePolicy": [
+ {
+ "input": {
+ "PolicyId": "p-examplepolicyid111"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to delete a policy from an organization. The example assumes that you previously detached the policy from all entities:\n\n",
+ "id": "to-delete-a-policy",
+ "title": "To delete a policy"
+ }
+ ],
+ "DescribeAccount": [
+ {
+ "input": {
+ "AccountId": "555555555555"
+ },
+ "output": {
+ "Account": {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/555555555555",
+ "Email": "anika@example.com",
+ "Id": "555555555555",
+ "Name": "Beta Account"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows a user in the master account (111111111111) asking for details about account 555555555555:",
+ "id": "to-get-the-details-about-an-account-1472503166868",
+ "title": "To get the details about an account"
+ }
+ ],
+ "DescribeCreateAccountStatus": [
+ {
+ "input": {
+ "CreateAccountRequestId": "car-exampleaccountcreationrequestid"
+ },
+ "output": {
+ "CreateAccountStatus": {
+ "AccountId": "333333333333",
+ "Id": "car-exampleaccountcreationrequestid",
+ "State": "SUCCEEDED"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request the status about a previous request to create an account in an organization. This operation can be called only by a principal from the organization's master account. In the example, the specified \"createAccountRequestId\" comes from the response of the original call to \"CreateAccount\":",
+ "id": "to-get-information-about-a-request-to-create-an-account-1472503727223",
+ "title": "To get information about a request to create an account"
+ }
+ ],
+ "DescribeHandshake": [
+ {
+ "input": {
+ "HandshakeId": "h-examplehandshakeid111"
+ },
+ "output": {
+ "Handshake": {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2016-11-30T17:24:58.046Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "333333333333",
+ "Type": "ACCOUNT"
+ }
+ ],
+ "RequestedTimestamp": "2016-11-30T17:24:58.046Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@example.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Master Account"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "ACCOUNT",
+ "Value": "333333333333"
+ }
+ ],
+ "State": "OPEN"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to request details about a handshake. The handshake ID comes either from the original call to \"InviteAccountToOrganization\", or from a call to \"ListHandshakesForAccount\" or \"ListHandshakesForOrganization\":",
+ "id": "to-get-information-about-a-handshake-1472503400505",
+ "title": "To get information about a handshake"
+ }
+ ],
+ "DescribeOrganization": [
+ {
+ "output": {
+ "Organization": {
+ "Arn": "arn:aws:organizations::111111111111:organization/o-exampleorgid",
+ "AvailablePolicyTypes": [
+ {
+ "Status": "ENABLED",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ ],
+ "FeatureSet": "ALL",
+ "Id": "o-exampleorgid",
+ "MasterAccountArn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111",
+ "MasterAccountEmail": "bill@example.com"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request information about the current user's organization:/n/n",
+ "id": "to-get-information-about-an-organization-1472503400505",
+ "title": "To get information about an organization"
+ }
+ ],
+ "DescribeOrganizationalUnit": [
+ {
+ "input": {
+ "OrganizationalUnitId": "ou-examplerootid111-exampleouid111"
+ },
+ "output": {
+ "OrganizationalUnit": {
+ "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111",
+ "Id": "ou-examplerootid111-exampleouid111",
+ "Name": "Accounting Group"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request details about an OU:/n/n",
+ "id": "to-get-information-about-an-organizational-unit",
+ "title": "To get information about an organizational unit"
+ }
+ ],
+ "DescribePolicy": [
+ {
+ "input": {
+ "PolicyId": "p-examplepolicyid111"
+ },
+ "output": {
+ "Policy": {
+ "Content": "{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n {\\n \\\"Effect\\\": \\\"Allow\\\",\\n \\\"Action\\\": \\\"*\\\",\\n \\\"Resource\\\": \\\"*\\\"\\n }\\n ]\\n}",
+ "PolicySummary": {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111",
+ "AwsManaged": false,
+ "Description": "Enables admins to delegate S3 permissions",
+ "Id": "p-examplepolicyid111",
+ "Name": "AllowAllS3Actions",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request information about a policy:/n/n",
+ "id": "to-get-information-about-a-policy",
+ "title": "To get information about a policy"
+ }
+ ],
+ "DetachPolicy": [
+ {
+ "input": {
+ "PolicyId": "p-examplepolicyid111",
+ "TargetId": "ou-examplerootid111-exampleouid111"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to detach a policy from an OU:/n/n",
+ "id": "to-detach-a-policy-from-a-root-ou-or-account",
+ "title": "To detach a policy from a root, OU, or account"
+ }
+ ],
+ "DisablePolicyType": [
+ {
+ "input": {
+ "PolicyType": "SERVICE_CONTROL_POLICY",
+ "RootId": "r-examplerootid111"
+ },
+ "output": {
+ "Root": {
+ "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111",
+ "Id": "r-examplerootid111",
+ "Name": "Root",
+ "PolicyTypes": [
+
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to disable the service control policy (SCP) policy type in a root. The response shows that the PolicyTypes response element no longer includes SERVICE_CONTROL_POLICY:/n/n",
+ "id": "to-disable-a-policy-type-in-a-root",
+ "title": "To disable a policy type in a root"
+ }
+ ],
+ "EnableAllFeatures": [
+ {
+ "input": {
+ },
+ "output": {
+ "Handshake": {
+ "Action": "ENABLE_ALL_FEATURES",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/enable_all_features/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2017-02-28T09:35:40.05Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ }
+ ],
+ "RequestedTimestamp": "2017-02-13T09:35:40.05Z",
+ "Resources": [
+ {
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ }
+ ],
+ "State": "REQUESTED"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows the administrator asking all the invited accounts in the organization to approve enabling all features in the organization. AWS Organizations sends an email to the address that is registered with every invited member account asking the owner to approve the change by accepting the handshake that is sent. After all invited member accounts accept the handshake, the organization administrator can finalize the change to enable all features, and those with appropriate permissions can create policies and apply them to roots, OUs, and accounts:/n/n",
+ "id": "to-enable-all-features-in-an-organization",
+ "title": "To enable all features in an organization"
+ }
+ ],
+ "EnablePolicyType": [
+ {
+ "input": {
+ "PolicyType": "SERVICE_CONTROL_POLICY",
+ "RootId": "r-examplerootid111"
+ },
+ "output": {
+ "Root": {
+ "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111",
+ "Id": "r-examplerootid111",
+ "Name": "Root",
+ "PolicyTypes": [
+ {
+ "Status": "ENABLED",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to enable the service control policy (SCP) policy type in a root. The output shows a root object with a PolicyTypes response element showing that SCPs are now enabled:/n/n",
+ "id": "to-enable-a-policy-type-in-a-root",
+ "title": "To enable a policy type in a root"
+ }
+ ],
+ "InviteAccountToOrganization": [
+ {
+ "input": {
+ "Notes": "This is a request for Juan's account to join Bill's organization",
+ "Target": {
+ "Id": "juan@example.com",
+ "Type": "EMAIL"
+ }
+ },
+ "output": {
+ "Handshake": {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2017-02-16T09:36:05.02Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "juan@example.com",
+ "Type": "EMAIL"
+ }
+ ],
+ "RequestedTimestamp": "2017-02-01T09:36:05.02Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@amazon.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Org Master Account"
+ },
+ {
+ "Type": "ORGANIZATION_FEATURE_SET",
+ "Value": "FULL"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "EMAIL",
+ "Value": "juan@example.com"
+ }
+ ],
+ "State": "OPEN"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows the admin of the master account owned by bill@example.com inviting the account owned by juan@example.com to join an organization.",
+ "id": "to-invite-an-account-to-join-an-organization-1472508594110",
+ "title": "To invite an account to join an organization"
+ }
+ ],
+ "LeaveOrganization": [
+ {
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "TThe following example shows how to remove your member account from an organization:",
+ "id": "to-leave-an-organization-as-a-member-account-1472508784736",
+ "title": "To leave an organization as a member account"
+ }
+ ],
+ "ListAccounts": [
+ {
+ "input": {
+ },
+ "output": {
+ "Accounts": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111",
+ "Email": "bill@example.com",
+ "Id": "111111111111",
+ "JoinedMethod": "INVITED",
+ "JoinedTimestamp": "20161215T193015Z",
+ "Name": "Master Account",
+ "Status": "ACTIVE"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/222222222222",
+ "Email": "alice@example.com",
+ "Id": "222222222222",
+ "JoinedMethod": "INVITED",
+ "JoinedTimestamp": "20161215T210221Z",
+ "Name": "Developer Account",
+ "Status": "ACTIVE"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333",
+ "Email": "juan@example.com",
+ "Id": "333333333333",
+ "JoinedMethod": "INVITED",
+ "JoinedTimestamp": "20161215T210347Z",
+ "Name": "Test Account",
+ "Status": "ACTIVE"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/444444444444",
+ "Email": "anika@example.com",
+ "Id": "444444444444",
+ "JoinedMethod": "INVITED",
+ "JoinedTimestamp": "20161215T210332Z",
+ "Name": "Production Account",
+ "Status": "ACTIVE"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to request a list of the accounts in an organization:",
+ "id": "to-retrieve-a-list-of-all-of-the-accounts-in-an-organization-1472509590974",
+ "title": "To retrieve a list of all of the accounts in an organization"
+ }
+ ],
+ "ListAccountsForParent": [
+ {
+ "input": {
+ "ParentId": "ou-examplerootid111-exampleouid111"
+ },
+ "output": {
+ "Accounts": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333",
+ "Email": "juan@example.com",
+ "Id": "333333333333",
+ "JoinedMethod": "INVITED",
+ "JoinedTimestamp": 1481835795.536,
+ "Name": "Development Account",
+ "Status": "ACTIVE"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/444444444444",
+ "Email": "anika@example.com",
+ "Id": "444444444444",
+ "JoinedMethod": "INVITED",
+ "JoinedTimestamp": 1481835812.143,
+ "Name": "Test Account",
+ "Status": "ACTIVE"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request a list of the accounts in an OU:/n/n",
+ "id": "to-retrieve-a-list-of-all-of-the-accounts-in-a-root-or-ou-1472509590974",
+ "title": "To retrieve a list of all of the accounts in a root or OU"
+ }
+ ],
+ "ListChildren": [
+ {
+ "input": {
+ "ChildType": "ORGANIZATIONAL_UNIT",
+ "ParentId": "ou-examplerootid111-exampleouid111"
+ },
+ "output": {
+ "Children": [
+ {
+ "Id": "ou-examplerootid111-exampleouid111",
+ "Type": "ORGANIZATIONAL_UNIT"
+ },
+ {
+ "Id": "ou-examplerootid111-exampleouid222",
+ "Type": "ORGANIZATIONAL_UNIT"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request a list of the child OUs in a parent root or OU:/n/n",
+ "id": "to-retrieve-a-list-of-all-of-the-child-accounts-and-OUs-in-a-parent-container",
+ "title": "To retrieve a list of all of the child accounts and OUs in a parent root or OU"
+ }
+ ],
+ "ListCreateAccountStatus": [
+ {
+ "input": {
+ "States": [
+ "SUCCEEDED"
+ ]
+ },
+ "output": {
+ "CreateAccountStatuses": [
+ {
+ "AccountId": "444444444444",
+ "AccountName": "Developer Test Account",
+ "CompletedTimestamp": "2017-01-15T13:45:23.6Z",
+ "Id": "car-exampleaccountcreationrequestid1",
+ "RequestedTimestamp": "2017-01-15T13:45:23.01Z",
+ "State": "SUCCEEDED"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows a user requesting a list of only the completed account creation requests made for the current organization:",
+ "id": "to-get-a-list-of-completed-account-creation-requests-made-in-the-organization",
+ "title": "To get a list of completed account creation requests made in the organization"
+ },
+ {
+ "input": {
+ "States": [
+ "IN_PROGRESS"
+ ]
+ },
+ "output": {
+ "CreateAccountStatuses": [
+ {
+ "AccountName": "Production Account",
+ "Id": "car-exampleaccountcreationrequestid2",
+ "RequestedTimestamp": "2017-01-15T13:45:23.01Z",
+ "State": "IN_PROGRESS"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows a user requesting a list of only the in-progress account creation requests made for the current organization:",
+ "id": "to-get-a-list-of-all-account-creation-requests-made-in-the-organization-1472509174532",
+ "title": "To get a list of all account creation requests made in the organization"
+ }
+ ],
+ "ListHandshakesForAccount": [
+ {
+ "output": {
+ "Handshakes": [
+ {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2017-01-28T14:35:23.3Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "juan@example.com",
+ "Type": "EMAIL"
+ }
+ ],
+ "RequestedTimestamp": "2017-01-13T14:35:23.3Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@amazon.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Org Master Account"
+ },
+ {
+ "Type": "ORGANIZATION_FEATURE_SET",
+ "Value": "FULL"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "EMAIL",
+ "Value": "juan@example.com"
+ }
+ ],
+ "State": "OPEN"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to get a list of handshakes that are associated with the account of the credentials used to call the operation:",
+ "id": "to-retrieve-a-list-of-the-handshakes-sent-to-an-account-1472510214747",
+ "title": "To retrieve a list of the handshakes sent to an account"
+ }
+ ],
+ "ListHandshakesForOrganization": [
+ {
+ "output": {
+ "Handshakes": [
+ {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2017-01-28T14:35:23.3Z",
+ "Id": "h-examplehandshakeid111",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "juan@example.com",
+ "Type": "EMAIL"
+ }
+ ],
+ "RequestedTimestamp": "2017-01-13T14:35:23.3Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@amazon.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Org Master Account"
+ },
+ {
+ "Type": "ORGANIZATION_FEATURE_SET",
+ "Value": "FULL"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "EMAIL",
+ "Value": "juan@example.com"
+ }
+ ],
+ "State": "OPEN"
+ },
+ {
+ "Action": "INVITE",
+ "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111",
+ "ExpirationTimestamp": "2017-01-28T14:35:23.3Z",
+ "Id": "h-examplehandshakeid222",
+ "Parties": [
+ {
+ "Id": "o-exampleorgid",
+ "Type": "ORGANIZATION"
+ },
+ {
+ "Id": "anika@example.com",
+ "Type": "EMAIL"
+ }
+ ],
+ "RequestedTimestamp": "2017-01-13T14:35:23.3Z",
+ "Resources": [
+ {
+ "Resources": [
+ {
+ "Type": "MASTER_EMAIL",
+ "Value": "bill@example.com"
+ },
+ {
+ "Type": "MASTER_NAME",
+ "Value": "Master Account"
+ }
+ ],
+ "Type": "ORGANIZATION",
+ "Value": "o-exampleorgid"
+ },
+ {
+ "Type": "EMAIL",
+ "Value": "anika@example.com"
+ },
+ {
+ "Type": "NOTES",
+ "Value": "This is an invitation to Anika's account to join Bill's organization."
+ }
+ ],
+ "State": "ACCEPTED"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to get a list of handshakes associated with the current organization:",
+ "id": "to-retrieve-a-list-of-the-handshakes-associated-with-an-organization-1472511206653",
+ "title": "To retrieve a list of the handshakes associated with an organization"
+ }
+ ],
+ "ListOrganizationalUnitsForParent": [
+ {
+ "input": {
+ "ParentId": "r-examplerootid111"
+ },
+ "output": {
+ "OrganizationalUnits": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examlerootid111-exampleouid111",
+ "Id": "ou-examplerootid111-exampleouid111",
+ "Name": "Development"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examlerootid111-exampleouid222",
+ "Id": "ou-examplerootid111-exampleouid222",
+ "Name": "Production"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to get a list of OUs in a specified root:/n/n",
+ "id": "to-retrieve-a-list-of-all-of-the-OUs-in-a-parent-container",
+ "title": "To retrieve a list of all of the child OUs in a parent root or OU"
+ }
+ ],
+ "ListParents": [
+ {
+ "input": {
+ "ChildId": "444444444444"
+ },
+ "output": {
+ "Parents": [
+ {
+ "Id": "ou-examplerootid111-exampleouid111",
+ "Type": "ORGANIZATIONAL_UNIT"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to list the root or OUs that contain account 444444444444:/n/n",
+ "id": "to-retrieve-a-list-of-all-of-the-parents-of-a-child-ou-or-account",
+ "title": "To retrieve a list of all of the parents of a child OU or account"
+ }
+ ],
+ "ListPolicies": [
+ {
+ "input": {
+ "Filter": "SERVICE_CONTROL_POLICY"
+ },
+ "output": {
+ "Policies": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111",
+ "AwsManaged": false,
+ "Description": "Enables account admins to delegate permissions for any S3 actions to users and roles in their accounts.",
+ "Id": "p-examplepolicyid111",
+ "Name": "AllowAllS3Actions",
+ "Type": "SERVICE_CONTROL_POLICY"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid222",
+ "AwsManaged": false,
+ "Description": "Enables account admins to delegate permissions for any EC2 actions to users and roles in their accounts.",
+ "Id": "p-examplepolicyid222",
+ "Name": "AllowAllEC2Actions",
+ "Type": "SERVICE_CONTROL_POLICY"
+ },
+ {
+ "Arn": "arn:aws:organizations::aws:policy/service_control_policy/p-FullAWSAccess",
+ "AwsManaged": true,
+ "Description": "Allows access to every operation",
+ "Id": "p-FullAWSAccess",
+ "Name": "FullAWSAccess",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to get a list of service control policies (SCPs):/n/n",
+ "id": "to-retrieve-a-list-of--policies-in-the-organization",
+ "title": "To retrieve a list policies in the organization"
+ }
+ ],
+ "ListPoliciesForTarget": [
+ {
+ "input": {
+ "Filter": "SERVICE_CONTROL_POLICY",
+ "TargetId": "444444444444"
+ },
+ "output": {
+ "Policies": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid222",
+ "AwsManaged": false,
+ "Description": "Enables account admins to delegate permissions for any EC2 actions to users and roles in their accounts.",
+ "Id": "p-examplepolicyid222",
+ "Name": "AllowAllEC2Actions",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to get a list of all service control policies (SCPs) of the type specified by the Filter parameter, that are directly attached to an account. The returned list does not include policies that apply to the account because of inheritance from its location in an OU hierarchy:/n/n",
+ "id": "to-retrieve-a-list-of-policies-attached-to-a-root-ou-or-account",
+ "title": "To retrieve a list policies attached to a root, OU, or account"
+ }
+ ],
+ "ListRoots": [
+ {
+ "input": {
+ },
+ "output": {
+ "Roots": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111",
+ "Id": "r-examplerootid111",
+ "Name": "Root",
+ "PolicyTypes": [
+ {
+ "Status": "ENABLED",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ ]
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to get the list of the roots in the current organization:/n/n",
+ "id": "to-retrieve-a-list-of-roots-in-the-organization",
+ "title": "To retrieve a list of roots in the organization"
+ }
+ ],
+ "ListTargetsForPolicy": [
+ {
+ "input": {
+ "PolicyId": "p-FullAWSAccess"
+ },
+ "output": {
+ "Targets": [
+ {
+ "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111",
+ "Name": "Root",
+ "TargetId": "r-examplerootid111",
+ "Type": "ROOT"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333;",
+ "Name": "Developer Test Account",
+ "TargetId": "333333333333",
+ "Type": "ACCOUNT"
+ },
+ {
+ "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111",
+ "Name": "Accounting",
+ "TargetId": "ou-examplerootid111-exampleouid111",
+ "Type": "ORGANIZATIONAL_UNIT"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to get the list of roots, OUs, and accounts to which the specified policy is attached:/n/n",
+ "id": "to-retrieve-a-list-of-roots-ous-and-accounts-to-which-a-policy-is-attached",
+ "title": "To retrieve a list of roots, OUs, and accounts to which a policy is attached"
+ }
+ ],
+ "MoveAccount": [
+ {
+ "input": {
+ "AccountId": "333333333333",
+ "DestinationParentId": "ou-examplerootid111-exampleouid111",
+ "SourceParentId": "r-examplerootid111"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to move a member account from the root to an OU:/n/n",
+ "id": "to-move-an-ou-or-account-to-another-ou-or-the-root",
+ "title": "To move an OU or account to another OU or the root"
+ }
+ ],
+ "RemoveAccountFromOrganization": [
+ {
+ "input": {
+ "AccountId": "333333333333"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to remove an account from an organization:",
+ "id": "to-remove-an-account-from-an-organization-as-the-master-account",
+ "title": "To remove an account from an organization as the master account"
+ }
+ ],
+ "UpdateOrganizationalUnit": [
+ {
+ "input": {
+ "Name": "AccountingOU",
+ "OrganizationalUnitId": "ou-examplerootid111-exampleouid111"
+ },
+ "output": {
+ "OrganizationalUnit": {
+ "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111",
+ "Id": "ou-examplerootid111-exampleouid111",
+ "Name": "AccountingOU"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to rename an OU. The output confirms the new name:/n/n",
+ "id": "to-rename-an-organizational-unit",
+ "title": "To rename an organizational unit"
+ }
+ ],
+ "UpdatePolicy": [
+ {
+ "input": {
+ "Description": "This description replaces the original.",
+ "Name": "Renamed-Policy",
+ "PolicyId": "p-examplepolicyid111"
+ },
+ "output": {
+ "Policy": {
+ "Content": "{ \"Version\": \"2012-10-17\", \"Statement\": { \"Effect\": \"Allow\", \"Action\": \"ec2:*\", \"Resource\": \"*\" } }",
+ "PolicySummary": {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111",
+ "AwsManaged": false,
+ "Description": "This description replaces the original.",
+ "Id": "p-examplepolicyid111",
+ "Name": "Renamed-Policy",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to rename a policy and give it a new description and new content. The output confirms the new name and description text:/n/n",
+ "id": "to-update-the-details-of-a-policy",
+ "title": "To update the details of a policy"
+ },
+ {
+ "input": {
+ "Content": "{ \\\"Version\\\": \\\"2012-10-17\\\", \\\"Statement\\\": {\\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\": \\\"s3:*\\\", \\\"Resource\\\": \\\"*\\\" } }",
+ "PolicyId": "p-examplepolicyid111"
+ },
+ "output": {
+ "Policy": {
+ "Content": "{ \\\"Version\\\": \\\"2012-10-17\\\", \\\"Statement\\\": { \\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\": \\\"s3:*\\\", \\\"Resource\\\": \\\"*\\\" } }",
+ "PolicySummary": {
+ "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111",
+ "AwsManaged": false,
+ "Description": "This description replaces the original.",
+ "Id": "p-examplepolicyid111",
+ "Name": "Renamed-Policy",
+ "Type": "SERVICE_CONTROL_POLICY"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to replace the JSON text of the SCP from the preceding example with a new JSON policy text string that allows S3 actions instead of EC2 actions:/n/n",
+ "id": "to-update-the-content-of-a-policy",
+ "title": "To update the content of a policy"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/paginators-1.json
new file mode 100644
index 0000000000..0f05c5771e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/paginators-1.json
@@ -0,0 +1,99 @@
+{
+ "pagination": {
+ "ListAccounts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Accounts"
+ },
+ "ListAccountsForParent": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Accounts"
+ },
+ "ListChildren": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Children"
+ },
+ "ListCreateAccountStatus": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CreateAccountStatuses"
+ },
+ "ListHandshakesForAccount": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Handshakes"
+ },
+ "ListHandshakesForOrganization": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Handshakes"
+ },
+ "ListOrganizationalUnitsForParent": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "OrganizationalUnits"
+ },
+ "ListParents": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Parents"
+ },
+ "ListPolicies": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Policies"
+ },
+ "ListPoliciesForTarget": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Policies"
+ },
+ "ListRoots": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Roots"
+ },
+ "ListTargetsForPolicy": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Targets"
+ },
+ "ListAWSServiceAccessForOrganization": {
+ "result_key": "EnabledServicePrincipals",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ },
+ "ListDelegatedAdministrators": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DelegatedAdministrators"
+ },
+ "ListDelegatedServicesForAccount": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DelegatedServices"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/service-2.json.gz
new file mode 100644
index 0000000000..7e26e5f3be
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/organizations/2016-11-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..30e9c6b0f5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/service-2.json.gz
new file mode 100644
index 0000000000..d5c5cf4178
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/osis/2022-01-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5d93f21115
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/paginators-1.json
new file mode 100644
index 0000000000..3641155079
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "GetOutpostInstanceTypes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InstanceTypes"
+ },
+ "ListAssets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Assets"
+ },
+ "ListCatalogItems": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CatalogItems"
+ },
+ "ListOrders": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Orders"
+ },
+ "ListOutposts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Outposts"
+ },
+ "ListSites": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Sites"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..f13d39be68
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/paginators-1.sdk-extras.json
@@ -0,0 +1,13 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "GetOutpostInstanceTypes": {
+ "non_aggregate_keys": [
+ "OutpostArn",
+ "OutpostId"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/service-2.json.gz
new file mode 100644
index 0000000000..d96d3fdd93
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/outposts/2019-12-03/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..987f7c9304
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/service-2.json.gz
new file mode 100644
index 0000000000..876ac57009
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/panorama/2019-07-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/partitions.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/partitions.json
new file mode 100644
index 0000000000..ab107ca551
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/partitions.json
@@ -0,0 +1,213 @@
+{
+ "partitions" : [ {
+ "id" : "aws",
+ "outputs" : {
+ "dnsSuffix" : "amazonaws.com",
+ "dualStackDnsSuffix" : "api.aws",
+ "implicitGlobalRegion" : "us-east-1",
+ "name" : "aws",
+ "supportsDualStack" : true,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$",
+ "regions" : {
+ "af-south-1" : {
+ "description" : "Africa (Cape Town)"
+ },
+ "ap-east-1" : {
+ "description" : "Asia Pacific (Hong Kong)"
+ },
+ "ap-northeast-1" : {
+ "description" : "Asia Pacific (Tokyo)"
+ },
+ "ap-northeast-2" : {
+ "description" : "Asia Pacific (Seoul)"
+ },
+ "ap-northeast-3" : {
+ "description" : "Asia Pacific (Osaka)"
+ },
+ "ap-south-1" : {
+ "description" : "Asia Pacific (Mumbai)"
+ },
+ "ap-south-2" : {
+ "description" : "Asia Pacific (Hyderabad)"
+ },
+ "ap-southeast-1" : {
+ "description" : "Asia Pacific (Singapore)"
+ },
+ "ap-southeast-2" : {
+ "description" : "Asia Pacific (Sydney)"
+ },
+ "ap-southeast-3" : {
+ "description" : "Asia Pacific (Jakarta)"
+ },
+ "ap-southeast-4" : {
+ "description" : "Asia Pacific (Melbourne)"
+ },
+ "aws-global" : {
+ "description" : "AWS Standard global region"
+ },
+ "ca-central-1" : {
+ "description" : "Canada (Central)"
+ },
+ "eu-central-1" : {
+ "description" : "Europe (Frankfurt)"
+ },
+ "eu-central-2" : {
+ "description" : "Europe (Zurich)"
+ },
+ "eu-north-1" : {
+ "description" : "Europe (Stockholm)"
+ },
+ "eu-south-1" : {
+ "description" : "Europe (Milan)"
+ },
+ "eu-south-2" : {
+ "description" : "Europe (Spain)"
+ },
+ "eu-west-1" : {
+ "description" : "Europe (Ireland)"
+ },
+ "eu-west-2" : {
+ "description" : "Europe (London)"
+ },
+ "eu-west-3" : {
+ "description" : "Europe (Paris)"
+ },
+ "il-central-1" : {
+ "description" : "Israel (Tel Aviv)"
+ },
+ "me-central-1" : {
+ "description" : "Middle East (UAE)"
+ },
+ "me-south-1" : {
+ "description" : "Middle East (Bahrain)"
+ },
+ "sa-east-1" : {
+ "description" : "South America (Sao Paulo)"
+ },
+ "us-east-1" : {
+ "description" : "US East (N. Virginia)"
+ },
+ "us-east-2" : {
+ "description" : "US East (Ohio)"
+ },
+ "us-west-1" : {
+ "description" : "US West (N. California)"
+ },
+ "us-west-2" : {
+ "description" : "US West (Oregon)"
+ }
+ }
+ }, {
+ "id" : "aws-cn",
+ "outputs" : {
+ "dnsSuffix" : "amazonaws.com.cn",
+ "dualStackDnsSuffix" : "api.amazonwebservices.com.cn",
+ "implicitGlobalRegion" : "cn-northwest-1",
+ "name" : "aws-cn",
+ "supportsDualStack" : true,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^cn\\-\\w+\\-\\d+$",
+ "regions" : {
+ "aws-cn-global" : {
+ "description" : "AWS China global region"
+ },
+ "cn-north-1" : {
+ "description" : "China (Beijing)"
+ },
+ "cn-northwest-1" : {
+ "description" : "China (Ningxia)"
+ }
+ }
+ }, {
+ "id" : "aws-us-gov",
+ "outputs" : {
+ "dnsSuffix" : "amazonaws.com",
+ "dualStackDnsSuffix" : "api.aws",
+ "implicitGlobalRegion" : "us-gov-west-1",
+ "name" : "aws-us-gov",
+ "supportsDualStack" : true,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$",
+ "regions" : {
+ "aws-us-gov-global" : {
+ "description" : "AWS GovCloud (US) global region"
+ },
+ "us-gov-east-1" : {
+ "description" : "AWS GovCloud (US-East)"
+ },
+ "us-gov-west-1" : {
+ "description" : "AWS GovCloud (US-West)"
+ }
+ }
+ }, {
+ "id" : "aws-iso",
+ "outputs" : {
+ "dnsSuffix" : "c2s.ic.gov",
+ "dualStackDnsSuffix" : "c2s.ic.gov",
+ "implicitGlobalRegion" : "us-iso-east-1",
+ "name" : "aws-iso",
+ "supportsDualStack" : false,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$",
+ "regions" : {
+ "aws-iso-global" : {
+ "description" : "AWS ISO (US) global region"
+ },
+ "us-iso-east-1" : {
+ "description" : "US ISO East"
+ },
+ "us-iso-west-1" : {
+ "description" : "US ISO WEST"
+ }
+ }
+ }, {
+ "id" : "aws-iso-b",
+ "outputs" : {
+ "dnsSuffix" : "sc2s.sgov.gov",
+ "dualStackDnsSuffix" : "sc2s.sgov.gov",
+ "implicitGlobalRegion" : "us-isob-east-1",
+ "name" : "aws-iso-b",
+ "supportsDualStack" : false,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$",
+ "regions" : {
+ "aws-iso-b-global" : {
+ "description" : "AWS ISOB (US) global region"
+ },
+ "us-isob-east-1" : {
+ "description" : "US ISOB East (Ohio)"
+ }
+ }
+ }, {
+ "id" : "aws-iso-e",
+ "outputs" : {
+ "dnsSuffix" : "cloud.adc-e.uk",
+ "dualStackDnsSuffix" : "cloud.adc-e.uk",
+ "implicitGlobalRegion" : "eu-isoe-west-1",
+ "name" : "aws-iso-e",
+ "supportsDualStack" : false,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$",
+ "regions" : { }
+ }, {
+ "id" : "aws-iso-f",
+ "outputs" : {
+ "dnsSuffix" : "csp.hci.ic.gov",
+ "dualStackDnsSuffix" : "csp.hci.ic.gov",
+ "implicitGlobalRegion" : "us-isof-south-1",
+ "name" : "aws-iso-f",
+ "supportsDualStack" : false,
+ "supportsFIPS" : true
+ },
+ "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$",
+ "regions" : { }
+ } ],
+ "version" : "1.1"
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..f81cbd457e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/service-2.json.gz
new file mode 100644
index 0000000000..6cc2c4ff00
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography-data/2022-02-03/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4bad4f44e3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/paginators-1.json
new file mode 100644
index 0000000000..02af499b65
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListAliases": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Aliases"
+ },
+ "ListKeys": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Keys"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Tags"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/service-2.json.gz
new file mode 100644
index 0000000000..05176a9799
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/payment-cryptography/2021-09-14/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0fa0e92f7c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..89234776f1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListConnectors": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Connectors"
+ },
+ "ListDirectoryRegistrations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DirectoryRegistrations"
+ },
+ "ListServicePrincipalNames": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ServicePrincipalNames"
+ },
+ "ListTemplateGroupAccessControlEntries": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AccessControlEntries"
+ },
+ "ListTemplates": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Templates"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..52588b03e7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pca-connector-ad/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..6a94429438
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/service-2.json.gz
new file mode 100644
index 0000000000..7d62ce35e6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-events/2018-03-22/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e8d28c22ba
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/service-2.json.gz
new file mode 100644
index 0000000000..11d11a7edd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize-runtime/2018-05-22/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..6d8b49e642
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/paginators-1.json
new file mode 100644
index 0000000000..ea43852fe9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/paginators-1.json
@@ -0,0 +1,100 @@
+{
+ "pagination": {
+ "ListCampaigns": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "campaigns"
+ },
+ "ListDatasetGroups": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "datasetGroups"
+ },
+ "ListDatasetImportJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "datasetImportJobs"
+ },
+ "ListDatasets": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "datasets"
+ },
+ "ListEventTrackers": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "eventTrackers"
+ },
+ "ListRecipes": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "recipes"
+ },
+ "ListSchemas": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "schemas"
+ },
+ "ListSolutionVersions": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "solutionVersions"
+ },
+ "ListSolutions": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "solutions"
+ },
+ "ListBatchInferenceJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "batchInferenceJobs"
+ },
+ "ListDatasetExportJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "datasetExportJobs"
+ },
+ "ListFilters": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "Filters"
+ },
+ "ListBatchSegmentJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "batchSegmentJobs"
+ },
+ "ListRecommenders": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "recommenders"
+ },
+ "ListMetricAttributionMetrics": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "metrics"
+ },
+ "ListMetricAttributions": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "metricAttributions"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/service-2.json.gz
new file mode 100644
index 0000000000..c94950b0bc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/personalize/2018-05-22/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a487a82a5f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/service-2.json.gz
new file mode 100644
index 0000000000..0f08d8a2f1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pi/2018-02-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..46c30214bb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/paginators-1.json
new file mode 100644
index 0000000000..f2693b1926
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "GetDedicatedIps": {
+ "input_token": "NextToken",
+ "limit_key": "PageSize",
+ "output_token": "NextToken",
+ "result_key": "DedicatedIps"
+ },
+ "ListConfigurationSets": {
+ "input_token": "NextToken",
+ "limit_key": "PageSize",
+ "output_token": "NextToken",
+ "result_key": "ConfigurationSets"
+ },
+ "ListDedicatedIpPools": {
+ "input_token": "NextToken",
+ "limit_key": "PageSize",
+ "output_token": "NextToken",
+ "result_key": "DedicatedIpPools"
+ },
+ "ListDeliverabilityTestReports": {
+ "input_token": "NextToken",
+ "limit_key": "PageSize",
+ "output_token": "NextToken",
+ "result_key": "DeliverabilityTestReports"
+ },
+ "ListEmailIdentities": {
+ "input_token": "NextToken",
+ "limit_key": "PageSize",
+ "output_token": "NextToken",
+ "result_key": "EmailIdentities"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/service-2.json.gz
new file mode 100644
index 0000000000..d19e053258
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-email/2018-07-26/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..32f1c4014c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/paginators-1.json
new file mode 100644
index 0000000000..a9ee30e497
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/paginators-1.json
@@ -0,0 +1,124 @@
+{
+ "pagination": {
+ "DescribeAccountAttributes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AccountAttributes"
+ },
+ "DescribeAccountLimits": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AccountLimits"
+ },
+ "DescribeConfigurationSets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ConfigurationSets"
+ },
+ "DescribeKeywords": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Keywords"
+ },
+ "DescribeOptOutLists": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "OptOutLists"
+ },
+ "DescribeOptedOutNumbers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "OptedOutNumbers"
+ },
+ "DescribePhoneNumbers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PhoneNumbers"
+ },
+ "DescribePools": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Pools"
+ },
+ "DescribeSenderIds": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "SenderIds"
+ },
+ "DescribeSpendLimits": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "SpendLimits"
+ },
+ "ListPoolOriginationIdentities": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "OriginationIdentities"
+ },
+ "DescribeRegistrationAttachments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationAttachments"
+ },
+ "DescribeRegistrationFieldDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationFieldDefinitions"
+ },
+ "DescribeRegistrationFieldValues": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationFieldValues"
+ },
+ "DescribeRegistrationSectionDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationSectionDefinitions"
+ },
+ "DescribeRegistrationTypeDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationTypeDefinitions"
+ },
+ "DescribeRegistrationVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationVersions"
+ },
+ "DescribeRegistrations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Registrations"
+ },
+ "DescribeVerifiedDestinationNumbers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "VerifiedDestinationNumbers"
+ },
+ "ListRegistrationAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RegistrationAssociations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..7db1e53015
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/paginators-1.sdk-extras.json
@@ -0,0 +1,55 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "DescribeKeywords": {
+ "non_aggregate_keys": [
+ "OriginationIdentity",
+ "OriginationIdentityArn"
+ ]
+ },
+ "DescribeRegistrationFieldDefinitions": {
+ "non_aggregate_keys": [
+ "RegistrationType"
+ ]
+ },
+ "DescribeRegistrationFieldValues": {
+ "non_aggregate_keys": [
+ "RegistrationId",
+ "RegistrationArn",
+ "VersionNumber"
+ ]
+ },
+ "DescribeRegistrationSectionDefinitions": {
+ "non_aggregate_keys": [
+ "RegistrationType"
+ ]
+ },
+ "DescribeRegistrationVersions": {
+ "non_aggregate_keys": [
+ "RegistrationId",
+ "RegistrationArn"
+ ]
+ },
+ "DescribeOptedOutNumbers": {
+ "non_aggregate_keys": [
+ "OptOutListArn",
+ "OptOutListName"
+ ]
+ },
+ "ListPoolOriginationIdentities": {
+ "non_aggregate_keys": [
+ "PoolArn",
+ "PoolId"
+ ]
+ },
+ "ListRegistrationAssociations": {
+ "non_aggregate_keys": [
+ "RegistrationId",
+ "RegistrationArn",
+ "RegistrationType"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/service-2.json.gz
new file mode 100644
index 0000000000..55b073a7ec
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice-v2/2022-03-31/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice/2018-09-05/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice/2018-09-05/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4dfe7254a1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice/2018-09-05/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice/2018-09-05/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice/2018-09-05/service-2.json.gz
new file mode 100644
index 0000000000..a3867ce41c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint-sms-voice/2018-09-05/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..3d0ab34be7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/service-2.json.gz
new file mode 100644
index 0000000000..2f2932b8a2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pinpoint/2016-12-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..55b7a5e54e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/paginators-1.json
new file mode 100644
index 0000000000..4663077cb4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListPipes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "Limit",
+ "result_key": "Pipes"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/service-2.json.gz
new file mode 100644
index 0000000000..16ce4b388b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pipes/2015-10-07/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a22c28f930
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/examples-1.json
new file mode 100644
index 0000000000..38205dbea2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/examples-1.json
@@ -0,0 +1,171 @@
+{
+ "version": "1.0",
+ "examples": {
+ "DeleteLexicon": [
+ {
+ "input": {
+ "Name": "example"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Deletes a specified pronunciation lexicon stored in an AWS Region.",
+ "id": "to-delete-a-lexicon-1481922498332",
+ "title": "To delete a lexicon"
+ }
+ ],
+ "DescribeVoices": [
+ {
+ "input": {
+ "LanguageCode": "en-GB"
+ },
+ "output": {
+ "Voices": [
+ {
+ "Gender": "Female",
+ "Id": "Emma",
+ "LanguageCode": "en-GB",
+ "LanguageName": "British English",
+ "Name": "Emma"
+ },
+ {
+ "Gender": "Male",
+ "Id": "Brian",
+ "LanguageCode": "en-GB",
+ "LanguageName": "British English",
+ "Name": "Brian"
+ },
+ {
+ "Gender": "Female",
+ "Id": "Amy",
+ "LanguageCode": "en-GB",
+ "LanguageName": "British English",
+ "Name": "Amy"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns the list of voices that are available for use when requesting speech synthesis. Displayed languages are those within the specified language code. If no language code is specified, voices for all available languages are displayed.",
+ "id": "to-describe-available-voices-1482180557753",
+ "title": "To describe available voices"
+ }
+ ],
+ "GetLexicon": [
+ {
+ "input": {
+ "Name": ""
+ },
+ "output": {
+ "Lexicon": {
+ "Content": "\r\n\r\n \r\n W3C\r\n World Wide Web Consortium\r\n \r\n",
+ "Name": "example"
+ },
+ "LexiconAttributes": {
+ "Alphabet": "ipa",
+ "LanguageCode": "en-US",
+ "LastModified": 1478542980.117,
+ "LexemesCount": 1,
+ "LexiconArn": "arn:aws:polly:us-east-1:123456789012:lexicon/example",
+ "Size": 503
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns the content of the specified pronunciation lexicon stored in an AWS Region.",
+ "id": "to-retrieve-a-lexicon-1481912870836",
+ "title": "To retrieve a lexicon"
+ }
+ ],
+ "ListLexicons": [
+ {
+ "input": {
+ },
+ "output": {
+ "Lexicons": [
+ {
+ "Attributes": {
+ "Alphabet": "ipa",
+ "LanguageCode": "en-US",
+ "LastModified": 1478542980.117,
+ "LexemesCount": 1,
+ "LexiconArn": "arn:aws:polly:us-east-1:123456789012:lexicon/example",
+ "Size": 503
+ },
+ "Name": "example"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a list of pronunciation lexicons stored in an AWS Region.",
+ "id": "to-list-all-lexicons-in-a-region-1481842106487",
+ "title": "To list all lexicons in a region"
+ }
+ ],
+ "PutLexicon": [
+ {
+ "input": {
+ "Content": "file://example.pls",
+ "Name": "W3C"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Stores a pronunciation lexicon in an AWS Region.",
+ "id": "to-save-a-lexicon-1482272584088",
+ "title": "To save a lexicon"
+ }
+ ],
+ "SynthesizeSpeech": [
+ {
+ "input": {
+ "LexiconNames": [
+ "example"
+ ],
+ "OutputFormat": "mp3",
+ "SampleRate": "8000",
+ "Text": "All Gaul is divided into three parts",
+ "TextType": "text",
+ "VoiceId": "Joanna"
+ },
+ "output": {
+ "AudioStream": "TEXT",
+ "ContentType": "audio/mpeg",
+ "RequestCharacters": 37
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Synthesizes plain text or SSML into a file of human-like speech.",
+ "id": "to-synthesize-speech-1482186064046",
+ "title": "To synthesize speech"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/paginators-1.json
new file mode 100644
index 0000000000..dc76e7c1ac
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/paginators-1.json
@@ -0,0 +1,20 @@
+{
+ "pagination": {
+ "DescribeVoices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Voices"
+ },
+ "ListLexicons": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Lexicons"
+ },
+ "ListSpeechSynthesisTasks": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "SynthesisTasks"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/service-2.json.gz
new file mode 100644
index 0000000000..975dbde9f3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/polly/2016-06-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..fb979604a4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/examples-1.json
new file mode 100644
index 0000000000..abc1c59f34
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/examples-1.json
@@ -0,0 +1,104 @@
+{
+ "version": "1.0",
+ "examples": {
+ "DescribeServices": [
+ {
+ "input": {
+ "FormatVersion": "aws_v1",
+ "MaxResults": 1,
+ "ServiceCode": "AmazonEC2"
+ },
+ "output": {
+ "FormatVersion": "aws_v1",
+ "NextToken": "abcdefg123",
+ "Services": [
+ {
+ "AttributeNames": [
+ "volumeType",
+ "maxIopsvolume",
+ "instanceCapacity10xlarge",
+ "locationType",
+ "operation"
+ ],
+ "ServiceCode": "AmazonEC2"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Retrieves the service for the given Service Code.",
+ "id": "to-retrieve-service-metadata",
+ "title": "To retrieve a list of services and service codes"
+ }
+ ],
+ "GetAttributeValues": [
+ {
+ "input": {
+ "AttributeName": "volumeType",
+ "MaxResults": 2,
+ "ServiceCode": "AmazonEC2"
+ },
+ "output": {
+ "AttributeValues": [
+ {
+ "Value": "Throughput Optimized HDD"
+ },
+ {
+ "Value": "Provisioned IOPS"
+ }
+ ],
+ "NextToken": "GpgauEXAMPLEezucl5LV0w==:7GzYJ0nw0DBTJ2J66EoTIIynE6O1uXwQtTRqioJzQadBnDVgHPzI1en4BUQnPCLpzeBk9RQQAWaFieA4+DapFAGLgk+Z/9/cTw9GldnPOHN98+FdmJP7wKU3QQpQ8MQr5KOeBkIsAqvAQYdL0DkL7tHwPtE5iCEByAmg9gcC/yBU1vAOsf7R3VaNN4M5jMDv3woSWqASSIlBVB6tgW78YL22KhssoItM/jWW+aP6Jqtq4mldxp/ct6DWAl+xLFwHU/CbketimPPXyqHF3/UXDw=="
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation returns a list of values available for the given attribute.",
+ "id": "to-retreive-attribute-values",
+ "title": "To retrieve a list of attribute values"
+ }
+ ],
+ "GetProducts": [
+ {
+ "input": {
+ "Filters": [
+ {
+ "Field": "ServiceCode",
+ "Type": "TERM_MATCH",
+ "Value": "AmazonEC2"
+ },
+ {
+ "Field": "volumeType",
+ "Type": "TERM_MATCH",
+ "Value": "Provisioned IOPS"
+ }
+ ],
+ "FormatVersion": "aws_v1",
+ "MaxResults": 1
+ },
+ "output": {
+ "FormatVersion": "aws_v1",
+ "NextToken": "57r3EXAMPLEujbzWfHF7Ciw==:ywSmZsD3mtpQmQLQ5XfOsIMkYybSj+vAT+kGmwMFq+K9DGmIoJkz7lunVeamiOPgthdWSO2a7YKojCO+zY4dJmuNl2QvbNhXs+AJ2Ufn7xGmJncNI2TsEuAsVCUfTAvAQNcwwamtk6XuZ4YdNnooV62FjkV3ZAn40d9+wAxV7+FImvhUHi/+f8afgZdGh2zPUlH8jlV9uUtj0oHp8+DhPUuHXh+WBII1E/aoKpPSm3c=",
+ "PriceList": [
+ "{\"product\":{\"productFamily\":\"Storage\",\"attributes\":{\"storageMedia\":\"SSD-backed\",\"maxThroughputvolume\":\"320 MB/sec\",\"volumeType\":\"Provisioned IOPS\",\"maxIopsvolume\":\"20000\",\"servicecode\":\"AmazonEC2\",\"usagetype\":\"CAN1-EBS:VolumeUsage.piops\",\"locationType\":\"AWS Region\",\"location\":\"Canada (Central)\",\"servicename\":\"Amazon Elastic Compute Cloud\",\"maxVolumeSize\":\"16 TiB\",\"operation\":\"\"},\"sku\":\"WQGC34PB2AWS8R4U\"},\"serviceCode\":\"AmazonEC2\",\"terms\":{\"OnDemand\":{\"WQGC34PB2AWS8R4U.JRTCKXETXF\":{\"priceDimensions\":{\"WQGC34PB2AWS8R4U.JRTCKXETXF.6YS6EN2CT7\":{\"unit\":\"GB-Mo\",\"endRange\":\"Inf\",\"description\":\"$0.138 per GB-month of Provisioned IOPS SSD (io1) provisioned storage - Canada (Central)\",\"appliesTo\":[],\"rateCode\":\"WQGC34PB2AWS8R4U.JRTCKXETXF.6YS6EN2CT7\",\"beginRange\":\"0\",\"pricePerUnit\":{\"USD\":\"0.1380000000\"}}},\"sku\":\"WQGC34PB2AWS8R4U\",\"effectiveDate\":\"2017-08-01T00:00:00Z\",\"offerTermCode\":\"JRTCKXETXF\",\"termAttributes\":{}}}},\"version\":\"20170901182201\",\"publicationDate\":\"2017-09-01T18:22:01Z\"}"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation returns a list of products that match the given criteria.",
+ "id": "to-retrieve-available products",
+ "title": "To retrieve a list of products"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/paginators-1.json
new file mode 100644
index 0000000000..0f2ce4e8e2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "DescribeServices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Services",
+ "non_aggregate_keys": [
+ "FormatVersion"
+ ]
+ },
+ "GetAttributeValues": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AttributeValues"
+ },
+ "GetProducts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PriceList",
+ "non_aggregate_keys": [
+ "FormatVersion"
+ ]
+ },
+ "ListPriceLists": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PriceLists"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/service-2.json.gz
new file mode 100644
index 0000000000..d7564c1d12
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/pricing/2017-10-15/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..94dbdee89b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/paginators-1.json
new file mode 100644
index 0000000000..8b7d279c18
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListDeviceIdentifiers": {
+ "input_token": "startToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "deviceIdentifiers"
+ },
+ "ListNetworkResources": {
+ "input_token": "startToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "networkResources"
+ },
+ "ListNetworkSites": {
+ "input_token": "startToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "networkSites"
+ },
+ "ListNetworks": {
+ "input_token": "startToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "networks"
+ },
+ "ListOrders": {
+ "input_token": "startToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "orders"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/service-2.json.gz
new file mode 100644
index 0000000000..4a228a9ceb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/privatenetworks/2021-12-03/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..1e28b3b0ed
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/paginators-1.json
new file mode 100644
index 0000000000..a52075c41e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/paginators-1.json
@@ -0,0 +1,121 @@
+{
+ "pagination": {
+ "ListEnvironmentAccountConnections": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "environmentAccountConnections"
+ },
+ "ListEnvironmentTemplateVersions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templateVersions"
+ },
+ "ListEnvironmentTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templates"
+ },
+ "ListEnvironments": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "environments"
+ },
+ "ListServiceInstances": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "serviceInstances"
+ },
+ "ListServiceTemplateVersions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templateVersions"
+ },
+ "ListServiceTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templates"
+ },
+ "ListServices": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "services"
+ },
+ "ListTagsForResource": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "tags"
+ },
+ "ListEnvironmentOutputs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "outputs"
+ },
+ "ListEnvironmentProvisionedResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "provisionedResources"
+ },
+ "ListRepositories": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "repositories"
+ },
+ "ListRepositorySyncDefinitions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "syncDefinitions"
+ },
+ "ListServiceInstanceOutputs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "outputs"
+ },
+ "ListServiceInstanceProvisionedResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "provisionedResources"
+ },
+ "ListServicePipelineOutputs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "outputs"
+ },
+ "ListServicePipelineProvisionedResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "provisionedResources"
+ },
+ "ListComponentOutputs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "outputs"
+ },
+ "ListComponentProvisionedResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "provisionedResources"
+ },
+ "ListComponents": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "components"
+ },
+ "ListDeployments": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "deployments"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/service-2.json.gz
new file mode 100644
index 0000000000..f10dd6040b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/waiters-2.json
new file mode 100644
index 0000000000..f99a6fe345
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/proton/2020-07-20/waiters-2.json
@@ -0,0 +1,208 @@
+{
+ "version" : 2,
+ "waiters" : {
+ "ComponentDeleted" : {
+ "description" : "Wait until a Component is deleted. Use this after invoking DeleteComponent",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetComponent",
+ "acceptors" : [ {
+ "matcher" : "error",
+ "state" : "success",
+ "expected" : "ResourceNotFoundException"
+ }, {
+ "matcher" : "path",
+ "argument" : "component.deploymentStatus",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "ComponentDeployed" : {
+ "description" : "Wait until a Component is deployed. Use this after invoking CreateComponent or UpdateComponent",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetComponent",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "component.deploymentStatus",
+ "state" : "success",
+ "expected" : "SUCCEEDED"
+ }, {
+ "matcher" : "path",
+ "argument" : "component.deploymentStatus",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "EnvironmentDeployed" : {
+ "description" : "Wait until an Environment is deployed. Use this after invoking CreateEnvironment or UpdateEnvironment",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetEnvironment",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "environment.deploymentStatus",
+ "state" : "success",
+ "expected" : "SUCCEEDED"
+ }, {
+ "matcher" : "path",
+ "argument" : "environment.deploymentStatus",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "EnvironmentTemplateVersionRegistered" : {
+ "description" : "Wait until an EnvironmentTemplateVersion is registered. Use this after invoking CreateEnvironmentTemplateVersion",
+ "delay" : 2,
+ "maxAttempts" : 150,
+ "operation" : "GetEnvironmentTemplateVersion",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "environmentTemplateVersion.status",
+ "state" : "success",
+ "expected" : "DRAFT"
+ }, {
+ "matcher" : "path",
+ "argument" : "environmentTemplateVersion.status",
+ "state" : "success",
+ "expected" : "PUBLISHED"
+ }, {
+ "matcher" : "path",
+ "argument" : "environmentTemplateVersion.status",
+ "state" : "failure",
+ "expected" : "REGISTRATION_FAILED"
+ } ]
+ },
+ "ServiceCreated" : {
+ "description" : "Wait until an Service has deployed its instances and possibly pipeline. Use this after invoking CreateService",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetService",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED_CLEANUP_COMPLETE"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED_CLEANUP_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "CREATE_FAILED"
+ } ]
+ },
+ "ServiceDeleted" : {
+ "description" : "Wait until a Service, its instances, and possibly pipeline have been deleted after DeleteService is invoked",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetService",
+ "acceptors" : [ {
+ "matcher" : "error",
+ "state" : "success",
+ "expected" : "ResourceNotFoundException"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "DELETE_FAILED"
+ } ]
+ },
+ "ServiceInstanceDeployed" : {
+ "description" : "Wait until a ServiceInstance is deployed. Use this after invoking CreateService or UpdateServiceInstance",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetServiceInstance",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "serviceInstance.deploymentStatus",
+ "state" : "success",
+ "expected" : "SUCCEEDED"
+ }, {
+ "matcher" : "path",
+ "argument" : "serviceInstance.deploymentStatus",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "ServicePipelineDeployed" : {
+ "description" : "Wait until an ServicePipeline is deployed. Use this after invoking CreateService or UpdateServicePipeline",
+ "delay" : 10,
+ "maxAttempts" : 360,
+ "operation" : "GetService",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "service.pipeline.deploymentStatus",
+ "state" : "success",
+ "expected" : "SUCCEEDED"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.pipeline.deploymentStatus",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "ServiceTemplateVersionRegistered" : {
+ "description" : "Wait until a ServiceTemplateVersion is registered. Use this after invoking CreateServiceTemplateVersion",
+ "delay" : 2,
+ "maxAttempts" : 150,
+ "operation" : "GetServiceTemplateVersion",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "serviceTemplateVersion.status",
+ "state" : "success",
+ "expected" : "DRAFT"
+ }, {
+ "matcher" : "path",
+ "argument" : "serviceTemplateVersion.status",
+ "state" : "success",
+ "expected" : "PUBLISHED"
+ }, {
+ "matcher" : "path",
+ "argument" : "serviceTemplateVersion.status",
+ "state" : "failure",
+ "expected" : "REGISTRATION_FAILED"
+ } ]
+ },
+ "ServiceUpdated" : {
+ "description" : "Wait until a Service, its instances, and possibly pipeline have been deployed after UpdateService is invoked",
+ "delay" : 5,
+ "maxAttempts" : 999,
+ "operation" : "GetService",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED_CLEANUP_COMPLETE"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED_CLEANUP_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "UPDATE_FAILED"
+ }, {
+ "matcher" : "path",
+ "argument" : "service.status",
+ "state" : "failure",
+ "expected" : "UPDATE_COMPLETE_CLEANUP_FAILED"
+ } ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..73f4712447
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/service-2.json.gz
new file mode 100644
index 0000000000..d2ae0fd0fc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb-session/2019-07-11/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4f74ea7c12
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/service-2.json.gz
new file mode 100644
index 0000000000..3556ecdaae
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/qldb/2019-01-02/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4bef325755
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/paginators-1.json
new file mode 100644
index 0000000000..83b6264f29
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/paginators-1.json
@@ -0,0 +1,190 @@
+{
+ "pagination": {
+ "ListAnalyses": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AnalysisSummaryList"
+ },
+ "ListDashboardVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DashboardVersionSummaryList"
+ },
+ "ListDashboards": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DashboardSummaryList"
+ },
+ "ListDataSets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DataSetSummaries"
+ },
+ "ListDataSources": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DataSources"
+ },
+ "ListIngestions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Ingestions"
+ },
+ "ListNamespaces": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Namespaces"
+ },
+ "ListTemplateAliases": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TemplateAliasList"
+ },
+ "ListTemplateVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TemplateVersionSummaryList"
+ },
+ "ListTemplates": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TemplateSummaryList"
+ },
+ "ListThemeVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ThemeVersionSummaryList"
+ },
+ "ListThemes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ThemeSummaryList"
+ },
+ "SearchAnalyses": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AnalysisSummaryList"
+ },
+ "SearchDashboards": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DashboardSummaryList"
+ },
+ "SearchDataSets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DataSetSummaries"
+ },
+ "SearchDataSources": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DataSourceSummaries"
+ },
+ "ListAssetBundleExportJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AssetBundleExportJobSummaryList"
+ },
+ "ListAssetBundleImportJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AssetBundleImportJobSummaryList"
+ },
+ "ListGroupMemberships": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "GroupMemberList"
+ },
+ "ListGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "GroupList"
+ },
+ "ListIAMPolicyAssignments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "IAMPolicyAssignments"
+ },
+ "ListIAMPolicyAssignmentsForUser": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ActiveAssignments"
+ },
+ "ListUserGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "GroupList"
+ },
+ "ListUsers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "UserList"
+ },
+ "SearchGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "GroupList"
+ },
+ "DescribeFolderPermissions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Permissions"
+ },
+ "DescribeFolderResolvedPermissions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Permissions"
+ },
+ "ListFolderMembers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FolderMemberList"
+ },
+ "ListFolders": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FolderSummaryList"
+ },
+ "SearchFolders": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FolderSummaryList"
+ },
+ "ListRoleMemberships": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MembersList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..a97c2f8f18
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/paginators-1.sdk-extras.json
@@ -0,0 +1,197 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "ListAnalyses": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListDashboardVersions": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListTemplateAliases": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListTemplateVersions": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListTemplates": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListThemeVersions": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListThemes": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "SearchAnalyses": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "SearchDashboards": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "SearchDataSets": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "SearchDataSources": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListNamespaces": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListIngestions": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListDataSources": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListDataSets": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListDashboards": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListAssetBundleExportJobs": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListAssetBundleImportJobs": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListGroupMemberships": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListGroups": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListIAMPolicyAssignments": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListIAMPolicyAssignmentsForUser": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListUserGroups": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListUsers": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "SearchGroups": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListFolders": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "ListFolderMembers": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "SearchFolders": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ },
+ "DescribeFolderPermissions": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId",
+ "Arn",
+ "FolderId"
+ ]
+ },
+ "DescribeFolderResolvedPermissions": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId",
+ "Arn",
+ "FolderId"
+ ]
+ },
+ "ListRoleMemberships": {
+ "non_aggregate_keys": [
+ "Status",
+ "RequestId"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/service-2.json.gz
new file mode 100644
index 0000000000..4e408fcff6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/quicksight/2018-04-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..357f264a57
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/paginators-1.json
new file mode 100644
index 0000000000..ec438a09a5
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "GetResourcePolicies": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "policies"
+ },
+ "GetResourceShareAssociations": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "resourceShareAssociations"
+ },
+ "GetResourceShareInvitations": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "resourceShareInvitations"
+ },
+ "GetResourceShares": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "resourceShares"
+ },
+ "ListPrincipals": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "principals"
+ },
+ "ListResources": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "resources"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/service-2.json.gz
new file mode 100644
index 0000000000..41ee4ef7f6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ram/2018-01-04/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..14e5c5e35d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/paginators-1.json
new file mode 100644
index 0000000000..bdbfafb483
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListRules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Rules"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/service-2.json.gz
new file mode 100644
index 0000000000..112c09b2fb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rbin/2021-06-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..89b86f3234
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/service-2.json.gz
new file mode 100644
index 0000000000..3a9be6c05d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds-data/2018-08-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e4f8fa61c5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/paginators-1.json
new file mode 100644
index 0000000000..76c4f3a119
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/paginators-1.json
@@ -0,0 +1,107 @@
+{
+ "pagination": {
+ "DescribeDBEngineVersions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBEngineVersions"
+ },
+ "DescribeDBInstances": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBInstances"
+ },
+ "DescribeDBLogFiles": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DescribeDBLogFiles"
+ },
+ "DescribeDBParameterGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBParameterGroups"
+ },
+ "DescribeDBParameters": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Parameters"
+ },
+ "DescribeDBSecurityGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBSecurityGroups"
+ },
+ "DescribeDBSnapshots": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBSnapshots"
+ },
+ "DescribeDBSubnetGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBSubnetGroups"
+ },
+ "DescribeEngineDefaultParameters": {
+ "input_token": "Marker",
+ "output_token": "EngineDefaults.Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "EngineDefaults.Parameters"
+ },
+ "DescribeEventSubscriptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "EventSubscriptionsList"
+ },
+ "DescribeEvents": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Events"
+ },
+ "DescribeOptionGroupOptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OptionGroupOptions"
+ },
+ "DescribeOptionGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OptionGroupsList"
+ },
+ "DescribeOrderableDBInstanceOptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OrderableDBInstanceOptions"
+ },
+ "DescribeReservedDBInstances": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ReservedDBInstances"
+ },
+ "DescribeReservedDBInstancesOfferings": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ReservedDBInstancesOfferings"
+ },
+ "DownloadDBLogFilePortion": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "NumberOfLines",
+ "more_results": "AdditionalDataPending",
+ "result_key": "LogFileData"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/service-2.json.gz
new file mode 100644
index 0000000000..515ceb1cda
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/waiters-2.json
new file mode 100644
index 0000000000..b01500797d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-09-01/waiters-2.json
@@ -0,0 +1,97 @@
+{
+ "version": 2,
+ "waiters": {
+ "DBInstanceAvailable": {
+ "delay": 30,
+ "operation": "DescribeDBInstances",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ }
+ ]
+ },
+ "DBInstanceDeleted": {
+ "delay": 30,
+ "operation": "DescribeDBInstances",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "deleted",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "resetting-master-credentials",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e25b9ffdb9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/examples-1.json
new file mode 100644
index 0000000000..e72a328e81
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/examples-1.json
@@ -0,0 +1,1951 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AddSourceIdentifierToSubscription": [
+ {
+ "input": {
+ "SourceIdentifier": "mymysqlinstance",
+ "SubscriptionName": "mymysqleventsubscription"
+ },
+ "output": {
+ "EventSubscription": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example add a source identifier to an event notification subscription.",
+ "id": "add-source-identifier-to-subscription-93fb6a15-0a59-4577-a7b5-e12db9752c14",
+ "title": "To add a source identifier to an event notification subscription"
+ }
+ ],
+ "AddTagsToResource": [
+ {
+ "input": {
+ "ResourceName": "arn:aws:rds:us-east-1:992648334831:og:mymysqloptiongroup",
+ "Tags": [
+ {
+ "Key": "Staging",
+ "Value": "LocationDB"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example adds a tag to an option group.",
+ "id": "add-tags-to-resource-fa99ef50-228b-449d-b893-ca4d4e9768ab",
+ "title": "To add tags to a resource"
+ }
+ ],
+ "ApplyPendingMaintenanceAction": [
+ {
+ "input": {
+ "ApplyAction": "system-update",
+ "OptInType": "immediate",
+ "ResourceIdentifier": "arn:aws:rds:us-east-1:992648334831:db:mymysqlinstance"
+ },
+ "output": {
+ "ResourcePendingMaintenanceActions": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example immediately applies a pending system update to a DB instance.",
+ "id": "apply-pending-maintenance-action-2a026047-8bbb-47fc-b695-abad9f308c24",
+ "title": "To apply a pending maintenance action"
+ }
+ ],
+ "AuthorizeDBSecurityGroupIngress": [
+ {
+ "input": {
+ "CIDRIP": "203.0.113.5/32",
+ "DBSecurityGroupName": "mydbsecuritygroup"
+ },
+ "output": {
+ "DBSecurityGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example authorizes access to the specified security group by the specified CIDR block.",
+ "id": "authorize-db-security-group-ingress-ebf9ab91-8912-4b07-a32e-ca150668164f",
+ "title": "To authorize DB security group integress"
+ }
+ ],
+ "CopyDBClusterParameterGroup": [
+ {
+ "input": {
+ "SourceDBClusterParameterGroupIdentifier": "mydbclusterparametergroup",
+ "TargetDBClusterParameterGroupDescription": "My DB cluster parameter group copy",
+ "TargetDBClusterParameterGroupIdentifier": "mydbclusterparametergroup-copy"
+ },
+ "output": {
+ "DBClusterParameterGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example copies a DB cluster parameter group.",
+ "id": "copy-db-cluster-parameter-group-6fefaffe-cde9-4dba-9f0b-d3f593572fe4",
+ "title": "To copy a DB cluster parameter group"
+ }
+ ],
+ "CopyDBClusterSnapshot": [
+ {
+ "input": {
+ "SourceDBClusterSnapshotIdentifier": "rds:sample-cluster-2016-09-14-10-38",
+ "TargetDBClusterSnapshotIdentifier": "cluster-snapshot-copy-1"
+ },
+ "output": {
+ "DBClusterSnapshot": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example copies an automated snapshot of a DB cluster to a new DB cluster snapshot.",
+ "id": "to-copy-a-db-cluster-snapshot-1473879770564",
+ "title": "To copy a DB cluster snapshot"
+ }
+ ],
+ "CopyDBParameterGroup": [
+ {
+ "input": {
+ "SourceDBParameterGroupIdentifier": "mymysqlparametergroup",
+ "TargetDBParameterGroupDescription": "My MySQL parameter group copy",
+ "TargetDBParameterGroupIdentifier": "mymysqlparametergroup-copy"
+ },
+ "output": {
+ "DBParameterGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example copies a DB parameter group.",
+ "id": "copy-db-parameter-group-610d4dba-2c87-467f-ae5d-edd7f8e47349",
+ "title": "To copy a DB parameter group"
+ }
+ ],
+ "CopyDBSnapshot": [
+ {
+ "input": {
+ "SourceDBSnapshotIdentifier": "mydbsnapshot",
+ "TargetDBSnapshotIdentifier": "mydbsnapshot-copy"
+ },
+ "output": {
+ "DBSnapshot": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example copies a DB snapshot.",
+ "id": "copy-db-snapshot-1b2f0210-bc67-415d-9822-6eecf447dc86",
+ "title": "To copy a DB snapshot"
+ }
+ ],
+ "CopyOptionGroup": [
+ {
+ "input": {
+ "SourceOptionGroupIdentifier": "mymysqloptiongroup",
+ "TargetOptionGroupDescription": "My MySQL option group copy",
+ "TargetOptionGroupIdentifier": "mymysqloptiongroup-copy"
+ },
+ "output": {
+ "OptionGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example copies an option group.",
+ "id": "copy-option-group-8d5c01c3-8846-4e9c-a4b0-1b7237f7d0ec",
+ "title": "To copy an option group"
+ }
+ ],
+ "CreateDBCluster": [
+ {
+ "input": {
+ "AvailabilityZones": [
+ "us-east-1a"
+ ],
+ "BackupRetentionPeriod": 1,
+ "DBClusterIdentifier": "mydbcluster",
+ "DBClusterParameterGroupName": "mydbclusterparametergroup",
+ "DatabaseName": "myauroradb",
+ "Engine": "aurora",
+ "EngineVersion": "5.6.10a",
+ "MasterUserPassword": "mypassword",
+ "MasterUsername": "myuser",
+ "Port": 3306,
+ "StorageEncrypted": true
+ },
+ "output": {
+ "DBCluster": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB cluster.",
+ "id": "create-db-cluster-423b998d-eba9-40dd-8e19-96c5b6e5f31d",
+ "title": "To create a DB cluster"
+ }
+ ],
+ "CreateDBClusterParameterGroup": [
+ {
+ "input": {
+ "DBClusterParameterGroupName": "mydbclusterparametergroup",
+ "DBParameterGroupFamily": "aurora5.6",
+ "Description": "My DB cluster parameter group"
+ },
+ "output": {
+ "DBClusterParameterGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB cluster parameter group.",
+ "id": "create-db-cluster-parameter-group-8eb1c3ae-1965-4262-afe3-ee134c4430b1",
+ "title": "To create a DB cluster parameter group"
+ }
+ ],
+ "CreateDBClusterSnapshot": [
+ {
+ "input": {
+ "DBClusterIdentifier": "mydbcluster",
+ "DBClusterSnapshotIdentifier": "mydbclustersnapshot"
+ },
+ "output": {
+ "DBClusterSnapshot": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB cluster snapshot.",
+ "id": "create-db-cluster-snapshot-",
+ "title": "To create a DB cluster snapshot"
+ }
+ ],
+ "CreateDBInstance": [
+ {
+ "input": {
+ "AllocatedStorage": 5,
+ "DBInstanceClass": "db.t2.micro",
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "Engine": "MySQL",
+ "MasterUserPassword": "MyPassword",
+ "MasterUsername": "MyUser"
+ },
+ "output": {
+ "DBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB instance.",
+ "id": "create-db-instance-57eb5d16-8bf8-4c84-9709-1700322b37b9",
+ "title": "To create a DB instance."
+ }
+ ],
+ "CreateDBInstanceReadReplica": [
+ {
+ "input": {
+ "AvailabilityZone": "us-east-1a",
+ "CopyTagsToSnapshot": true,
+ "DBInstanceClass": "db.t2.micro",
+ "DBInstanceIdentifier": "mydbreadreplica",
+ "PubliclyAccessible": true,
+ "SourceDBInstanceIdentifier": "mymysqlinstance",
+ "StorageType": "gp2",
+ "Tags": [
+ {
+ "Key": "mydbreadreplicakey",
+ "Value": "mydbreadreplicavalue"
+ }
+ ]
+ },
+ "output": {
+ "DBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB instance read replica.",
+ "id": "create-db-instance-read-replica-81b41cd5-2871-4dae-bc59-3e264449d5fe",
+ "title": "To create a DB instance read replica."
+ }
+ ],
+ "CreateDBParameterGroup": [
+ {
+ "input": {
+ "DBParameterGroupFamily": "mysql5.6",
+ "DBParameterGroupName": "mymysqlparametergroup",
+ "Description": "My MySQL parameter group"
+ },
+ "output": {
+ "DBParameterGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB parameter group.",
+ "id": "create-db-parameter-group-42afcc37-12e9-4b6a-a55c-b8a141246e87",
+ "title": "To create a DB parameter group."
+ }
+ ],
+ "CreateDBSecurityGroup": [
+ {
+ "input": {
+ "DBSecurityGroupDescription": "My DB security group",
+ "DBSecurityGroupName": "mydbsecuritygroup"
+ },
+ "output": {
+ "DBSecurityGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB security group.",
+ "id": "create-db-security-group-41b6786a-539e-42a5-a645-a8bc3cf99353",
+ "title": "To create a DB security group."
+ }
+ ],
+ "CreateDBSnapshot": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "DBSnapshotIdentifier": "mydbsnapshot"
+ },
+ "output": {
+ "DBSnapshot": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB snapshot.",
+ "id": "create-db-snapshot-e10e0e2c-9ac4-426d-9b17-6b6a3e382ce2",
+ "title": "To create a DB snapshot."
+ }
+ ],
+ "CreateDBSubnetGroup": [
+ {
+ "input": {
+ "DBSubnetGroupDescription": "My DB subnet group",
+ "DBSubnetGroupName": "mydbsubnetgroup",
+ "SubnetIds": [
+ "subnet-1fab8a69",
+ "subnet-d43a468c"
+ ]
+ },
+ "output": {
+ "DBSubnetGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a DB subnet group.",
+ "id": "create-db-subnet-group-c3d162c2-0ec4-4955-ba89-18967615fdb8",
+ "title": "To create a DB subnet group."
+ }
+ ],
+ "CreateEventSubscription": [
+ {
+ "input": {
+ "Enabled": true,
+ "EventCategories": [
+ "availability"
+ ],
+ "SnsTopicArn": "arn:aws:sns:us-east-1:992648334831:MyDemoSNSTopic",
+ "SourceIds": [
+ "mymysqlinstance"
+ ],
+ "SourceType": "db-instance",
+ "SubscriptionName": "mymysqleventsubscription"
+ },
+ "output": {
+ "EventSubscription": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates an event notification subscription.",
+ "id": "create-event-subscription-00dd0ee6-0e0f-4a38-ae83-e5f2ded5f69a",
+ "title": "To create an event notification subscription"
+ }
+ ],
+ "CreateOptionGroup": [
+ {
+ "input": {
+ "EngineName": "MySQL",
+ "MajorEngineVersion": "5.6",
+ "OptionGroupDescription": "My MySQL 5.6 option group",
+ "OptionGroupName": "mymysqloptiongroup"
+ },
+ "output": {
+ "OptionGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates an option group.",
+ "id": "create-option-group-a7708c87-1b79-4a5e-a762-21cf8fc62b78",
+ "title": "To create an option group"
+ }
+ ],
+ "DeleteDBCluster": [
+ {
+ "input": {
+ "DBClusterIdentifier": "mydbcluster",
+ "SkipFinalSnapshot": true
+ },
+ "output": {
+ "DBCluster": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB cluster.",
+ "id": "delete-db-cluster-927fc2c8-6c67-4075-b1ba-75490be0f7d6",
+ "title": "To delete a DB cluster."
+ }
+ ],
+ "DeleteDBClusterParameterGroup": [
+ {
+ "input": {
+ "DBClusterParameterGroupName": "mydbclusterparametergroup"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB cluster parameter group.",
+ "id": "delete-db-cluster-parameter-group-364f5555-ba0a-4cc8-979c-e769098924fc",
+ "title": "To delete a DB cluster parameter group."
+ }
+ ],
+ "DeleteDBClusterSnapshot": [
+ {
+ "input": {
+ "DBClusterSnapshotIdentifier": "mydbclustersnapshot"
+ },
+ "output": {
+ "DBClusterSnapshot": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB cluster snapshot.",
+ "id": "delete-db-cluster-snapshot-c67e0d95-670e-4fb5-af90-6d9a70a91b07",
+ "title": "To delete a DB cluster snapshot."
+ }
+ ],
+ "DeleteDBInstance": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "SkipFinalSnapshot": true
+ },
+ "output": {
+ "DBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB instance.",
+ "id": "delete-db-instance-4412e650-949c-488a-b32a-7d3038ebccc4",
+ "title": "To delete a DB instance."
+ }
+ ],
+ "DeleteDBParameterGroup": [
+ {
+ "input": {
+ "DBParameterGroupName": "mydbparamgroup3"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a DB parameter group.",
+ "id": "to-delete-a-db-parameter-group-1473888796509",
+ "title": "To delete a DB parameter group"
+ }
+ ],
+ "DeleteDBSecurityGroup": [
+ {
+ "input": {
+ "DBSecurityGroupName": "mysecgroup"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a DB security group.",
+ "id": "to-delete-a-db-security-group-1473960141889",
+ "title": "To delete a DB security group"
+ }
+ ],
+ "DeleteDBSnapshot": [
+ {
+ "input": {
+ "DBSnapshotIdentifier": "mydbsnapshot"
+ },
+ "output": {
+ "DBSnapshot": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB snapshot.",
+ "id": "delete-db-snapshot-505d6b4e-8ced-479c-856a-c460a33fe07b",
+ "title": "To delete a DB cluster snapshot."
+ }
+ ],
+ "DeleteDBSubnetGroup": [
+ {
+ "input": {
+ "DBSubnetGroupName": "mydbsubnetgroup"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB subnetgroup.",
+ "id": "delete-db-subnet-group-4ae00375-511e-443d-a01d-4b9f552244aa",
+ "title": "To delete a DB subnet group."
+ }
+ ],
+ "DeleteEventSubscription": [
+ {
+ "input": {
+ "SubscriptionName": "myeventsubscription"
+ },
+ "output": {
+ "EventSubscription": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified DB event subscription.",
+ "id": "delete-db-event-subscription-d33567e3-1d5d-48ff-873f-0270453f4a75",
+ "title": "To delete a DB event subscription."
+ }
+ ],
+ "DeleteOptionGroup": [
+ {
+ "input": {
+ "OptionGroupName": "mydboptiongroup"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified option group.",
+ "id": "delete-db-option-group-578be2be-3095-431a-9ea4-9a3c3b0daef4",
+ "title": "To delete an option group."
+ }
+ ],
+ "DescribeAccountAttributes": [
+ {
+ "input": {
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists account attributes.",
+ "id": "describe-account-attributes-683d3ff7-5524-421a-8da5-e88f1ea2222b",
+ "title": "To list account attributes"
+ }
+ ],
+ "DescribeCertificates": [
+ {
+ "input": {
+ "CertificateIdentifier": "rds-ca-2015",
+ "MaxRecords": 20
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists up to 20 certificates for the specified certificate identifier.",
+ "id": "describe-certificates-9d71a70d-7908-4444-b43f-321d842c62dc",
+ "title": "To list certificates"
+ }
+ ],
+ "DescribeDBClusterParameterGroups": [
+ {
+ "input": {
+ "DBClusterParameterGroupName": "mydbclusterparametergroup"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists settings for the specified DB cluster parameter group.",
+ "id": "describe-db-cluster-parameter-groups-cf9c6e66-664e-4f57-8e29-a9080abfc013",
+ "title": "To list DB cluster parameter group settings"
+ }
+ ],
+ "DescribeDBClusterParameters": [
+ {
+ "input": {
+ "DBClusterParameterGroupName": "mydbclusterparametergroup",
+ "Source": "system"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists system parameters for the specified DB cluster parameter group.",
+ "id": "describe-db-cluster-parameters-98043c28-e489-41a7-b118-bfd96dc779a1",
+ "title": "To list DB cluster parameters"
+ }
+ ],
+ "DescribeDBClusterSnapshotAttributes": [
+ {
+ "input": {
+ "DBClusterSnapshotIdentifier": "mydbclustersnapshot"
+ },
+ "output": {
+ "DBClusterSnapshotAttributesResult": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists attributes for the specified DB cluster snapshot.",
+ "id": "describe-db-cluster-snapshot-attributes-6752ade3-0c7b-4b06-a8e4-b76bf4e2d3571",
+ "title": "To list DB cluster snapshot attributes"
+ }
+ ],
+ "DescribeDBClusterSnapshots": [
+ {
+ "input": {
+ "DBClusterSnapshotIdentifier": "mydbclustersnapshot",
+ "SnapshotType": "manual"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists settings for the specified, manually-created cluster snapshot.",
+ "id": "describe-db-cluster-snapshots-52f38af1-3431-4a51-9a6a-e6bb8c961b32",
+ "title": "To list DB cluster snapshots"
+ }
+ ],
+ "DescribeDBClusters": [
+ {
+ "input": {
+ "DBClusterIdentifier": "mynewdbcluster"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists settings for the specified DB cluster.",
+ "id": "describe-db-clusters-7aae8861-cb95-4b3b-9042-f62df7698635",
+ "title": "To list DB clusters"
+ }
+ ],
+ "DescribeDBEngineVersions": [
+ {
+ "input": {
+ "DBParameterGroupFamily": "mysql5.6",
+ "DefaultOnly": true,
+ "Engine": "mysql",
+ "EngineVersion": "5.6",
+ "ListSupportedCharacterSets": true
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists settings for the specified DB engine version.",
+ "id": "describe-db-engine-versions-8e698cf2-2162-425a-a854-111cdaceb52b",
+ "title": "To list DB engine version settings"
+ }
+ ],
+ "DescribeDBInstances": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists settings for the specified DB instance.",
+ "id": "describe-db-instances-0e11a8c5-4ec3-4463-8cbf-f7254d04c4fc",
+ "title": "To list DB instance settings"
+ }
+ ],
+ "DescribeDBLogFiles": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "FileLastWritten": 1470873600000,
+ "FileSize": 0,
+ "FilenameContains": "error"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists matching log file names for the specified DB instance, file name pattern, last write date in POSIX time with milleseconds, and minimum file size.",
+ "id": "describe-db-log-files-5f002d8d-5c1d-44c2-b5f4-bd284c0f1285",
+ "title": "To list DB log file names"
+ }
+ ],
+ "DescribeDBParameterGroups": [
+ {
+ "input": {
+ "DBParameterGroupName": "mymysqlparametergroup"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information about the specified DB parameter group.",
+ "id": "describe-db-parameter-groups-",
+ "title": "To list information about DB parameter groups"
+ }
+ ],
+ "DescribeDBParameters": [
+ {
+ "input": {
+ "DBParameterGroupName": "mymysqlparametergroup",
+ "MaxRecords": 20,
+ "Source": "system"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for up to the first 20 system parameters for the specified DB parameter group.",
+ "id": "describe-db-parameters-09db4201-ef4f-4d97-a4b5-d71c0715b901",
+ "title": "To list information about DB parameters"
+ }
+ ],
+ "DescribeDBSecurityGroups": [
+ {
+ "input": {
+ "DBSecurityGroupName": "mydbsecuritygroup"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists settings for the specified security group.",
+ "id": "describe-db-security-groups-66fe9ea1-17dd-4275-b82e-f771cee0c849",
+ "title": "To list DB security group settings"
+ }
+ ],
+ "DescribeDBSnapshotAttributes": [
+ {
+ "input": {
+ "DBSnapshotIdentifier": "mydbsnapshot"
+ },
+ "output": {
+ "DBSnapshotAttributesResult": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists attributes for the specified DB snapshot.",
+ "id": "describe-db-snapshot-attributes-1d4fb750-34f6-4e43-8b3d-b2751d796a95",
+ "title": "To list DB snapshot attributes"
+ }
+ ],
+ "DescribeDBSnapshots": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "IncludePublic": false,
+ "IncludeShared": true,
+ "SnapshotType": "manual"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists all manually-created, shared snapshots for the specified DB instance.",
+ "id": "describe-db-snapshots-2c935989-a1ef-4c85-aea4-1d0f45f17f26",
+ "title": "To list DB snapshot attributes"
+ }
+ ],
+ "DescribeDBSubnetGroups": [
+ {
+ "input": {
+ "DBSubnetGroupName": "mydbsubnetgroup"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information about the specified DB subnet group.",
+ "id": "describe-db-subnet-groups-1d97b340-682f-4dd6-9653-8ed72a8d1221",
+ "title": "To list information about DB subnet groups"
+ }
+ ],
+ "DescribeEngineDefaultClusterParameters": [
+ {
+ "input": {
+ "DBParameterGroupFamily": "aurora5.6"
+ },
+ "output": {
+ "EngineDefaults": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists default parameters for the specified DB cluster engine.",
+ "id": "describe-engine-default-cluster-parameters-f130374a-7bee-434b-b51d-da20b6e000e0",
+ "title": "To list default parameters for a DB cluster engine"
+ }
+ ],
+ "DescribeEngineDefaultParameters": [
+ {
+ "input": {
+ "DBParameterGroupFamily": "mysql5.6"
+ },
+ "output": {
+ "EngineDefaults": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists default parameters for the specified DB engine.",
+ "id": "describe-engine-default-parameters-35d5108e-1d44-4fac-8aeb-04b8fdfface1",
+ "title": "To list default parameters for a DB engine"
+ }
+ ],
+ "DescribeEventCategories": [
+ {
+ "input": {
+ "SourceType": "db-instance"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists all DB instance event categories.",
+ "id": "describe-event-categories-97bd4c77-12da-4be6-b42f-edf77771428b",
+ "title": "To list event categories."
+ }
+ ],
+ "DescribeEventSubscriptions": [
+ {
+ "input": {
+ "SubscriptionName": "mymysqleventsubscription"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for the specified DB event notification subscription.",
+ "id": "describe-event-subscriptions-11184a82-e58a-4d0c-b558-f3a7489e0850",
+ "title": "To list information about DB event notification subscriptions"
+ }
+ ],
+ "DescribeEvents": [
+ {
+ "input": {
+ "Duration": 10080,
+ "EventCategories": [
+ "backup"
+ ],
+ "SourceIdentifier": "mymysqlinstance",
+ "SourceType": "db-instance"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all backup-related events for the specified DB instance for the past 7 days (7 days * 24 hours * 60 minutes = 10,080 minutes).",
+ "id": "describe-events-3836e5ed-3913-4f76-8452-c77fcad5016b",
+ "title": "To list information about events"
+ }
+ ],
+ "DescribeOptionGroupOptions": [
+ {
+ "input": {
+ "EngineName": "mysql",
+ "MajorEngineVersion": "5.6"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all option group options for the specified DB engine.",
+ "id": "describe-option-group-options-30d735a4-81f1-49e4-b3f2-5dc45d50c8ed",
+ "title": "To list information about DB option group options"
+ }
+ ],
+ "DescribeOptionGroups": [
+ {
+ "input": {
+ "EngineName": "mysql",
+ "MajorEngineVersion": "5.6"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all option groups for the specified DB engine.",
+ "id": "describe-option-groups-4ef478a1-66d5-45f2-bec3-e608720418a4",
+ "title": "To list information about DB option groups"
+ }
+ ],
+ "DescribeOrderableDBInstanceOptions": [
+ {
+ "input": {
+ "DBInstanceClass": "db.t2.micro",
+ "Engine": "mysql",
+ "EngineVersion": "5.6.27",
+ "LicenseModel": "general-public-license",
+ "Vpc": true
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all orderable DB instance options for the specified DB engine, engine version, DB instance class, license model, and VPC settings.",
+ "id": "describe-orderable-db-instance-options-7444d3ed-82eb-42b9-9ed9-896b8c27a782",
+ "title": "To list information about orderable DB instance options"
+ }
+ ],
+ "DescribePendingMaintenanceActions": [
+ {
+ "input": {
+ "ResourceIdentifier": "arn:aws:rds:us-east-1:992648334831:db:mymysqlinstance"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all pending maintenance actions for the specified DB instance.",
+ "id": "describe-pending-maintenance-actions-e6021f7e-58ae-49cc-b874-11996176835c",
+ "title": "To list information about pending maintenance actions"
+ }
+ ],
+ "DescribeReservedDBInstances": [
+ {
+ "input": {
+ "DBInstanceClass": "db.t2.micro",
+ "Duration": "1y",
+ "MultiAZ": false,
+ "OfferingType": "No Upfront",
+ "ProductDescription": "mysql"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all reserved DB instances for the specified DB instance class, duration, product, offering type, and availability zone settings.",
+ "id": "describe-reserved-db-instances-d45adaca-2e30-407c-a0f3-aa7b98bea17f",
+ "title": "To list information about reserved DB instances"
+ }
+ ],
+ "DescribeReservedDBInstancesOfferings": [
+ {
+ "input": {
+ "DBInstanceClass": "db.t2.micro",
+ "Duration": "1y",
+ "MultiAZ": false,
+ "OfferingType": "No Upfront",
+ "ProductDescription": "mysql"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for all reserved DB instance offerings for the specified DB instance class, duration, product, offering type, and availability zone settings.",
+ "id": "describe-reserved-db-instances-offerings-9de7d1fd-d6a6-4a72-84ae-b2ef58d47d8d",
+ "title": "To list information about reserved DB instance offerings"
+ }
+ ],
+ "DescribeSourceRegions": [
+ {
+ "input": {
+ },
+ "output": {
+ "SourceRegions": [
+ {
+ "Endpoint": "https://rds.ap-northeast-1.amazonaws.com",
+ "RegionName": "ap-northeast-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.ap-northeast-2.amazonaws.com",
+ "RegionName": "ap-northeast-2",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.ap-south-1.amazonaws.com",
+ "RegionName": "ap-south-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.ap-southeast-1.amazonaws.com",
+ "RegionName": "ap-southeast-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.ap-southeast-2.amazonaws.com",
+ "RegionName": "ap-southeast-2",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.eu-central-1.amazonaws.com",
+ "RegionName": "eu-central-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.eu-west-1.amazonaws.com",
+ "RegionName": "eu-west-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.sa-east-1.amazonaws.com",
+ "RegionName": "sa-east-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.us-west-1.amazonaws.com",
+ "RegionName": "us-west-1",
+ "Status": "available"
+ },
+ {
+ "Endpoint": "https://rds.us-west-2.amazonaws.com",
+ "RegionName": "us-west-2",
+ "Status": "available"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "To list the AWS regions where a Read Replica can be created.",
+ "id": "to-describe-source-regions-1473457722410",
+ "title": "To describe source regions"
+ }
+ ],
+ "DownloadDBLogFilePortion": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "LogFileName": "mysqlUpgrade"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information for the specified log file for the specified DB instance.",
+ "id": "download-db-log-file-portion-54a82731-a441-4fc7-a010-8eccae6fa202",
+ "title": "To list information about DB log files"
+ }
+ ],
+ "FailoverDBCluster": [
+ {
+ "input": {
+ "DBClusterIdentifier": "myaurorainstance-cluster",
+ "TargetDBInstanceIdentifier": "myaurorareplica"
+ },
+ "output": {
+ "DBCluster": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example performs a failover for the specified DB cluster to the specified DB instance.",
+ "id": "failover-db-cluster-9e7f2f93-d98c-42c7-bb0e-d6c485c096d6",
+ "title": "To perform a failover for a DB cluster"
+ }
+ ],
+ "ListTagsForResource": [
+ {
+ "input": {
+ "ResourceName": "arn:aws:rds:us-east-1:992648334831:og:mymysqloptiongroup"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists information about all tags associated with the specified DB option group.",
+ "id": "list-tags-for-resource-8401f3c2-77cd-4f90-bfd5-b523f0adcc2f",
+ "title": "To list information about tags associated with a resource"
+ }
+ ],
+ "ModifyDBCluster": [
+ {
+ "input": {
+ "ApplyImmediately": true,
+ "DBClusterIdentifier": "mydbcluster",
+ "MasterUserPassword": "mynewpassword",
+ "NewDBClusterIdentifier": "mynewdbcluster",
+ "PreferredBackupWindow": "04:00-04:30",
+ "PreferredMaintenanceWindow": "Tue:05:00-Tue:05:30"
+ },
+ "output": {
+ "DBCluster": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example changes the specified settings for the specified DB cluster.",
+ "id": "modify-db-cluster-a370ee1b-768d-450a-853b-707cb1ab663d",
+ "title": "To change DB cluster settings"
+ }
+ ],
+ "ModifyDBClusterParameterGroup": [
+ {
+ "input": {
+ "DBClusterParameterGroupName": "mydbclusterparametergroup",
+ "Parameters": [
+ {
+ "ApplyMethod": "immediate",
+ "ParameterName": "time_zone",
+ "ParameterValue": "America/Phoenix"
+ }
+ ]
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example immediately changes the specified setting for the specified DB cluster parameter group.",
+ "id": "modify-db-cluster-parameter-group-f9156bc9-082a-442e-8d12-239542c1a113",
+ "title": "To change DB cluster parameter group settings"
+ }
+ ],
+ "ModifyDBClusterSnapshotAttribute": [
+ {
+ "input": {
+ "AttributeName": "restore",
+ "DBClusterSnapshotIdentifier": "manual-cluster-snapshot1",
+ "ValuesToAdd": [
+ "123451234512",
+ "123456789012"
+ ],
+ "ValuesToRemove": [
+ "all"
+ ]
+ },
+ "output": {
+ "DBClusterSnapshotAttributesResult": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example gives two AWS accounts access to a manual DB cluster snapshot and ensures that the DB cluster snapshot is private by removing the value \"all\".",
+ "id": "to-add-or-remove-access-to-a-manual-db-cluster-snapshot-1473889426431",
+ "title": "To add or remove access to a manual DB cluster snapshot"
+ }
+ ],
+ "ModifyDBInstance": [
+ {
+ "input": {
+ "AllocatedStorage": 10,
+ "ApplyImmediately": true,
+ "BackupRetentionPeriod": 1,
+ "DBInstanceClass": "db.t2.small",
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "MasterUserPassword": "mynewpassword",
+ "PreferredBackupWindow": "04:00-04:30",
+ "PreferredMaintenanceWindow": "Tue:05:00-Tue:05:30"
+ },
+ "output": {
+ "DBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example immediately changes the specified settings for the specified DB instance.",
+ "id": "modify-db-instance-6979a368-6254-467b-8a8d-61103f4fcde9",
+ "title": "To change DB instance settings"
+ }
+ ],
+ "ModifyDBParameterGroup": [
+ {
+ "input": {
+ "DBParameterGroupName": "mymysqlparametergroup",
+ "Parameters": [
+ {
+ "ApplyMethod": "immediate",
+ "ParameterName": "time_zone",
+ "ParameterValue": "America/Phoenix"
+ }
+ ]
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example immediately changes the specified setting for the specified DB parameter group.",
+ "id": "modify-db-parameter-group-f3a4e52a-68e4-4b88-b559-f912d34c457a",
+ "title": "To change DB parameter group settings"
+ }
+ ],
+ "ModifyDBSnapshotAttribute": [
+ {
+ "input": {
+ "AttributeName": "restore",
+ "DBSnapshotIdentifier": "mydbsnapshot",
+ "ValuesToAdd": [
+ "all"
+ ]
+ },
+ "output": {
+ "DBSnapshotAttributesResult": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example adds the specified attribute for the specified DB snapshot.",
+ "id": "modify-db-snapshot-attribute-2e66f120-2b21-4a7c-890b-4474da88bde6",
+ "title": "To change DB snapshot attributes"
+ }
+ ],
+ "ModifyDBSubnetGroup": [
+ {
+ "input": {
+ "DBSubnetGroupName": "mydbsubnetgroup",
+ "SubnetIds": [
+ "subnet-70e1975a",
+ "subnet-747a5c49"
+ ]
+ },
+ "output": {
+ "DBSubnetGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example changes the specified setting for the specified DB subnet group.",
+ "id": "modify-db-subnet-group-e34a97d9-8fe6-4239-a4ed-ad6e73a956b0",
+ "title": "To change DB subnet group settings"
+ }
+ ],
+ "ModifyEventSubscription": [
+ {
+ "input": {
+ "Enabled": true,
+ "EventCategories": [
+ "deletion",
+ "low storage"
+ ],
+ "SourceType": "db-instance",
+ "SubscriptionName": "mymysqleventsubscription"
+ },
+ "output": {
+ "EventSubscription": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example changes the specified setting for the specified event notification subscription.",
+ "id": "modify-event-subscription-405ac869-1f02-42cd-b8f4-6950a435f30e",
+ "title": "To change event notification subscription settings"
+ }
+ ],
+ "ModifyOptionGroup": [
+ {
+ "input": {
+ "ApplyImmediately": true,
+ "OptionGroupName": "myawsuser-og02",
+ "OptionsToInclude": [
+ {
+ "DBSecurityGroupMemberships": [
+ "default"
+ ],
+ "OptionName": "MEMCACHED"
+ }
+ ]
+ },
+ "output": {
+ "OptionGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds an option to an option group.",
+ "id": "to-modify-an-option-group-1473890247875",
+ "title": "To modify an option group"
+ }
+ ],
+ "PromoteReadReplica": [
+ {
+ "input": {
+ "BackupRetentionPeriod": 1,
+ "DBInstanceIdentifier": "mydbreadreplica",
+ "PreferredBackupWindow": "03:30-04:00"
+ },
+ "output": {
+ "DBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example promotes the specified read replica and sets its backup retention period and preferred backup window.",
+ "id": "promote-read-replica-cc580039-c55d-4035-838a-def4a1ae4181",
+ "title": "To promote a read replica"
+ }
+ ],
+ "PurchaseReservedDBInstancesOffering": [
+ {
+ "input": {
+ "ReservedDBInstanceId": "myreservationid",
+ "ReservedDBInstancesOfferingId": "fb29428a-646d-4390-850e-5fe89926e727"
+ },
+ "output": {
+ "ReservedDBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example purchases a reserved DB instance offering that matches the specified settings.",
+ "id": "purchase-reserved-db-instances-offfering-f423c736-8413-429b-ba13-850fd4fa4dcd",
+ "title": "To purchase a reserved DB instance offering"
+ }
+ ],
+ "RebootDBInstance": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mymysqlinstance",
+ "ForceFailover": false
+ },
+ "output": {
+ "DBInstance": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example reboots the specified DB instance without forcing a failover.",
+ "id": "reboot-db-instance-b9ce8a0a-2920-451d-a1f3-01d288aa7366",
+ "title": "To reboot a DB instance"
+ }
+ ],
+ "RemoveSourceIdentifierFromSubscription": [
+ {
+ "input": {
+ "SourceIdentifier": "mymysqlinstance",
+ "SubscriptionName": "myeventsubscription"
+ },
+ "output": {
+ "EventSubscription": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example removes the specified source identifier from the specified DB event subscription.",
+ "id": "remove-source-identifier-from-subscription-30d25493-c19d-4cf7-b4e5-68371d0d8770",
+ "title": "To remove a source identifier from a DB event subscription"
+ }
+ ],
+ "RemoveTagsFromResource": [
+ {
+ "input": {
+ "ResourceName": "arn:aws:rds:us-east-1:992648334831:og:mydboptiongroup",
+ "TagKeys": [
+ "MyKey"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example removes the specified tag associated with the specified DB option group.",
+ "id": "remove-tags-from-resource-49f00574-38f6-4d01-ac89-d3c668449ce3",
+ "title": "To remove tags from a resource"
+ }
+ ],
+ "ResetDBClusterParameterGroup": [
+ {
+ "input": {
+ "DBClusterParameterGroupName": "mydbclusterparametergroup",
+ "ResetAllParameters": true
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example resets all parameters for the specified DB cluster parameter group to their default values.",
+ "id": "reset-db-cluster-parameter-group-b04aeaf7-7f73-49e1-9bb4-857573ea3ee4",
+ "title": "To reset the values of a DB cluster parameter group"
+ }
+ ],
+ "ResetDBParameterGroup": [
+ {
+ "input": {
+ "DBParameterGroupName": "mydbparametergroup",
+ "ResetAllParameters": true
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example resets all parameters for the specified DB parameter group to their default values.",
+ "id": "reset-db-parameter-group-ed2ed723-de0d-4824-8af5-3c65fa130abf",
+ "title": "To reset the values of a DB parameter group"
+ }
+ ],
+ "RestoreDBClusterFromSnapshot": [
+ {
+ "input": {
+ "DBClusterIdentifier": "restored-cluster1",
+ "Engine": "aurora",
+ "SnapshotIdentifier": "sample-cluster-snapshot1"
+ },
+ "output": {
+ "DBCluster": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example restores an Amazon Aurora DB cluster from a DB cluster snapshot.",
+ "id": "to-restore-an-amazon-aurora-db-cluster-from-a-db-cluster-snapshot-1473958144325",
+ "title": "To restore an Amazon Aurora DB cluster from a DB cluster snapshot"
+ }
+ ],
+ "RestoreDBClusterToPointInTime": [
+ {
+ "input": {
+ "DBClusterIdentifier": "sample-restored-cluster1",
+ "RestoreToTime": "2016-09-13T18:45:00Z",
+ "SourceDBClusterIdentifier": "sample-cluster1"
+ },
+ "output": {
+ "DBCluster": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example restores a DB cluster to a new DB cluster at a point in time from the source DB cluster.",
+ "id": "to-restore-a-db-cluster-to-a-point-in-time-1473962082214",
+ "title": "To restore a DB cluster to a point in time."
+ }
+ ],
+ "RestoreDBInstanceFromDBSnapshot": [
+ {
+ "input": {
+ "DBInstanceIdentifier": "mysqldb-restored",
+ "DBSnapshotIdentifier": "rds:mysqldb-2014-04-22-08-15"
+ },
+ "output": {
+ "DBInstance": {
+ "AllocatedStorage": 200,
+ "AutoMinorVersionUpgrade": true,
+ "AvailabilityZone": "us-west-2b",
+ "BackupRetentionPeriod": 7,
+ "CACertificateIdentifier": "rds-ca-2015",
+ "CopyTagsToSnapshot": false,
+ "DBInstanceArn": "arn:aws:rds:us-west-2:123456789012:db:mysqldb-restored",
+ "DBInstanceClass": "db.t2.small",
+ "DBInstanceIdentifier": "mysqldb-restored",
+ "DBInstanceStatus": "available",
+ "DBName": "sample",
+ "DBParameterGroups": [
+ {
+ "DBParameterGroupName": "default.mysql5.6",
+ "ParameterApplyStatus": "in-sync"
+ }
+ ],
+ "DBSecurityGroups": [
+
+ ],
+ "DBSubnetGroup": {
+ "DBSubnetGroupDescription": "default",
+ "DBSubnetGroupName": "default",
+ "SubnetGroupStatus": "Complete",
+ "Subnets": [
+ {
+ "SubnetAvailabilityZone": {
+ "Name": "us-west-2a"
+ },
+ "SubnetIdentifier": "subnet-77e8db03",
+ "SubnetStatus": "Active"
+ },
+ {
+ "SubnetAvailabilityZone": {
+ "Name": "us-west-2b"
+ },
+ "SubnetIdentifier": "subnet-c39989a1",
+ "SubnetStatus": "Active"
+ },
+ {
+ "SubnetAvailabilityZone": {
+ "Name": "us-west-2c"
+ },
+ "SubnetIdentifier": "subnet-4b267b0d",
+ "SubnetStatus": "Active"
+ }
+ ],
+ "VpcId": "vpc-c1c5b3a3"
+ },
+ "DbInstancePort": 0,
+ "DbiResourceId": "db-VNZUCCBTEDC4WR7THXNJO72HVQ",
+ "DomainMemberships": [
+
+ ],
+ "Engine": "mysql",
+ "EngineVersion": "5.6.27",
+ "LicenseModel": "general-public-license",
+ "MasterUsername": "mymasteruser",
+ "MonitoringInterval": 0,
+ "MultiAZ": false,
+ "OptionGroupMemberships": [
+ {
+ "OptionGroupName": "default:mysql-5-6",
+ "Status": "in-sync"
+ }
+ ],
+ "PendingModifiedValues": {
+ },
+ "PreferredBackupWindow": "12:58-13:28",
+ "PreferredMaintenanceWindow": "tue:10:16-tue:10:46",
+ "PubliclyAccessible": true,
+ "ReadReplicaDBInstanceIdentifiers": [
+
+ ],
+ "StorageEncrypted": false,
+ "StorageType": "gp2",
+ "VpcSecurityGroups": [
+ {
+ "Status": "active",
+ "VpcSecurityGroupId": "sg-e5e5b0d2"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example restores a DB instance from a DB snapshot.",
+ "id": "to-restore-a-db-instance-from-a-db-snapshot-1473961657311",
+ "title": "To restore a DB instance from a DB snapshot."
+ }
+ ],
+ "RestoreDBInstanceToPointInTime": [
+ {
+ "input": {
+ "RestoreTime": "2016-09-13T18:45:00Z",
+ "SourceDBInstanceIdentifier": "mysql-sample",
+ "TargetDBInstanceIdentifier": "mysql-sample-restored"
+ },
+ "output": {
+ "DBInstance": {
+ "AllocatedStorage": 200,
+ "AutoMinorVersionUpgrade": true,
+ "AvailabilityZone": "us-west-2b",
+ "BackupRetentionPeriod": 7,
+ "CACertificateIdentifier": "rds-ca-2015",
+ "CopyTagsToSnapshot": false,
+ "DBInstanceArn": "arn:aws:rds:us-west-2:123456789012:db:mysql-sample-restored",
+ "DBInstanceClass": "db.t2.small",
+ "DBInstanceIdentifier": "mysql-sample-restored",
+ "DBInstanceStatus": "available",
+ "DBName": "sample",
+ "DBParameterGroups": [
+ {
+ "DBParameterGroupName": "default.mysql5.6",
+ "ParameterApplyStatus": "in-sync"
+ }
+ ],
+ "DBSecurityGroups": [
+
+ ],
+ "DBSubnetGroup": {
+ "DBSubnetGroupDescription": "default",
+ "DBSubnetGroupName": "default",
+ "SubnetGroupStatus": "Complete",
+ "Subnets": [
+ {
+ "SubnetAvailabilityZone": {
+ "Name": "us-west-2a"
+ },
+ "SubnetIdentifier": "subnet-77e8db03",
+ "SubnetStatus": "Active"
+ },
+ {
+ "SubnetAvailabilityZone": {
+ "Name": "us-west-2b"
+ },
+ "SubnetIdentifier": "subnet-c39989a1",
+ "SubnetStatus": "Active"
+ },
+ {
+ "SubnetAvailabilityZone": {
+ "Name": "us-west-2c"
+ },
+ "SubnetIdentifier": "subnet-4b267b0d",
+ "SubnetStatus": "Active"
+ }
+ ],
+ "VpcId": "vpc-c1c5b3a3"
+ },
+ "DbInstancePort": 0,
+ "DbiResourceId": "db-VNZUCCBTEDC4WR7THXNJO72HVQ",
+ "DomainMemberships": [
+
+ ],
+ "Engine": "mysql",
+ "EngineVersion": "5.6.27",
+ "LicenseModel": "general-public-license",
+ "MasterUsername": "mymasteruser",
+ "MonitoringInterval": 0,
+ "MultiAZ": false,
+ "OptionGroupMemberships": [
+ {
+ "OptionGroupName": "default:mysql-5-6",
+ "Status": "in-sync"
+ }
+ ],
+ "PendingModifiedValues": {
+ },
+ "PreferredBackupWindow": "12:58-13:28",
+ "PreferredMaintenanceWindow": "tue:10:16-tue:10:46",
+ "PubliclyAccessible": true,
+ "ReadReplicaDBInstanceIdentifiers": [
+
+ ],
+ "StorageEncrypted": false,
+ "StorageType": "gp2",
+ "VpcSecurityGroups": [
+ {
+ "Status": "active",
+ "VpcSecurityGroupId": "sg-e5e5b0d2"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example restores a DB instance to a new DB instance at a point in time from the source DB instance.",
+ "id": "to-restore-a-db-instance-to-a-point-in-time-1473962652154",
+ "title": "To restore a DB instance to a point in time."
+ }
+ ],
+ "RevokeDBSecurityGroupIngress": [
+ {
+ "input": {
+ "CIDRIP": "203.0.113.5/32",
+ "DBSecurityGroupName": "mydbsecuritygroup"
+ },
+ "output": {
+ "DBSecurityGroup": {
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example revokes ingress for the specified CIDR block associated with the specified DB security group.",
+ "id": "revoke-db-security-group-ingress-ce5b2c1c-bd4e-4809-b04a-6d78ec448813",
+ "title": "To revoke ingress for a DB security group"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/paginators-1.json
new file mode 100644
index 0000000000..1aef6c371a
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/paginators-1.json
@@ -0,0 +1,239 @@
+{
+ "pagination": {
+ "DescribeCertificates": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Certificates"
+ },
+ "DescribeDBClusterBacktracks": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBClusterBacktracks"
+ },
+ "DescribeDBClusterParameterGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBClusterParameterGroups"
+ },
+ "DescribeDBClusterParameters": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Parameters"
+ },
+ "DescribeDBClusterSnapshots": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBClusterSnapshots"
+ },
+ "DescribeDBClusters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusters"
+ },
+ "DescribeDBEngineVersions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBEngineVersions"
+ },
+ "DescribeDBInstanceAutomatedBackups": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBInstanceAutomatedBackups"
+ },
+ "DescribeDBInstances": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBInstances"
+ },
+ "DescribeDBLogFiles": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DescribeDBLogFiles"
+ },
+ "DescribeDBParameterGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBParameterGroups"
+ },
+ "DescribeDBParameters": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Parameters"
+ },
+ "DescribeDBSecurityGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBSecurityGroups"
+ },
+ "DescribeDBSnapshots": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBSnapshots"
+ },
+ "DescribeDBSubnetGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DBSubnetGroups"
+ },
+ "DescribeEngineDefaultClusterParameters": {
+ "input_token": "Marker",
+ "output_token": "EngineDefaults.Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "EngineDefaults.Parameters"
+ },
+ "DescribeEngineDefaultParameters": {
+ "input_token": "Marker",
+ "output_token": "EngineDefaults.Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "EngineDefaults.Parameters"
+ },
+ "DescribeEventSubscriptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "EventSubscriptionsList"
+ },
+ "DescribeEvents": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Events"
+ },
+ "DescribeGlobalClusters": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "GlobalClusters"
+ },
+ "DescribeOptionGroupOptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OptionGroupOptions"
+ },
+ "DescribeOptionGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OptionGroupsList"
+ },
+ "DescribeOrderableDBInstanceOptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OrderableDBInstanceOptions"
+ },
+ "DescribePendingMaintenanceActions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "PendingMaintenanceActions"
+ },
+ "DescribeReservedDBInstances": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ReservedDBInstances"
+ },
+ "DescribeReservedDBInstancesOfferings": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ReservedDBInstancesOfferings"
+ },
+ "DescribeSourceRegions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "SourceRegions"
+ },
+ "DownloadDBLogFilePortion": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "NumberOfLines",
+ "more_results": "AdditionalDataPending",
+ "result_key": "LogFileData"
+ },
+ "DescribeDBClusterEndpoints": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusterEndpoints"
+ },
+ "DescribeDBProxies": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBProxies"
+ },
+ "DescribeDBProxyTargetGroups": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "TargetGroups"
+ },
+ "DescribeDBProxyTargets": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "Targets"
+ },
+ "DescribeExportTasks": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "ExportTasks"
+ },
+ "DescribeDBProxyEndpoints": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBProxyEndpoints"
+ },
+ "DescribeBlueGreenDeployments": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "BlueGreenDeployments"
+ },
+ "DescribeDBClusterAutomatedBackups": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBClusterAutomatedBackups"
+ },
+ "DescribeIntegrations": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "Integrations"
+ },
+ "DescribeDBSnapshotTenantDatabases": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DBSnapshotTenantDatabases"
+ },
+ "DescribeTenantDatabases": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "TenantDatabases"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..5016e0282b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/paginators-1.sdk-extras.json
@@ -0,0 +1,12 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "DescribeCertificates": {
+ "non_aggregate_keys": [
+ "DefaultCertificateForNewLaunches"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/service-2.json.gz
new file mode 100644
index 0000000000..1ecb2cf55b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/service-2.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/service-2.sdk-extras.json
new file mode 100644
index 0000000000..36aea1fc02
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/service-2.sdk-extras.json
@@ -0,0 +1,47 @@
+ {
+ "version": 1.0,
+ "merge": {
+ "shapes": {
+ "CopyDBClusterSnapshotMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the snapshot to be copied.
"
+ }
+ }
+ },
+ "CreateDBClusterMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the source for the db cluster.
"
+ }
+ }
+ },
+ "CopyDBSnapshotMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the snapshot to be copied.
"
+ }
+ }
+ },
+ "CreateDBInstanceReadReplicaMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the source for the read replica.
"
+ }
+ }
+ },
+ "StartDBInstanceAutomatedBackupsReplicationMessage": {
+ "members": {
+ "SourceRegion": {
+ "shape": "String",
+ "documentation": "The ID of the region that contains the source for the db instance.
"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/waiters-2.json
new file mode 100644
index 0000000000..d91adea381
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rds/2014-10-31/waiters-2.json
@@ -0,0 +1,412 @@
+{
+ "version": 2,
+ "waiters": {
+ "DBInstanceAvailable": {
+ "delay": 30,
+ "operation": "DescribeDBInstances",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ }
+ ]
+ },
+ "DBInstanceDeleted": {
+ "delay": 30,
+ "operation": "DescribeDBInstances",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": true,
+ "matcher": "path",
+ "state": "success",
+ "argument": "length(DBInstances) == `0`"
+ },
+ {
+ "expected": "DBInstanceNotFound",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ },
+ {
+ "expected": "resetting-master-credentials",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBInstances[].DBInstanceStatus"
+ }
+ ]
+ },
+ "DBSnapshotAvailable": {
+ "delay": 30,
+ "operation": "DescribeDBSnapshots",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ }
+ ]
+ },
+ "DBSnapshotDeleted": {
+ "delay": 30,
+ "operation": "DescribeDBSnapshots",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": true,
+ "matcher": "path",
+ "state": "success",
+ "argument": "length(DBSnapshots) == `0`"
+ },
+ {
+ "expected": "DBSnapshotNotFound",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ },
+ {
+ "expected": "resetting-master-credentials",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBSnapshots[].Status"
+ }
+ ]
+ },
+ "DBClusterSnapshotAvailable": {
+ "delay": 30,
+ "operation": "DescribeDBClusterSnapshots",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ }
+ ]
+ },
+ "DBClusterSnapshotDeleted": {
+ "delay": 30,
+ "operation": "DescribeDBClusterSnapshots",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": true,
+ "matcher": "path",
+ "state": "success",
+ "argument": "length(DBClusterSnapshots) == `0`"
+ },
+ {
+ "expected": "DBClusterSnapshotNotFoundFault",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ },
+ {
+ "expected": "resetting-master-credentials",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusterSnapshots[].Status"
+ }
+ ]
+ },
+ "DBClusterAvailable": {
+ "delay": 30,
+ "operation": "DescribeDBClusters",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ }
+ ]
+ },
+ "DBClusterDeleted": {
+ "delay": 30,
+ "operation": "DescribeDBClusters",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": true,
+ "matcher": "path",
+ "state": "success",
+ "argument": "length(DBClusters) == `0`"
+ },
+ {
+ "expected": "DBClusterNotFoundFault",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "rebooting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ },
+ {
+ "expected": "resetting-master-credentials",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "DBClusters[].Status"
+ }
+ ]
+ },
+ "TenantDatabaseAvailable": {
+ "delay": 30,
+ "operation": "DescribeTenantDatabases",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "TenantDatabases[].Status"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "TenantDatabases[].Status"
+ },
+ {
+ "expected": "incompatible-parameters",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "TenantDatabases[].Status"
+ },
+ {
+ "expected": "incompatible-restore",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "TenantDatabases[].Status"
+ }
+ ]
+ },
+ "TenantDatabaseDeleted": {
+ "delay": 30,
+ "operation": "DescribeTenantDatabases",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": true,
+ "matcher": "path",
+ "state": "success",
+ "argument": "length(TenantDatabases) == `0`"
+ },
+ {
+ "expected": "DBInstanceNotFoundFault",
+ "matcher": "error",
+ "state": "success"
+ }
+ ]
+ },
+ "DBSnapshotCompleted": {
+ "delay": 15,
+ "operation": "DescribeDBSnapshots",
+ "maxAttempts": 40,
+ "acceptors": [
+ {
+ "expected": "DBSnapshotNotFound",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "DBSnapshots[].Status"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..17d2b59c6e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/paginators-1.json
new file mode 100644
index 0000000000..b33a4ab753
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/paginators-1.json
@@ -0,0 +1,39 @@
+{
+ "pagination": {
+ "DescribeTable": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ColumnList"
+ },
+ "GetStatementResult": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Records"
+ },
+ "ListDatabases": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Databases"
+ },
+ "ListSchemas": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Schemas"
+ },
+ "ListStatements": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Statements"
+ },
+ "ListTables": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Tables"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..d9b46b92d6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/paginators-1.sdk-extras.json
@@ -0,0 +1,18 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "GetStatementResult": {
+ "non_aggregate_keys": [
+ "ColumnMetadata",
+ "TotalNumRows"
+ ]
+ },
+ "DescribeTable": {
+ "non_aggregate_keys": [
+ "TableName"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/service-2.json.gz
new file mode 100644
index 0000000000..818388f850
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-data/2019-12-20/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2e9a2dde1c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/paginators-1.json
new file mode 100644
index 0000000000..c8f2687419
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/paginators-1.json
@@ -0,0 +1,52 @@
+{
+ "pagination": {
+ "ListEndpointAccess": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "endpoints"
+ },
+ "ListNamespaces": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "namespaces"
+ },
+ "ListRecoveryPoints": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "recoveryPoints"
+ },
+ "ListSnapshots": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "snapshots"
+ },
+ "ListUsageLimits": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "usageLimits"
+ },
+ "ListWorkgroups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "workgroups"
+ },
+ "ListTableRestoreStatus": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "tableRestoreStatuses"
+ },
+ "ListCustomDomainAssociations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "associations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/service-2.json.gz
new file mode 100644
index 0000000000..e318b59cbb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift-serverless/2021-04-21/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0dd64ab5be
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/paginators-1.json
new file mode 100644
index 0000000000..a103fac93a
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/paginators-1.json
@@ -0,0 +1,214 @@
+{
+ "pagination": {
+ "DescribeClusterParameterGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ParameterGroups"
+ },
+ "DescribeClusterParameters": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Parameters"
+ },
+ "DescribeClusterSecurityGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ClusterSecurityGroups"
+ },
+ "DescribeClusterSnapshots": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Snapshots"
+ },
+ "DescribeClusterSubnetGroups": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ClusterSubnetGroups"
+ },
+ "DescribeClusterVersions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ClusterVersions"
+ },
+ "DescribeClusters": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Clusters"
+ },
+ "DescribeDefaultClusterParameters": {
+ "input_token": "Marker",
+ "output_token": "DefaultClusterParameters.Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "DefaultClusterParameters.Parameters"
+ },
+ "DescribeEventSubscriptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "EventSubscriptionsList"
+ },
+ "DescribeEvents": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "Events"
+ },
+ "DescribeHsmClientCertificates": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "HsmClientCertificates"
+ },
+ "DescribeHsmConfigurations": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "HsmConfigurations"
+ },
+ "DescribeOrderableClusterOptions": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "OrderableClusterOptions"
+ },
+ "DescribeReservedNodeOfferings": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ReservedNodeOfferings"
+ },
+ "DescribeReservedNodes": {
+ "input_token": "Marker",
+ "output_token": "Marker",
+ "limit_key": "MaxRecords",
+ "result_key": "ReservedNodes"
+ },
+ "DescribeClusterDbRevisions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "ClusterDbRevisions"
+ },
+ "DescribeClusterTracks": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "MaintenanceTracks"
+ },
+ "DescribeSnapshotCopyGrants": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "SnapshotCopyGrants"
+ },
+ "DescribeSnapshotSchedules": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "SnapshotSchedules"
+ },
+ "DescribeTableRestoreStatus": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "TableRestoreStatusDetails"
+ },
+ "DescribeTags": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "TaggedResources"
+ },
+ "GetReservedNodeExchangeOfferings": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "ReservedNodeOfferings"
+ },
+ "DescribeNodeConfigurationOptions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "NodeConfigurationOptionList"
+ },
+ "DescribeScheduledActions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "ScheduledActions"
+ },
+ "DescribeUsageLimits": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "UsageLimits"
+ },
+ "DescribeEndpointAccess": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "EndpointAccessList"
+ },
+ "DescribeEndpointAuthorization": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "EndpointAuthorizationList"
+ },
+ "DescribeDataShares": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DataShares"
+ },
+ "DescribeDataSharesForConsumer": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DataShares"
+ },
+ "DescribeDataSharesForProducer": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "DataShares"
+ },
+ "DescribeReservedNodeExchangeStatus": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "ReservedNodeExchangeStatusDetails"
+ },
+ "GetReservedNodeExchangeConfigurationOptions": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "ReservedNodeConfigurationOptionList"
+ },
+ "DescribeCustomDomainAssociations": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "Associations"
+ },
+ "DescribeInboundIntegrations": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "InboundIntegrations"
+ },
+ "DescribeRedshiftIdcApplications": {
+ "input_token": "Marker",
+ "limit_key": "MaxRecords",
+ "output_token": "Marker",
+ "result_key": "RedshiftIdcApplications"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/service-2.json.gz
new file mode 100644
index 0000000000..cf4ffc77b4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/waiters-2.json
new file mode 100644
index 0000000000..164e9b0df2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/redshift/2012-12-01/waiters-2.json
@@ -0,0 +1,97 @@
+{
+ "version": 2,
+ "waiters": {
+ "ClusterAvailable": {
+ "delay": 60,
+ "operation": "DescribeClusters",
+ "maxAttempts": 30,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Clusters[].ClusterStatus"
+ },
+ {
+ "expected": "deleting",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Clusters[].ClusterStatus"
+ },
+ {
+ "expected": "ClusterNotFound",
+ "matcher": "error",
+ "state": "retry"
+ }
+ ]
+ },
+ "ClusterDeleted": {
+ "delay": 60,
+ "operation": "DescribeClusters",
+ "maxAttempts": 30,
+ "acceptors": [
+ {
+ "expected": "ClusterNotFound",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "creating",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Clusters[].ClusterStatus"
+ },
+ {
+ "expected": "modifying",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Clusters[].ClusterStatus"
+ }
+ ]
+ },
+ "ClusterRestored": {
+ "operation": "DescribeClusters",
+ "maxAttempts": 30,
+ "delay": 60,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "pathAll",
+ "argument": "Clusters[].RestoreStatus.Status",
+ "expected": "completed"
+ },
+ {
+ "state": "failure",
+ "matcher": "pathAny",
+ "argument": "Clusters[].ClusterStatus",
+ "expected": "deleting"
+ }
+ ]
+ },
+ "SnapshotAvailable": {
+ "delay": 15,
+ "operation": "DescribeClusterSnapshots",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": "available",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "Snapshots[].Status"
+ },
+ {
+ "expected": "failed",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Snapshots[].Status"
+ },
+ {
+ "expected": "deleted",
+ "matcher": "pathAny",
+ "state": "failure",
+ "argument": "Snapshots[].Status"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0cdeddf8be
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/examples-1.json
new file mode 100644
index 0000000000..039e04d60f
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/examples-1.json
@@ -0,0 +1,651 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CompareFaces": [
+ {
+ "input": {
+ "SimilarityThreshold": 90,
+ "SourceImage": {
+ "S3Object": {
+ "Bucket": "mybucket",
+ "Name": "mysourceimage"
+ }
+ },
+ "TargetImage": {
+ "S3Object": {
+ "Bucket": "mybucket",
+ "Name": "mytargetimage"
+ }
+ }
+ },
+ "output": {
+ "FaceMatches": [
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.33481481671333313,
+ "Left": 0.31888890266418457,
+ "Top": 0.4933333396911621,
+ "Width": 0.25
+ },
+ "Confidence": 99.9991226196289
+ },
+ "Similarity": 100
+ }
+ ],
+ "SourceImageFace": {
+ "BoundingBox": {
+ "Height": 0.33481481671333313,
+ "Left": 0.31888890266418457,
+ "Top": 0.4933333396911621,
+ "Width": 0.25
+ },
+ "Confidence": 99.9991226196289
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation compares the largest face detected in the source image with each face detected in the target image.",
+ "id": "to-compare-two-images-1482181985581",
+ "title": "To compare two images"
+ }
+ ],
+ "CreateCollection": [
+ {
+ "input": {
+ "CollectionId": "myphotos"
+ },
+ "output": {
+ "CollectionArn": "aws:rekognition:us-west-2:123456789012:collection/myphotos",
+ "StatusCode": 200
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation creates a Rekognition collection for storing image data.",
+ "id": "to-create-a-collection-1481833313674",
+ "title": "To create a collection"
+ }
+ ],
+ "DeleteCollection": [
+ {
+ "input": {
+ "CollectionId": "myphotos"
+ },
+ "output": {
+ "StatusCode": 200
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation deletes a Rekognition collection.",
+ "id": "to-delete-a-collection-1481838179973",
+ "title": "To delete a collection"
+ }
+ ],
+ "DeleteFaces": [
+ {
+ "input": {
+ "CollectionId": "myphotos",
+ "FaceIds": [
+ "ff43d742-0c13-5d16-a3e8-03d3f58e980b"
+ ]
+ },
+ "output": {
+ "DeletedFaces": [
+ "ff43d742-0c13-5d16-a3e8-03d3f58e980b"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation deletes one or more faces from a Rekognition collection.",
+ "id": "to-delete-a-face-1482182799377",
+ "title": "To delete a face"
+ }
+ ],
+ "DetectFaces": [
+ {
+ "input": {
+ "Image": {
+ "S3Object": {
+ "Bucket": "mybucket",
+ "Name": "myphoto"
+ }
+ }
+ },
+ "output": {
+ "FaceDetails": [
+ {
+ "BoundingBox": {
+ "Height": 0.18000000715255737,
+ "Left": 0.5555555820465088,
+ "Top": 0.33666667342185974,
+ "Width": 0.23999999463558197
+ },
+ "Confidence": 100,
+ "Landmarks": [
+ {
+ "Type": "eyeLeft",
+ "X": 0.6394737362861633,
+ "Y": 0.40819624066352844
+ },
+ {
+ "Type": "eyeRight",
+ "X": 0.7266660928726196,
+ "Y": 0.41039225459098816
+ },
+ {
+ "Type": "eyeRight",
+ "X": 0.6912462115287781,
+ "Y": 0.44240960478782654
+ },
+ {
+ "Type": "mouthDown",
+ "X": 0.6306198239326477,
+ "Y": 0.46700039505958557
+ },
+ {
+ "Type": "mouthUp",
+ "X": 0.7215608954429626,
+ "Y": 0.47114261984825134
+ }
+ ],
+ "Pose": {
+ "Pitch": 4.050806522369385,
+ "Roll": 0.9950747489929199,
+ "Yaw": 13.693790435791016
+ },
+ "Quality": {
+ "Brightness": 37.60169982910156,
+ "Sharpness": 80
+ }
+ }
+ ],
+ "OrientationCorrection": "ROTATE_0"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation detects faces in an image stored in an AWS S3 bucket.",
+ "id": "to-detect-faces-in-an-image-1481841782793",
+ "title": "To detect faces in an image"
+ }
+ ],
+ "DetectLabels": [
+ {
+ "input": {
+ "Image": {
+ "S3Object": {
+ "Bucket": "mybucket",
+ "Name": "myphoto"
+ }
+ },
+ "MaxLabels": 123,
+ "MinConfidence": 70
+ },
+ "output": {
+ "Labels": [
+ {
+ "Confidence": 99.25072479248047,
+ "Name": "People"
+ },
+ {
+ "Confidence": 99.25074005126953,
+ "Name": "Person"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation detects labels in the supplied image",
+ "id": "to-detect-labels-1481834255770",
+ "title": "To detect labels"
+ }
+ ],
+ "IndexFaces": [
+ {
+ "input": {
+ "CollectionId": "myphotos",
+ "DetectionAttributes": [
+
+ ],
+ "ExternalImageId": "myphotoid",
+ "Image": {
+ "S3Object": {
+ "Bucket": "mybucket",
+ "Name": "myphoto"
+ }
+ }
+ },
+ "output": {
+ "FaceRecords": [
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.33481481671333313,
+ "Left": 0.31888890266418457,
+ "Top": 0.4933333396911621,
+ "Width": 0.25
+ },
+ "Confidence": 99.9991226196289,
+ "FaceId": "ff43d742-0c13-5d16-a3e8-03d3f58e980b",
+ "ImageId": "465f4e93-763e-51d0-b030-b9667a2d94b1"
+ },
+ "FaceDetail": {
+ "BoundingBox": {
+ "Height": 0.33481481671333313,
+ "Left": 0.31888890266418457,
+ "Top": 0.4933333396911621,
+ "Width": 0.25
+ },
+ "Confidence": 99.9991226196289,
+ "Landmarks": [
+ {
+ "Type": "eyeLeft",
+ "X": 0.3976764678955078,
+ "Y": 0.6248345971107483
+ },
+ {
+ "Type": "eyeRight",
+ "X": 0.4810936450958252,
+ "Y": 0.6317117214202881
+ },
+ {
+ "Type": "noseLeft",
+ "X": 0.41986238956451416,
+ "Y": 0.7111940383911133
+ },
+ {
+ "Type": "mouthDown",
+ "X": 0.40525302290916443,
+ "Y": 0.7497701048851013
+ },
+ {
+ "Type": "mouthUp",
+ "X": 0.4753248989582062,
+ "Y": 0.7558549642562866
+ }
+ ],
+ "Pose": {
+ "Pitch": -9.713645935058594,
+ "Roll": 4.707281112670898,
+ "Yaw": -24.438663482666016
+ },
+ "Quality": {
+ "Brightness": 29.23358917236328,
+ "Sharpness": 80
+ }
+ }
+ },
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.32592591643333435,
+ "Left": 0.5144444704055786,
+ "Top": 0.15111111104488373,
+ "Width": 0.24444444477558136
+ },
+ "Confidence": 99.99950408935547,
+ "FaceId": "8be04dba-4e58-520d-850e-9eae4af70eb2",
+ "ImageId": "465f4e93-763e-51d0-b030-b9667a2d94b1"
+ },
+ "FaceDetail": {
+ "BoundingBox": {
+ "Height": 0.32592591643333435,
+ "Left": 0.5144444704055786,
+ "Top": 0.15111111104488373,
+ "Width": 0.24444444477558136
+ },
+ "Confidence": 99.99950408935547,
+ "Landmarks": [
+ {
+ "Type": "eyeLeft",
+ "X": 0.6006892323493958,
+ "Y": 0.290842205286026
+ },
+ {
+ "Type": "eyeRight",
+ "X": 0.6808141469955444,
+ "Y": 0.29609042406082153
+ },
+ {
+ "Type": "noseLeft",
+ "X": 0.6395332217216492,
+ "Y": 0.3522595763206482
+ },
+ {
+ "Type": "mouthDown",
+ "X": 0.5892083048820496,
+ "Y": 0.38689887523651123
+ },
+ {
+ "Type": "mouthUp",
+ "X": 0.674560010433197,
+ "Y": 0.394125759601593
+ }
+ ],
+ "Pose": {
+ "Pitch": -4.683138370513916,
+ "Roll": 2.1029529571533203,
+ "Yaw": 6.716655254364014
+ },
+ "Quality": {
+ "Brightness": 34.951698303222656,
+ "Sharpness": 160
+ }
+ }
+ }
+ ],
+ "OrientationCorrection": "ROTATE_0"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation detects faces in an image and adds them to the specified Rekognition collection.",
+ "id": "to-add-a-face-to-a-collection-1482179542923",
+ "title": "To add a face to a collection"
+ }
+ ],
+ "ListCollections": [
+ {
+ "input": {
+ },
+ "output": {
+ "CollectionIds": [
+ "myphotos"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation returns a list of Rekognition collections.",
+ "id": "to-list-the-collections-1482179199088",
+ "title": "To list the collections"
+ }
+ ],
+ "ListFaces": [
+ {
+ "input": {
+ "CollectionId": "myphotos",
+ "MaxResults": 20
+ },
+ "output": {
+ "Faces": [
+ {
+ "BoundingBox": {
+ "Height": 0.18000000715255737,
+ "Left": 0.5555559992790222,
+ "Top": 0.336667001247406,
+ "Width": 0.23999999463558197
+ },
+ "Confidence": 100,
+ "FaceId": "1c62e8b5-69a7-5b7d-b3cd-db4338a8a7e7",
+ "ImageId": "147fdf82-7a71-52cf-819b-e786c7b9746e"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.16555599868297577,
+ "Left": 0.30963000655174255,
+ "Top": 0.7066670060157776,
+ "Width": 0.22074100375175476
+ },
+ "Confidence": 100,
+ "FaceId": "29a75abe-397b-5101-ba4f-706783b2246c",
+ "ImageId": "147fdf82-7a71-52cf-819b-e786c7b9746e"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.3234420120716095,
+ "Left": 0.3233329951763153,
+ "Top": 0.5,
+ "Width": 0.24222199618816376
+ },
+ "Confidence": 99.99829864501953,
+ "FaceId": "38271d79-7bc2-5efb-b752-398a8d575b85",
+ "ImageId": "d5631190-d039-54e4-b267-abd22c8647c5"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.03555560111999512,
+ "Left": 0.37388700246810913,
+ "Top": 0.2477779984474182,
+ "Width": 0.04747769981622696
+ },
+ "Confidence": 99.99210357666016,
+ "FaceId": "3b01bef0-c883-5654-ba42-d5ad28b720b3",
+ "ImageId": "812d9f04-86f9-54fc-9275-8d0dcbcb6784"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.05333330109715462,
+ "Left": 0.2937690019607544,
+ "Top": 0.35666701197624207,
+ "Width": 0.07121659815311432
+ },
+ "Confidence": 99.99919891357422,
+ "FaceId": "4839a608-49d0-566c-8301-509d71b534d1",
+ "ImageId": "812d9f04-86f9-54fc-9275-8d0dcbcb6784"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.3249259889125824,
+ "Left": 0.5155559778213501,
+ "Top": 0.1513350009918213,
+ "Width": 0.24333299696445465
+ },
+ "Confidence": 99.99949645996094,
+ "FaceId": "70008e50-75e4-55d0-8e80-363fb73b3a14",
+ "ImageId": "d5631190-d039-54e4-b267-abd22c8647c5"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.03777780011296272,
+ "Left": 0.7002969980239868,
+ "Top": 0.18777799606323242,
+ "Width": 0.05044509842991829
+ },
+ "Confidence": 99.92639923095703,
+ "FaceId": "7f5f88ed-d684-5a88-b0df-01e4a521552b",
+ "ImageId": "812d9f04-86f9-54fc-9275-8d0dcbcb6784"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.05555560067296028,
+ "Left": 0.13946600258350372,
+ "Top": 0.46333301067352295,
+ "Width": 0.07270029932260513
+ },
+ "Confidence": 99.99469757080078,
+ "FaceId": "895b4e2c-81de-5902-a4bd-d1792bda00b2",
+ "ImageId": "812d9f04-86f9-54fc-9275-8d0dcbcb6784"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.3259260058403015,
+ "Left": 0.5144439935684204,
+ "Top": 0.15111100673675537,
+ "Width": 0.24444399774074554
+ },
+ "Confidence": 99.99949645996094,
+ "FaceId": "8be04dba-4e58-520d-850e-9eae4af70eb2",
+ "ImageId": "465f4e93-763e-51d0-b030-b9667a2d94b1"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.18888899683952332,
+ "Left": 0.3783380091190338,
+ "Top": 0.2355560064315796,
+ "Width": 0.25222599506378174
+ },
+ "Confidence": 99.9999008178711,
+ "FaceId": "908544ad-edc3-59df-8faf-6a87cc256cf5",
+ "ImageId": "3c731605-d772-541a-a5e7-0375dbc68a07"
+ },
+ {
+ "BoundingBox": {
+ "Height": 0.33481499552726746,
+ "Left": 0.31888899207115173,
+ "Top": 0.49333301186561584,
+ "Width": 0.25
+ },
+ "Confidence": 99.99909973144531,
+ "FaceId": "ff43d742-0c13-5d16-a3e8-03d3f58e980b",
+ "ImageId": "465f4e93-763e-51d0-b030-b9667a2d94b1"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation lists the faces in a Rekognition collection.",
+ "id": "to-list-the-faces-in-a-collection-1482181416530",
+ "title": "To list the faces in a collection"
+ }
+ ],
+ "SearchFaces": [
+ {
+ "input": {
+ "CollectionId": "myphotos",
+ "FaceId": "70008e50-75e4-55d0-8e80-363fb73b3a14",
+ "FaceMatchThreshold": 90,
+ "MaxFaces": 10
+ },
+ "output": {
+ "FaceMatches": [
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.3259260058403015,
+ "Left": 0.5144439935684204,
+ "Top": 0.15111100673675537,
+ "Width": 0.24444399774074554
+ },
+ "Confidence": 99.99949645996094,
+ "FaceId": "8be04dba-4e58-520d-850e-9eae4af70eb2",
+ "ImageId": "465f4e93-763e-51d0-b030-b9667a2d94b1"
+ },
+ "Similarity": 99.97222137451172
+ },
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.16555599868297577,
+ "Left": 0.30963000655174255,
+ "Top": 0.7066670060157776,
+ "Width": 0.22074100375175476
+ },
+ "Confidence": 100,
+ "FaceId": "29a75abe-397b-5101-ba4f-706783b2246c",
+ "ImageId": "147fdf82-7a71-52cf-819b-e786c7b9746e"
+ },
+ "Similarity": 97.04154968261719
+ },
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.18888899683952332,
+ "Left": 0.3783380091190338,
+ "Top": 0.2355560064315796,
+ "Width": 0.25222599506378174
+ },
+ "Confidence": 99.9999008178711,
+ "FaceId": "908544ad-edc3-59df-8faf-6a87cc256cf5",
+ "ImageId": "3c731605-d772-541a-a5e7-0375dbc68a07"
+ },
+ "Similarity": 95.94520568847656
+ }
+ ],
+ "SearchedFaceId": "70008e50-75e4-55d0-8e80-363fb73b3a14"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation searches for matching faces in the collection the supplied face belongs to.",
+ "id": "to-delete-a-face-1482182799377",
+ "title": "To delete a face"
+ }
+ ],
+ "SearchFacesByImage": [
+ {
+ "input": {
+ "CollectionId": "myphotos",
+ "FaceMatchThreshold": 95,
+ "Image": {
+ "S3Object": {
+ "Bucket": "mybucket",
+ "Name": "myphoto"
+ }
+ },
+ "MaxFaces": 5
+ },
+ "output": {
+ "FaceMatches": [
+ {
+ "Face": {
+ "BoundingBox": {
+ "Height": 0.3234420120716095,
+ "Left": 0.3233329951763153,
+ "Top": 0.5,
+ "Width": 0.24222199618816376
+ },
+ "Confidence": 99.99829864501953,
+ "FaceId": "38271d79-7bc2-5efb-b752-398a8d575b85",
+ "ImageId": "d5631190-d039-54e4-b267-abd22c8647c5"
+ },
+ "Similarity": 99.97036743164062
+ }
+ ],
+ "SearchedFaceBoundingBox": {
+ "Height": 0.33481481671333313,
+ "Left": 0.31888890266418457,
+ "Top": 0.4933333396911621,
+ "Width": 0.25
+ },
+ "SearchedFaceConfidence": 99.9991226196289
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation searches for faces in a Rekognition collection that match the largest face in an S3 bucket stored image.",
+ "id": "to-search-for-faces-matching-a-supplied-image-1482175994491",
+ "title": "To search for faces matching a supplied image"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/paginators-1.json
new file mode 100644
index 0000000000..436503d688
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/paginators-1.json
@@ -0,0 +1,64 @@
+{
+ "pagination": {
+ "ListCollections": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": [
+ "CollectionIds",
+ "FaceModelVersions"
+ ]
+ },
+ "ListFaces": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Faces",
+ "non_aggregate_keys": [
+ "FaceModelVersion"
+ ]
+ },
+ "ListStreamProcessors": {
+ "result_key": "StreamProcessors",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "DescribeProjectVersions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ProjectVersionDescriptions"
+ },
+ "DescribeProjects": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ProjectDescriptions"
+ },
+ "ListDatasetEntries": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DatasetEntries"
+ },
+ "ListDatasetLabels": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DatasetLabelDescriptions"
+ },
+ "ListProjectPolicies": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ProjectPolicies"
+ },
+ "ListUsers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Users"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/service-2.json.gz
new file mode 100644
index 0000000000..059c959b8e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/waiters-2.json
new file mode 100644
index 0000000000..c67dc6239b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rekognition/2016-06-27/waiters-2.json
@@ -0,0 +1,45 @@
+{
+ "version": 2,
+ "waiters": {
+ "ProjectVersionTrainingCompleted": {
+ "description": "Wait until the ProjectVersion training completes.",
+ "operation": "DescribeProjectVersions",
+ "delay": 120,
+ "maxAttempts": 360,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "pathAll",
+ "argument": "ProjectVersionDescriptions[].Status",
+ "expected": "TRAINING_COMPLETED"
+ },
+ {
+ "state": "failure",
+ "matcher": "pathAny",
+ "argument": "ProjectVersionDescriptions[].Status",
+ "expected": "TRAINING_FAILED"
+ }
+ ]
+ },
+ "ProjectVersionRunning": {
+ "description": "Wait until the ProjectVersion is running.",
+ "delay": 30,
+ "maxAttempts": 40,
+ "operation": "DescribeProjectVersions",
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "pathAll",
+ "argument": "ProjectVersionDescriptions[].Status",
+ "expected": "RUNNING"
+ },
+ {
+ "state": "failure",
+ "matcher": "pathAny",
+ "argument": "ProjectVersionDescriptions[].Status",
+ "expected": "FAILED"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e65e0b01cc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/paginators-1.json
new file mode 100644
index 0000000000..75eb51bde3
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListSpaces": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "spaces"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/service-2.json.gz
new file mode 100644
index 0000000000..221e427e40
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/repostspace/2022-05-13/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8aca8ea744
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/service-2.json.gz
new file mode 100644
index 0000000000..7a1fed2b7d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resiliencehub/2020-04-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..bae6a1fb1f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/paginators-1.json
new file mode 100644
index 0000000000..c5a49dc5fe
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListIndexes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Indexes"
+ },
+ "ListSupportedResourceTypes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResourceTypes"
+ },
+ "ListViews": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Views"
+ },
+ "Search": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Resources"
+ },
+ "ListIndexesForMembers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Indexes"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..a5959a5834
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/paginators-1.sdk-extras.json
@@ -0,0 +1,13 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "Search": {
+ "non_aggregate_keys": [
+ "ViewArn",
+ "Count"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/service-2.json.gz
new file mode 100644
index 0000000000..c86509907f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-explorer-2/2022-07-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..3e34b89b40
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/paginators-1.json
new file mode 100644
index 0000000000..04de8d30fe
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListGroups": {
+ "result_key": [
+ "GroupIdentifiers",
+ "Groups"
+ ],
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "SearchResources": {
+ "result_key": "ResourceIdentifiers",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListGroupResources": {
+ "result_key": [
+ "ResourceIdentifiers",
+ "Resources"
+ ],
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/service-2.json.gz
new file mode 100644
index 0000000000..27654fcb5f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resource-groups/2017-11-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..742fff91da
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/paginators-1.json
new file mode 100644
index 0000000000..7312afc50c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/paginators-1.json
@@ -0,0 +1,26 @@
+{
+ "pagination": {
+ "GetResources": {
+ "input_token": "PaginationToken",
+ "limit_key": "ResourcesPerPage",
+ "output_token": "PaginationToken",
+ "result_key": "ResourceTagMappingList"
+ },
+ "GetTagKeys": {
+ "input_token": "PaginationToken",
+ "output_token": "PaginationToken",
+ "result_key": "TagKeys"
+ },
+ "GetTagValues": {
+ "input_token": "PaginationToken",
+ "output_token": "PaginationToken",
+ "result_key": "TagValues"
+ },
+ "GetComplianceSummary": {
+ "input_token": "PaginationToken",
+ "limit_key": "MaxResults",
+ "output_token": "PaginationToken",
+ "result_key": "SummaryList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/service-2.json.gz
new file mode 100644
index 0000000000..8b4d8386d4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/resourcegroupstaggingapi/2017-01-26/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8b9794c503
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/paginators-1.json
new file mode 100644
index 0000000000..380e723c43
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/paginators-1.json
@@ -0,0 +1,70 @@
+{
+ "pagination": {
+ "ListDeploymentJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "deploymentJobs"
+ },
+ "ListFleets": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "fleetDetails"
+ },
+ "ListRobotApplications": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "robotApplicationSummaries"
+ },
+ "ListRobots": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "robots"
+ },
+ "ListSimulationApplications": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "simulationApplicationSummaries"
+ },
+ "ListSimulationJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "simulationJobSummaries"
+ },
+ "ListSimulationJobBatches": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "simulationJobBatchSummaries"
+ },
+ "ListWorldExportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "worldExportJobSummaries"
+ },
+ "ListWorldGenerationJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "worldGenerationJobSummaries"
+ },
+ "ListWorldTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "templateSummaries"
+ },
+ "ListWorlds": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "worldSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/service-2.json.gz
new file mode 100644
index 0000000000..e02d2ebe34
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/robomaker/2018-06-29/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..6df8c1edbb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..97298614bf
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/paginators-1.json
@@ -0,0 +1,24 @@
+{
+ "pagination": {
+ "ListCrls": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "crls"
+ },
+ "ListProfiles": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "profiles"
+ },
+ "ListSubjects": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "subjects"
+ },
+ "ListTrustAnchors": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "trustAnchors"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..2d1d3d9ece
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rolesanywhere/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..711f4289a1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/paginators-1.json
new file mode 100644
index 0000000000..a2ef01b9f6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListRoutingControls": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RoutingControls"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/service-2.json.gz
new file mode 100644
index 0000000000..9d597bb031
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-cluster/2019-12-02/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..fdd9fb14e3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/paginators-1.json
new file mode 100644
index 0000000000..024682ba8a
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListAssociatedRoute53HealthChecks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "HealthCheckIds"
+ },
+ "ListClusters": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Clusters"
+ },
+ "ListControlPanels": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ControlPanels"
+ },
+ "ListRoutingControls": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RoutingControls"
+ },
+ "ListSafetyRules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "SafetyRules"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/service-2.json.gz
new file mode 100644
index 0000000000..3f195bdb4b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/waiters-2.json
new file mode 100644
index 0000000000..1794757e6d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-control-config/2020-11-02/waiters-2.json
@@ -0,0 +1,152 @@
+{
+ "version": 2,
+ "waiters": {
+ "ClusterCreated": {
+ "description": "Wait until a cluster is created",
+ "operation": "DescribeCluster",
+ "delay": 5,
+ "maxAttempts": 26,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "Cluster.Status",
+ "expected": "DEPLOYED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Cluster.Status",
+ "expected": "PENDING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "ClusterDeleted": {
+ "description": "Wait for a cluster to be deleted",
+ "operation": "DescribeCluster",
+ "delay": 5,
+ "maxAttempts": 26,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "status",
+ "expected": 404
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "Cluster.Status",
+ "expected": "PENDING_DELETION"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "ControlPanelCreated": {
+ "description": "Wait until a control panel is created",
+ "operation": "DescribeControlPanel",
+ "delay": 5,
+ "maxAttempts": 26,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "ControlPanel.Status",
+ "expected": "DEPLOYED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "ControlPanel.Status",
+ "expected": "PENDING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "ControlPanelDeleted": {
+ "description": "Wait until a control panel is deleted",
+ "operation": "DescribeControlPanel",
+ "delay": 5,
+ "maxAttempts": 26,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "status",
+ "expected": 404
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "ControlPanel.Status",
+ "expected": "PENDING_DELETION"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "RoutingControlCreated": {
+ "description": "Wait until a routing control is created",
+ "operation": "DescribeRoutingControl",
+ "delay": 5,
+ "maxAttempts": 26,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "path",
+ "argument": "RoutingControl.Status",
+ "expected": "DEPLOYED"
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "RoutingControl.Status",
+ "expected": "PENDING"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ },
+ "RoutingControlDeleted": {
+ "description": "Wait for a routing control to be deleted",
+ "operation": "DescribeRoutingControl",
+ "delay": 5,
+ "maxAttempts": 26,
+ "acceptors": [
+ {
+ "state": "success",
+ "matcher": "status",
+ "expected": 404
+ },
+ {
+ "state": "retry",
+ "matcher": "path",
+ "argument": "RoutingControl.Status",
+ "expected": "PENDING_DELETION"
+ },
+ {
+ "state": "retry",
+ "matcher": "status",
+ "expected": 500
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..ad66453a62
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/paginators-1.json
new file mode 100644
index 0000000000..a71f088013
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/paginators-1.json
@@ -0,0 +1,77 @@
+{
+ "pagination": {
+ "ListReadinessChecks": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ReadinessChecks"
+ },
+ "ListResourceSets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResourceSets"
+ },
+ "ListCells": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Cells"
+ },
+ "ListRecoveryGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RecoveryGroups"
+ },
+ "ListRules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Rules"
+ },
+ "ListCrossAccountAuthorizations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CrossAccountAuthorizations"
+ },
+ "GetCellReadinessSummary": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ReadinessChecks",
+ "non_aggregate_keys": [
+ "Readiness"
+ ]
+ },
+ "GetRecoveryGroupReadinessSummary": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ReadinessChecks",
+ "non_aggregate_keys": [
+ "Readiness"
+ ]
+ },
+ "GetReadinessCheckStatus": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Resources",
+ "non_aggregate_keys": [
+ "Readiness",
+ "Messages"
+ ]
+ },
+ "GetReadinessCheckResourceStatus": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Rules",
+ "non_aggregate_keys": [
+ "Readiness"
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/service-2.json.gz
new file mode 100644
index 0000000000..102ddeb43b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53-recovery-readiness/2019-12-02/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..d3716af532
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/examples-1.json
new file mode 100644
index 0000000000..d757c2b9bd
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/examples-1.json
@@ -0,0 +1,762 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AssociateVPCWithHostedZone": [
+ {
+ "input": {
+ "Comment": "",
+ "HostedZoneId": "Z3M3LMPEXAMPLE",
+ "VPC": {
+ "VPCId": "vpc-1a2b3c4d",
+ "VPCRegion": "us-east-2"
+ }
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "",
+ "Id": "/change/C3HC6WDB2UANE2",
+ "Status": "INSYNC",
+ "SubmittedAt": "2017-01-31T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ "Status": "Valid values are PENDING and INSYNC.",
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example associates the VPC with ID vpc-1a2b3c4d with the hosted zone with ID Z3M3LMPEXAMPLE.",
+ "id": "to-associate-a-vpc-with-a-hosted-zone-1484069228699",
+ "title": "To associate a VPC with a hosted zone"
+ }
+ ],
+ "ChangeResourceRecordSets": [
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.44"
+ }
+ ],
+ "TTL": 60,
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "Web server for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "Web server for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "TTL": "The amount of time in seconds that you want DNS resolvers to cache the values in this resource record set before submitting another request to Route 53",
+ "Value": "The value that is applicable to the value of Type. For example, if Type is A, Value is an IPv4 address"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates a resource record set that routes Internet traffic to a resource with an IP address of 192.0.2.44.",
+ "id": "to-create-update-or-delete-resource-record-sets-1484344703668",
+ "title": "To create a basic resource record set"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "HealthCheckId": "abcdef11-2222-3333-4444-555555fedcba",
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.44"
+ }
+ ],
+ "SetIdentifier": "Seattle data center",
+ "TTL": 60,
+ "Type": "A",
+ "Weight": 100
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "HealthCheckId": "abcdef66-7777-8888-9999-000000fedcba",
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.45"
+ }
+ ],
+ "SetIdentifier": "Portland data center",
+ "TTL": 60,
+ "Type": "A",
+ "Weight": 200
+ }
+ }
+ ],
+ "Comment": "Web servers for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "Web servers for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "TTL": "The amount of time in seconds that you want DNS resolvers to cache the values in this resource record set before submitting another request to Route 53. TTLs must be the same for all weighted resource record sets that have the same name and type.",
+ "Value": "The value that is applicable to the value of Type. For example, if Type is A, Value is an IPv4 address"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates two weighted resource record sets. The resource with a Weight of 100 will get 1/3rd of traffic (100/100+200), and the other resource will get the rest of the traffic for example.com.",
+ "id": "to-create-weighted-resource-record-sets-1484348208522",
+ "title": "To create weighted resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "d123rk29d0stfj.cloudfront.net",
+ "EvaluateTargetHealth": false,
+ "HostedZoneId": "Z2FDTNDATAQYW2"
+ },
+ "Name": "example.com",
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "CloudFront distribution for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "CloudFront distribution for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "DNSName": "The DNS name assigned to the resource",
+ "HostedZoneId": "Depends on the type of resource that you want to route traffic to",
+ "Type": "A or AAAA, depending on the type of resource that you want to route traffic to"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates an alias resource record set that routes traffic to a CloudFront distribution.",
+ "id": "to-create-an-alias-resource-record-set-1484348404062",
+ "title": "To create an alias resource record set"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-123456789.us-east-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z3AADJGX6KTTL2"
+ },
+ "Name": "example.com",
+ "SetIdentifier": "Ohio region",
+ "Type": "A",
+ "Weight": 100
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-987654321.us-west-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z1H1FL5HABSF5"
+ },
+ "Name": "example.com",
+ "SetIdentifier": "Oregon region",
+ "Type": "A",
+ "Weight": 200
+ }
+ }
+ ],
+ "Comment": "ELB load balancers for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "ELB load balancers for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "DNSName": "The DNS name assigned to the resource",
+ "HostedZoneId": "Depends on the type of resource that you want to route traffic to",
+ "Type": "A or AAAA, depending on the type of resource that you want to route traffic to"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates two weighted alias resource record sets that route traffic to ELB load balancers. The resource with a Weight of 100 will get 1/3rd of traffic (100/100+200), and the other resource will get the rest of the traffic for example.com.",
+ "id": "to-create-weighted-alias-resource-record-sets-1484349467416",
+ "title": "To create weighted alias resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "HealthCheckId": "abcdef11-2222-3333-4444-555555fedcba",
+ "Name": "example.com",
+ "Region": "us-east-2",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.44"
+ }
+ ],
+ "SetIdentifier": "Ohio region",
+ "TTL": 60,
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "HealthCheckId": "abcdef66-7777-8888-9999-000000fedcba",
+ "Name": "example.com",
+ "Region": "us-west-2",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.45"
+ }
+ ],
+ "SetIdentifier": "Oregon region",
+ "TTL": 60,
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "EC2 instances for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "EC2 instances for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "TTL": "The amount of time in seconds that you want DNS resolvers to cache the values in this resource record set before submitting another request to Route 53",
+ "Value": "The value that is applicable to the value of Type. For example, if Type is A, Value is an IPv4 address"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates two latency resource record sets that route traffic to EC2 instances. Traffic for example.com is routed either to the Ohio region or the Oregon region, depending on the latency between the user and those regions.",
+ "id": "to-create-latency-resource-record-sets-1484350219917",
+ "title": "To create latency resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-123456789.us-east-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z3AADJGX6KTTL2"
+ },
+ "Name": "example.com",
+ "Region": "us-east-2",
+ "SetIdentifier": "Ohio region",
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-987654321.us-west-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z1H1FL5HABSF5"
+ },
+ "Name": "example.com",
+ "Region": "us-west-2",
+ "SetIdentifier": "Oregon region",
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "ELB load balancers for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "ELB load balancers for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "DNSName": "The DNS name assigned to the resource",
+ "HostedZoneId": "Depends on the type of resource that you want to route traffic to",
+ "Type": "A or AAAA, depending on the type of resource that you want to route traffic to"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates two latency alias resource record sets that route traffic for example.com to ELB load balancers. Requests are routed either to the Ohio region or the Oregon region, depending on the latency between the user and those regions.",
+ "id": "to-create-latency-alias-resource-record-sets-1484601774179",
+ "title": "To create latency alias resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "Failover": "PRIMARY",
+ "HealthCheckId": "abcdef11-2222-3333-4444-555555fedcba",
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.44"
+ }
+ ],
+ "SetIdentifier": "Ohio region",
+ "TTL": 60,
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "Failover": "SECONDARY",
+ "HealthCheckId": "abcdef66-7777-8888-9999-000000fedcba",
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.45"
+ }
+ ],
+ "SetIdentifier": "Oregon region",
+ "TTL": 60,
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "Failover configuration for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "Failover configuration for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "TTL": "The amount of time in seconds that you want DNS resolvers to cache the values in this resource record set before submitting another request to Route 53",
+ "Value": "The value that is applicable to the value of Type. For example, if Type is A, Value is an IPv4 address"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates primary and secondary failover resource record sets that route traffic to EC2 instances. Traffic is generally routed to the primary resource, in the Ohio region. If that resource is unavailable, traffic is routed to the secondary resource, in the Oregon region.",
+ "id": "to-create-failover-resource-record-sets-1484604541740",
+ "title": "To create failover resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-123456789.us-east-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z3AADJGX6KTTL2"
+ },
+ "Failover": "PRIMARY",
+ "Name": "example.com",
+ "SetIdentifier": "Ohio region",
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-987654321.us-west-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z1H1FL5HABSF5"
+ },
+ "Failover": "SECONDARY",
+ "Name": "example.com",
+ "SetIdentifier": "Oregon region",
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "Failover alias configuration for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "Failover alias configuration for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "DNSName": "The DNS name assigned to the resource",
+ "HostedZoneId": "Depends on the type of resource that you want to route traffic to",
+ "Type": "A or AAAA, depending on the type of resource that you want to route traffic to"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates primary and secondary failover alias resource record sets that route traffic to ELB load balancers. Traffic is generally routed to the primary resource, in the Ohio region. If that resource is unavailable, traffic is routed to the secondary resource, in the Oregon region.",
+ "id": "to-create-failover-alias-resource-record-sets-1484607497724",
+ "title": "To create failover alias resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "GeoLocation": {
+ "ContinentCode": "NA"
+ },
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.44"
+ }
+ ],
+ "SetIdentifier": "North America",
+ "TTL": 60,
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "GeoLocation": {
+ "ContinentCode": "SA"
+ },
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.45"
+ }
+ ],
+ "SetIdentifier": "South America",
+ "TTL": 60,
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "GeoLocation": {
+ "ContinentCode": "EU"
+ },
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.46"
+ }
+ ],
+ "SetIdentifier": "Europe",
+ "TTL": 60,
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "GeoLocation": {
+ "CountryCode": "*"
+ },
+ "Name": "example.com",
+ "ResourceRecords": [
+ {
+ "Value": "192.0.2.47"
+ }
+ ],
+ "SetIdentifier": "Other locations",
+ "TTL": 60,
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "Geolocation configuration for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "Geolocation configuration for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "TTL": "The amount of time in seconds that you want DNS resolvers to cache the values in this resource record set before submitting another request to Route 53",
+ "Value": "The value that is applicable to the value of Type. For example, if Type is A, Value is an IPv4 address"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates four geolocation resource record sets that use IPv4 addresses to route traffic to resources such as web servers running on EC2 instances. Traffic is routed to one of four IP addresses, for North America (NA), for South America (SA), for Europe (EU), and for all other locations (*).",
+ "id": "to-create-geolocation-resource-record-sets-1484612462466",
+ "title": "To create geolocation resource record sets"
+ },
+ {
+ "input": {
+ "ChangeBatch": {
+ "Changes": [
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-123456789.us-east-2.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z3AADJGX6KTTL2"
+ },
+ "GeoLocation": {
+ "ContinentCode": "NA"
+ },
+ "Name": "example.com",
+ "SetIdentifier": "North America",
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-234567890.sa-east-1.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z2P70J7HTTTPLU"
+ },
+ "GeoLocation": {
+ "ContinentCode": "SA"
+ },
+ "Name": "example.com",
+ "SetIdentifier": "South America",
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-234567890.eu-central-1.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z215JYRZR1TBD5"
+ },
+ "GeoLocation": {
+ "ContinentCode": "EU"
+ },
+ "Name": "example.com",
+ "SetIdentifier": "Europe",
+ "Type": "A"
+ }
+ },
+ {
+ "Action": "CREATE",
+ "ResourceRecordSet": {
+ "AliasTarget": {
+ "DNSName": "example-com-234567890.ap-southeast-1.elb.amazonaws.com ",
+ "EvaluateTargetHealth": true,
+ "HostedZoneId": "Z1LMS91P8CMLE5"
+ },
+ "GeoLocation": {
+ "CountryCode": "*"
+ },
+ "Name": "example.com",
+ "SetIdentifier": "Other locations",
+ "Type": "A"
+ }
+ }
+ ],
+ "Comment": "Geolocation alias configuration for example.com"
+ },
+ "HostedZoneId": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "ChangeInfo": {
+ "Comment": "Geolocation alias configuration for example.com",
+ "Id": "/change/C2682N5HXP0BZ4",
+ "Status": "PENDING",
+ "SubmittedAt": "2017-02-10T01:36:41.958Z"
+ }
+ },
+ "comments": {
+ "input": {
+ "Action": "Valid values: CREATE, DELETE, UPSERT",
+ "DNSName": "The DNS name assigned to the resource",
+ "HostedZoneId": "Depends on the type of resource that you want to route traffic to",
+ "Type": "A or AAAA, depending on the type of resource that you want to route traffic to"
+ },
+ "output": {
+ "SubmittedAt": "The date and time are in Coordinated Universal Time (UTC) and ISO 8601 format."
+ }
+ },
+ "description": "The following example creates four geolocation alias resource record sets that route traffic to ELB load balancers. Traffic is routed to one of four IP addresses, for North America (NA), for South America (SA), for Europe (EU), and for all other locations (*).",
+ "id": "to-create-geolocation-alias-resource-record-sets-1484612871203",
+ "title": "To create geolocation alias resource record sets"
+ }
+ ],
+ "ChangeTagsForResource": [
+ {
+ "input": {
+ "AddTags": [
+ {
+ "Key": "apex",
+ "Value": "3874"
+ },
+ {
+ "Key": "acme",
+ "Value": "4938"
+ }
+ ],
+ "RemoveTagKeys": [
+ "Nadir"
+ ],
+ "ResourceId": "Z3M3LMPEXAMPLE",
+ "ResourceType": "hostedzone"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ "ResourceType": "Valid values are healthcheck and hostedzone."
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds two tags and removes one tag from the hosted zone with ID Z3M3LMPEXAMPLE.",
+ "id": "to-add-or-remove-tags-from-a-hosted-zone-or-health-check-1484084752409",
+ "title": "To add or remove tags from a hosted zone or health check"
+ }
+ ],
+ "GetHostedZone": [
+ {
+ "input": {
+ "Id": "Z3M3LMPEXAMPLE"
+ },
+ "output": {
+ "DelegationSet": {
+ "NameServers": [
+ "ns-2048.awsdns-64.com",
+ "ns-2049.awsdns-65.net",
+ "ns-2050.awsdns-66.org",
+ "ns-2051.awsdns-67.co.uk"
+ ]
+ },
+ "HostedZone": {
+ "CallerReference": "C741617D-04E4-F8DE-B9D7-0D150FC61C2E",
+ "Config": {
+ "PrivateZone": false
+ },
+ "Id": "/hostedzone/Z3M3LMPEXAMPLE",
+ "Name": "myawsbucket.com.",
+ "ResourceRecordSetCount": 8
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ "Id": "The ID of the hosted zone that you specified in the GetHostedZone request.",
+ "Name": "The name of the hosted zone.",
+ "NameServers": "The servers that you specify in your domain configuration.",
+ "PrivateZone": "True if this is a private hosted zone, false if it's a public hosted zone."
+ }
+ },
+ "description": "The following example gets information about the Z3M3LMPEXAMPLE hosted zone.",
+ "id": "to-get-information-about-a-hosted-zone-1481752361124",
+ "title": "To get information about a hosted zone"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/paginators-1.json
new file mode 100644
index 0000000000..2c370965ff
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/paginators-1.json
@@ -0,0 +1,67 @@
+{
+ "pagination": {
+ "ListHealthChecks": {
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "more_results": "IsTruncated",
+ "limit_key": "MaxItems",
+ "result_key": "HealthChecks"
+ },
+ "ListHostedZones": {
+ "input_token": "Marker",
+ "output_token": "NextMarker",
+ "more_results": "IsTruncated",
+ "limit_key": "MaxItems",
+ "result_key": "HostedZones"
+ },
+ "ListResourceRecordSets": {
+ "more_results": "IsTruncated",
+ "limit_key": "MaxItems",
+ "result_key": "ResourceRecordSets",
+ "input_token": [
+ "StartRecordName",
+ "StartRecordType",
+ "StartRecordIdentifier"
+ ],
+ "output_token": [
+ "NextRecordName",
+ "NextRecordType",
+ "NextRecordIdentifier"
+ ]
+ },
+ "ListVPCAssociationAuthorizations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "non_aggregate_keys": [
+ "HostedZoneId"
+ ],
+ "result_key": [
+ "VPCs"
+ ]
+ },
+ "ListQueryLoggingConfigs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "QueryLoggingConfigs"
+ },
+ "ListCidrBlocks": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CidrBlocks"
+ },
+ "ListCidrCollections": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CidrCollections"
+ },
+ "ListCidrLocations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CidrLocations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/service-2.json.gz
new file mode 100644
index 0000000000..1cd8f754ad
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/waiters-2.json
new file mode 100644
index 0000000000..94aad399ef
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53/2013-04-01/waiters-2.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "waiters": {
+ "ResourceRecordSetsChanged": {
+ "delay": 30,
+ "maxAttempts": 60,
+ "operation": "GetChange",
+ "acceptors": [
+ {
+ "matcher": "path",
+ "expected": "INSYNC",
+ "argument": "ChangeInfo.Status",
+ "state": "success"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..9ccecfc51e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/paginators-1.json
new file mode 100644
index 0000000000..c2f5cbcb9c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/paginators-1.json
@@ -0,0 +1,29 @@
+{
+ "version": "1.0",
+ "pagination": {
+ "ListDomains": {
+ "limit_key": "MaxItems",
+ "input_token": "Marker",
+ "output_token": "NextPageMarker",
+ "result_key": "Domains"
+ },
+ "ListOperations": {
+ "limit_key": "MaxItems",
+ "input_token": "Marker",
+ "output_token": "NextPageMarker",
+ "result_key": "Operations"
+ },
+ "ViewBilling": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextPageMarker",
+ "result_key": "BillingRecords"
+ },
+ "ListPrices": {
+ "input_token": "Marker",
+ "limit_key": "MaxItems",
+ "output_token": "NextPageMarker",
+ "result_key": "Prices"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/service-2.json.gz
new file mode 100644
index 0000000000..f6db51f3dd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53domains/2014-05-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..71740d189f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/paginators-1.json
new file mode 100644
index 0000000000..d6529438ff
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/paginators-1.json
@@ -0,0 +1,100 @@
+{
+ "pagination": {
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ },
+ "ListResolverEndpointIpAddresses": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "IpAddresses"
+ },
+ "ListResolverEndpoints": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverEndpoints"
+ },
+ "ListResolverQueryLogConfigAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverQueryLogConfigAssociations"
+ },
+ "ListResolverQueryLogConfigs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverQueryLogConfigs"
+ },
+ "ListResolverRuleAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverRuleAssociations"
+ },
+ "ListResolverRules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverRules"
+ },
+ "ListResolverDnssecConfigs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverDnssecConfigs"
+ },
+ "ListFirewallConfigs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FirewallConfigs"
+ },
+ "ListFirewallDomainLists": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FirewallDomainLists"
+ },
+ "ListFirewallDomains": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Domains"
+ },
+ "ListFirewallRuleGroupAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FirewallRuleGroupAssociations"
+ },
+ "ListFirewallRuleGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FirewallRuleGroups"
+ },
+ "ListFirewallRules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FirewallRules"
+ },
+ "ListResolverConfigs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResolverConfigs"
+ },
+ "ListOutpostResolvers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "OutpostResolvers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..6808793615
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/paginators-1.sdk-extras.json
@@ -0,0 +1,39 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "ListResolverEndpointIpAddresses": {
+ "non_aggregate_keys": [
+ "MaxResults"
+ ]
+ },
+ "ListResolverEndpoints": {
+ "non_aggregate_keys": [
+ "MaxResults"
+ ]
+ },
+ "ListResolverQueryLogConfigAssociations": {
+ "non_aggregate_keys": [
+ "TotalCount",
+ "TotalFilteredCount"
+ ]
+ },
+ "ListResolverQueryLogConfigs": {
+ "non_aggregate_keys": [
+ "TotalCount",
+ "TotalFilteredCount"
+ ]
+ },
+ "ListResolverRuleAssociations": {
+ "non_aggregate_keys": [
+ "MaxResults"
+ ]
+ },
+ "ListResolverRules": {
+ "non_aggregate_keys": [
+ "MaxResults"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/service-2.json.gz
new file mode 100644
index 0000000000..17851c4472
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/route53resolver/2018-04-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..7024f10d4a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..1a044920d1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "GetAppMonitorData": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Events"
+ },
+ "ListAppMonitors": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AppMonitorSummaries"
+ },
+ "BatchGetRumMetricDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MetricDefinitions"
+ },
+ "ListRumMetricsDestinations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Destinations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..b551f4e3d3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/rum/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..271930e3b0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/examples-1.json
new file mode 100644
index 0000000000..38a47bb331
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/examples-1.json
@@ -0,0 +1,1843 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AbortMultipartUpload": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "bigobject",
+ "UploadId": "xadcOB_7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example aborts a multipart upload.",
+ "id": "to-abort-a-multipart-upload-1481853354987",
+ "title": "To abort a multipart upload"
+ }
+ ],
+ "CompleteMultipartUpload": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "bigobject",
+ "MultipartUpload": {
+ "Parts": [
+ {
+ "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"",
+ "PartNumber": "1"
+ },
+ {
+ "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"",
+ "PartNumber": "2"
+ }
+ ]
+ },
+ "UploadId": "7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--"
+ },
+ "output": {
+ "Bucket": "acexamplebucket",
+ "ETag": "\"4d9031c7644d8081c2829f4ea23c55f7-2\"",
+ "Key": "bigobject",
+ "Location": "https://examplebucket.s3.amazonaws.com/bigobject"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example completes a multipart upload.",
+ "id": "to-complete-multipart-upload-1481851590483",
+ "title": "To complete multipart upload"
+ }
+ ],
+ "CopyObject": [
+ {
+ "input": {
+ "Bucket": "destinationbucket",
+ "CopySource": "/sourcebucket/HappyFacejpg",
+ "Key": "HappyFaceCopyjpg"
+ },
+ "output": {
+ "CopyObjectResult": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "LastModified": "2016-12-15T17:38:53.000Z"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example copies an object from one bucket to another.",
+ "id": "to-copy-an-object-1481823186878",
+ "title": "To copy an object"
+ }
+ ],
+ "CreateBucket": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "CreateBucketConfiguration": {
+ "LocationConstraint": "eu-west-1"
+ }
+ },
+ "output": {
+ "Location": "http://examplebucket.s3.amazonaws.com/"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a bucket. The request specifies an AWS region where to create the bucket.",
+ "id": "to-create-a-bucket-in-a-specific-region-1483399072992",
+ "title": "To create a bucket in a specific region"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "Location": "/examplebucket"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a bucket.",
+ "id": "to-create-a-bucket--1472851826060",
+ "title": "To create a bucket "
+ }
+ ],
+ "CreateMultipartUpload": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "largeobject"
+ },
+ "output": {
+ "Bucket": "examplebucket",
+ "Key": "largeobject",
+ "UploadId": "ibZBv_75gd9r8lH_gqXatLdxMVpAlj6ZQjEs.OwyF3953YdwbcQnMA2BLGn8Lx12fQNICtMw5KyteFeHw.Sjng--"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example initiates a multipart upload.",
+ "id": "to-initiate-a-multipart-upload-1481836794513",
+ "title": "To initiate a multipart upload"
+ }
+ ],
+ "DeleteBucket": [
+ {
+ "input": {
+ "Bucket": "forrandall2"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes the specified bucket.",
+ "id": "to-delete-a-bucket-1473108514262",
+ "title": "To delete a bucket"
+ }
+ ],
+ "DeleteBucketCors": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes CORS configuration on a bucket.",
+ "id": "to-delete-cors-configuration-on-a-bucket-1483042856112",
+ "title": "To delete cors configuration on a bucket."
+ }
+ ],
+ "DeleteBucketLifecycle": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes lifecycle configuration on a bucket.",
+ "id": "to-delete-lifecycle-configuration-on-a-bucket-1483043310583",
+ "title": "To delete lifecycle configuration on a bucket."
+ }
+ ],
+ "DeleteBucketPolicy": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes bucket policy on the specified bucket.",
+ "id": "to-delete-bucket-policy-1483043406577",
+ "title": "To delete bucket policy"
+ }
+ ],
+ "DeleteBucketReplication": [
+ {
+ "input": {
+ "Bucket": "example"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes replication configuration set on bucket.",
+ "id": "to-delete-bucket-replication-configuration-1483043684668",
+ "title": "To delete bucket replication configuration"
+ }
+ ],
+ "DeleteBucketTagging": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes bucket tags.",
+ "id": "to-delete-bucket-tags-1483043846509",
+ "title": "To delete bucket tags"
+ }
+ ],
+ "DeleteBucketWebsite": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes bucket website configuration.",
+ "id": "to-delete-bucket-website-configuration-1483043937825",
+ "title": "To delete bucket website configuration"
+ }
+ ],
+ "DeleteObject": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "objectkey.jpg"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an object from an S3 bucket.",
+ "id": "to-delete-an-object-1472850136595",
+ "title": "To delete an object"
+ },
+ {
+ "input": {
+ "Bucket": "ExampleBucket",
+ "Key": "HappyFace.jpg"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an object from a non-versioned bucket.",
+ "id": "to-delete-an-object-from-a-non-versioned-bucket-1481588533089",
+ "title": "To delete an object (from a non-versioned bucket)"
+ }
+ ],
+ "DeleteObjectTagging": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg",
+ "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI"
+ },
+ "output": {
+ "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example removes tag set associated with the specified object version. The request specifies both the object key and object version.",
+ "id": "to-remove-tag-set-from-an-object-version-1483145285913",
+ "title": "To remove tag set from an object version"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ "VersionId": "null"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example removes tag set associated with the specified object. If the bucket is versioning enabled, the operation removes tag set from the latest object version.",
+ "id": "to-remove-tag-set-from-an-object-1483145342862",
+ "title": "To remove tag set from an object"
+ }
+ ],
+ "DeleteObjects": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Delete": {
+ "Objects": [
+ {
+ "Key": "HappyFace.jpg",
+ "VersionId": "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b"
+ },
+ {
+ "Key": "HappyFace.jpg",
+ "VersionId": "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd"
+ }
+ ],
+ "Quiet": false
+ }
+ },
+ "output": {
+ "Deleted": [
+ {
+ "Key": "HappyFace.jpg",
+ "VersionId": "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd"
+ },
+ {
+ "Key": "HappyFace.jpg",
+ "VersionId": "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes objects from a bucket. The request specifies object versions. S3 deletes specific object versions and returns the key and versions of deleted objects in the response.",
+ "id": "to-delete-multiple-object-versions-from-a-versioned-bucket-1483147087737",
+ "title": "To delete multiple object versions from a versioned bucket"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Delete": {
+ "Objects": [
+ {
+ "Key": "objectkey1"
+ },
+ {
+ "Key": "objectkey2"
+ }
+ ],
+ "Quiet": false
+ }
+ },
+ "output": {
+ "Deleted": [
+ {
+ "DeleteMarker": "true",
+ "DeleteMarkerVersionId": "A._w1z6EFiCF5uhtQMDal9JDkID9tQ7F",
+ "Key": "objectkey1"
+ },
+ {
+ "DeleteMarker": "true",
+ "DeleteMarkerVersionId": "iOd_ORxhkKe_e8G8_oSGxt2PjsCZKlkt",
+ "Key": "objectkey2"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes objects from a bucket. The bucket is versioned, and the request does not specify the object version to delete. In this case, all versions remain in the bucket and S3 adds a delete marker.",
+ "id": "to-delete-multiple-objects-from-a-versioned-bucket-1483146248805",
+ "title": "To delete multiple objects from a versioned bucket"
+ }
+ ],
+ "GetBucketCors": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "CORSRules": [
+ {
+ "AllowedHeaders": [
+ "Authorization"
+ ],
+ "AllowedMethods": [
+ "GET"
+ ],
+ "AllowedOrigins": [
+ "*"
+ ],
+ "MaxAgeSeconds": 3000
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns cross-origin resource sharing (CORS) configuration set on a bucket.",
+ "id": "to-get-cors-configuration-set-on-a-bucket-1481596855475",
+ "title": "To get cors configuration set on a bucket"
+ }
+ ],
+ "GetBucketLifecycle": [
+ {
+ "input": {
+ "Bucket": "acl1"
+ },
+ "output": {
+ "Rules": [
+ {
+ "Expiration": {
+ "Days": 1
+ },
+ "ID": "delete logs",
+ "Prefix": "123/",
+ "Status": "Enabled"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example gets ACL on the specified bucket.",
+ "id": "to-get-a-bucket-acl-1474413606503",
+ "title": "To get a bucket acl"
+ }
+ ],
+ "GetBucketLifecycleConfiguration": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "Rules": [
+ {
+ "ID": "Rule for TaxDocs/",
+ "Prefix": "TaxDocs",
+ "Status": "Enabled",
+ "Transitions": [
+ {
+ "Days": 365,
+ "StorageClass": "STANDARD_IA"
+ }
+ ]
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves lifecycle configuration on set on a bucket. ",
+ "id": "to-get-lifecycle-configuration-on-a-bucket-1481666063200",
+ "title": "To get lifecycle configuration on a bucket"
+ }
+ ],
+ "GetBucketLocation": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "LocationConstraint": "us-west-2"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns bucket location.",
+ "id": "to-get-bucket-location-1481594573609",
+ "title": "To get bucket location"
+ }
+ ],
+ "GetBucketNotification": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "QueueConfiguration": {
+ "Event": "s3:ObjectCreated:Put",
+ "Events": [
+ "s3:ObjectCreated:Put"
+ ],
+ "Id": "MDQ2OGQ4NDEtOTBmNi00YTM4LTk0NzYtZDIwN2I3NWQ1NjIx",
+ "Queue": "arn:aws:sqs:us-east-1:acct-id:S3ObjectCreatedEventQueue"
+ },
+ "TopicConfiguration": {
+ "Event": "s3:ObjectCreated:Copy",
+ "Events": [
+ "s3:ObjectCreated:Copy"
+ ],
+ "Id": "YTVkMWEzZGUtNTY1NS00ZmE2LWJjYjktMmRlY2QwODFkNTJi",
+ "Topic": "arn:aws:sns:us-east-1:acct-id:S3ObjectCreatedEventTopic"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns notification configuration set on a bucket.",
+ "id": "to-get-notification-configuration-set-on-a-bucket-1481594028667",
+ "title": "To get notification configuration set on a bucket"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "QueueConfiguration": {
+ "Event": "s3:ObjectCreated:Put",
+ "Events": [
+ "s3:ObjectCreated:Put"
+ ],
+ "Id": "MDQ2OGQ4NDEtOTBmNi00YTM4LTk0NzYtZDIwN2I3NWQ1NjIx",
+ "Queue": "arn:aws:sqs:us-east-1:acct-id:S3ObjectCreatedEventQueue"
+ },
+ "TopicConfiguration": {
+ "Event": "s3:ObjectCreated:Copy",
+ "Events": [
+ "s3:ObjectCreated:Copy"
+ ],
+ "Id": "YTVkMWEzZGUtNTY1NS00ZmE2LWJjYjktMmRlY2QwODFkNTJi",
+ "Topic": "arn:aws:sns:us-east-1:acct-id:S3ObjectCreatedEventTopic"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns notification configuration set on a bucket.",
+ "id": "to-get-notification-configuration-set-on-a-bucket-1481594028667",
+ "title": "To get notification configuration set on a bucket"
+ }
+ ],
+ "GetBucketPolicy": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "Policy": "{\"Version\":\"2008-10-17\",\"Id\":\"LogPolicy\",\"Statement\":[{\"Sid\":\"Enables the log delivery group to publish logs to your bucket \",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"111122223333\"},\"Action\":[\"s3:GetBucketAcl\",\"s3:GetObjectAcl\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::policytest1/*\",\"arn:aws:s3:::policytest1\"]}]}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns bucket policy associated with a bucket.",
+ "id": "to-get-bucket-policy-1481595098424",
+ "title": "To get bucket policy"
+ }
+ ],
+ "GetBucketReplication": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "ReplicationConfiguration": {
+ "Role": "arn:aws:iam::acct-id:role/example-role",
+ "Rules": [
+ {
+ "Destination": {
+ "Bucket": "arn:aws:s3:::destination-bucket"
+ },
+ "ID": "MWIwNTkwZmItMTE3MS00ZTc3LWJkZDEtNzRmODQwYzc1OTQy",
+ "Prefix": "Tax",
+ "Status": "Enabled"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns replication configuration set on a bucket.",
+ "id": "to-get-replication-configuration-set-on-a-bucket-1481593597175",
+ "title": "To get replication configuration set on a bucket"
+ }
+ ],
+ "GetBucketRequestPayment": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "Payer": "BucketOwner"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves bucket versioning configuration.",
+ "id": "to-get-bucket-versioning-configuration-1483037183929",
+ "title": "To get bucket versioning configuration"
+ }
+ ],
+ "GetBucketTagging": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "TagSet": [
+ {
+ "Key": "key1",
+ "Value": "value1"
+ },
+ {
+ "Key": "key2",
+ "Value": "value2"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns tag set associated with a bucket",
+ "id": "to-get-tag-set-associated-with-a-bucket-1481593232107",
+ "title": "To get tag set associated with a bucket"
+ }
+ ],
+ "GetBucketVersioning": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "MFADelete": "Disabled",
+ "Status": "Enabled"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves bucket versioning configuration.",
+ "id": "to-get-bucket-versioning-configuration-1483037183929",
+ "title": "To get bucket versioning configuration"
+ }
+ ],
+ "GetBucketWebsite": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "ErrorDocument": {
+ "Key": "error.html"
+ },
+ "IndexDocument": {
+ "Suffix": "index.html"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves website configuration of a bucket.",
+ "id": "to-get-bucket-website-configuration-1483037016926",
+ "title": "To get bucket website configuration"
+ }
+ ],
+ "GetObject": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ "AcceptRanges": "bytes",
+ "ContentLength": "3191",
+ "ContentType": "image/jpeg",
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "LastModified": "Thu, 15 Dec 2016 01:19:41 GMT",
+ "Metadata": {
+ },
+ "TagCount": 2,
+ "VersionId": "null"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves an object for an S3 bucket.",
+ "id": "to-retrieve-an-object-1481827837012",
+ "title": "To retrieve an object"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "SampleFile.txt",
+ "Range": "bytes=0-9"
+ },
+ "output": {
+ "AcceptRanges": "bytes",
+ "ContentLength": "10",
+ "ContentRange": "bytes 0-9/43",
+ "ContentType": "text/plain",
+ "ETag": "\"0d94420ffd0bc68cd3d152506b97a9cc\"",
+ "LastModified": "Thu, 09 Oct 2014 22:57:28 GMT",
+ "Metadata": {
+ },
+ "VersionId": "null"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves an object for an S3 bucket. The request specifies the range header to retrieve a specific byte range.",
+ "id": "to-retrieve-a-byte-range-of-an-object--1481832674603",
+ "title": "To retrieve a byte range of an object "
+ }
+ ],
+ "GetObjectAcl": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ "Grants": [
+ {
+ "Grantee": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc",
+ "Type": "CanonicalUser"
+ },
+ "Permission": "WRITE"
+ },
+ {
+ "Grantee": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc",
+ "Type": "CanonicalUser"
+ },
+ "Permission": "WRITE_ACP"
+ },
+ {
+ "Grantee": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc",
+ "Type": "CanonicalUser"
+ },
+ "Permission": "READ"
+ },
+ {
+ "Grantee": {
+ "DisplayName": "owner-display-name",
+ "ID": "852b113eexamplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc",
+ "Type": "CanonicalUser"
+ },
+ "Permission": "READ_ACP"
+ }
+ ],
+ "Owner": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves access control list (ACL) of an object.",
+ "id": "to-retrieve-object-acl-1481833557740",
+ "title": "To retrieve object ACL"
+ }
+ ],
+ "GetObjectTagging": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ "TagSet": [
+ {
+ "Key": "Key4",
+ "Value": "Value4"
+ },
+ {
+ "Key": "Key3",
+ "Value": "Value3"
+ }
+ ],
+ "VersionId": "null"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves tag set of an object.",
+ "id": "to-retrieve-tag-set-of-an-object-1481833847896",
+ "title": "To retrieve tag set of an object"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "exampleobject",
+ "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI"
+ },
+ "output": {
+ "TagSet": [
+ {
+ "Key": "Key1",
+ "Value": "Value1"
+ }
+ ],
+ "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves tag set of an object. The request specifies object version.",
+ "id": "to-retrieve-tag-set-of-a-specific-object-version-1483400283663",
+ "title": "To retrieve tag set of a specific object version"
+ }
+ ],
+ "GetObjectTorrent": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves torrent files of an object.",
+ "id": "to-retrieve-torrent-files-for-an-object-1481834115959",
+ "title": "To retrieve torrent files for an object"
+ }
+ ],
+ "HeadBucket": [
+ {
+ "input": {
+ "Bucket": "acl1"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation checks to see if a bucket exists.",
+ "id": "to-determine-if-bucket-exists-1473110292262",
+ "title": "To determine if bucket exists"
+ }
+ ],
+ "HeadObject": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ "AcceptRanges": "bytes",
+ "ContentLength": "3191",
+ "ContentType": "image/jpeg",
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "LastModified": "Thu, 15 Dec 2016 01:19:41 GMT",
+ "Metadata": {
+ },
+ "VersionId": "null"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves an object metadata.",
+ "id": "to-retrieve-metadata-of-an-object-without-returning-the-object-itself-1481834820480",
+ "title": "To retrieve metadata of an object without returning the object itself"
+ }
+ ],
+ "ListMultipartUploads": [
+ {
+ "input": {
+ "Bucket": "examplebucket"
+ },
+ "output": {
+ "Uploads": [
+ {
+ "Initiated": "2014-05-01T05:40:58.000Z",
+ "Initiator": {
+ "DisplayName": "display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Key": "JavaFile",
+ "Owner": {
+ "DisplayName": "display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "StorageClass": "STANDARD",
+ "UploadId": "examplelUa.CInXklLQtSMJITdUnoZ1Y5GACB5UckOtspm5zbDMCkPF_qkfZzMiFZ6dksmcnqxJyIBvQMG9X9Q--"
+ },
+ {
+ "Initiated": "2014-05-01T05:41:27.000Z",
+ "Initiator": {
+ "DisplayName": "display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Key": "JavaFile",
+ "Owner": {
+ "DisplayName": "display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "StorageClass": "STANDARD",
+ "UploadId": "examplelo91lv1iwvWpvCiJWugw2xXLPAD7Z8cJyX9.WiIRgNrdG6Ldsn.9FtS63TCl1Uf5faTB.1U5Ckcbmdw--"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example lists in-progress multipart uploads on a specific bucket.",
+ "id": "to-list-in-progress-multipart-uploads-on-a-bucket-1481852775260",
+ "title": "To list in-progress multipart uploads on a bucket"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "KeyMarker": "nextkeyfrompreviousresponse",
+ "MaxUploads": "2",
+ "UploadIdMarker": "valuefrompreviousresponse"
+ },
+ "output": {
+ "Bucket": "acl1",
+ "IsTruncated": true,
+ "KeyMarker": "",
+ "MaxUploads": "2",
+ "NextKeyMarker": "someobjectkey",
+ "NextUploadIdMarker": "examplelo91lv1iwvWpvCiJWugw2xXLPAD7Z8cJyX9.WiIRgNrdG6Ldsn.9FtS63TCl1Uf5faTB.1U5Ckcbmdw--",
+ "UploadIdMarker": "",
+ "Uploads": [
+ {
+ "Initiated": "2014-05-01T05:40:58.000Z",
+ "Initiator": {
+ "DisplayName": "ownder-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Key": "JavaFile",
+ "Owner": {
+ "DisplayName": "mohanataws",
+ "ID": "852b113e7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "StorageClass": "STANDARD",
+ "UploadId": "gZ30jIqlUa.CInXklLQtSMJITdUnoZ1Y5GACB5UckOtspm5zbDMCkPF_qkfZzMiFZ6dksmcnqxJyIBvQMG9X9Q--"
+ },
+ {
+ "Initiated": "2014-05-01T05:41:27.000Z",
+ "Initiator": {
+ "DisplayName": "ownder-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Key": "JavaFile",
+ "Owner": {
+ "DisplayName": "ownder-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "StorageClass": "STANDARD",
+ "UploadId": "b7tZSqIlo91lv1iwvWpvCiJWugw2xXLPAD7Z8cJyX9.WiIRgNrdG6Ldsn.9FtS63TCl1Uf5faTB.1U5Ckcbmdw--"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example specifies the upload-id-marker and key-marker from previous truncated response to retrieve next setup of multipart uploads.",
+ "id": "list-next-set-of-multipart-uploads-when-previous-result-is-truncated-1482428106748",
+ "title": "List next set of multipart uploads when previous result is truncated"
+ }
+ ],
+ "ListObjectVersions": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Prefix": "HappyFace.jpg"
+ },
+ "output": {
+ "Versions": [
+ {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "IsLatest": true,
+ "Key": "HappyFace.jpg",
+ "LastModified": "2016-12-15T01:19:41.000Z",
+ "Owner": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Size": 3191,
+ "StorageClass": "STANDARD",
+ "VersionId": "null"
+ },
+ {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "IsLatest": false,
+ "Key": "HappyFace.jpg",
+ "LastModified": "2016-12-13T00:58:26.000Z",
+ "Owner": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Size": 3191,
+ "StorageClass": "STANDARD",
+ "VersionId": "PHtexPGjH2y.zBgT8LmB7wwLI2mpbz.k"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example return versions of an object with specific key name prefix. The request limits the number of items returned to two. If there are are more than two object version, S3 returns NextToken in the response. You can specify this token value in your next request to fetch next set of object versions.",
+ "id": "to-list-object-versions-1481910996058",
+ "title": "To list object versions"
+ }
+ ],
+ "ListObjects": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "MaxKeys": "2"
+ },
+ "output": {
+ "Contents": [
+ {
+ "ETag": "\"70ee1738b6b21e2c8a43f3a5ab0eee71\"",
+ "Key": "example1.jpg",
+ "LastModified": "2014-11-21T19:40:05.000Z",
+ "Owner": {
+ "DisplayName": "myname",
+ "ID": "12345example25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Size": 11,
+ "StorageClass": "STANDARD"
+ },
+ {
+ "ETag": "\"9c8af9a76df052144598c115ef33e511\"",
+ "Key": "example2.jpg",
+ "LastModified": "2013-11-15T01:10:49.000Z",
+ "Owner": {
+ "DisplayName": "myname",
+ "ID": "12345example25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Size": 713193,
+ "StorageClass": "STANDARD"
+ }
+ ],
+ "NextMarker": "eyJNYXJrZXIiOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiOiAyfQ=="
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example list two objects in a bucket.",
+ "id": "to-list-objects-in-a-bucket-1473447646507",
+ "title": "To list objects in a bucket"
+ }
+ ],
+ "ListObjectsV2": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "MaxKeys": "2"
+ },
+ "output": {
+ "Contents": [
+ {
+ "ETag": "\"70ee1738b6b21e2c8a43f3a5ab0eee71\"",
+ "Key": "happyface.jpg",
+ "LastModified": "2014-11-21T19:40:05.000Z",
+ "Size": 11,
+ "StorageClass": "STANDARD"
+ },
+ {
+ "ETag": "\"becf17f89c30367a9a44495d62ed521a-1\"",
+ "Key": "test.jpg",
+ "LastModified": "2014-05-02T04:51:50.000Z",
+ "Size": 4192256,
+ "StorageClass": "STANDARD"
+ }
+ ],
+ "IsTruncated": true,
+ "KeyCount": "2",
+ "MaxKeys": "2",
+ "Name": "examplebucket",
+ "NextContinuationToken": "1w41l63U0xa8q7smH50vCxyTQqdxo69O3EmK28Bi5PcROI4wI/EyIJg==",
+ "Prefix": ""
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves object list. The request specifies max keys to limit response to include only 2 object keys. ",
+ "id": "to-get-object-list",
+ "title": "To get object list"
+ }
+ ],
+ "ListParts": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "bigobject",
+ "UploadId": "example7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--"
+ },
+ "output": {
+ "Initiator": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Owner": {
+ "DisplayName": "owner-display-name",
+ "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc"
+ },
+ "Parts": [
+ {
+ "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"",
+ "LastModified": "2016-12-16T00:11:42.000Z",
+ "PartNumber": "1",
+ "Size": 26246026
+ },
+ {
+ "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"",
+ "LastModified": "2016-12-16T00:15:01.000Z",
+ "PartNumber": "2",
+ "Size": 26246026
+ }
+ ],
+ "StorageClass": "STANDARD"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example lists parts uploaded for a specific multipart upload.",
+ "id": "to-list-parts-of-a-multipart-upload-1481852006923",
+ "title": "To list parts of a multipart upload."
+ }
+ ],
+ "PutBucketAcl": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "GrantFullControl": "id=examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484",
+ "GrantWrite": "uri=http://acs.amazonaws.com/groups/s3/LogDelivery"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example replaces existing ACL on a bucket. The ACL grants the bucket owner (specified using the owner ID) and write permission to the LogDelivery group. Because this is a replace operation, you must specify all the grants in your request. To incrementally add or remove ACL grants, you might use the console.",
+ "id": "put-bucket-acl-1482260397033",
+ "title": "Put bucket acl"
+ }
+ ],
+ "PutBucketCors": [
+ {
+ "input": {
+ "Bucket": "",
+ "CORSConfiguration": {
+ "CORSRules": [
+ {
+ "AllowedHeaders": [
+ "*"
+ ],
+ "AllowedMethods": [
+ "PUT",
+ "POST",
+ "DELETE"
+ ],
+ "AllowedOrigins": [
+ "http://www.example.com"
+ ],
+ "ExposeHeaders": [
+ "x-amz-server-side-encryption"
+ ],
+ "MaxAgeSeconds": 3000
+ },
+ {
+ "AllowedHeaders": [
+ "Authorization"
+ ],
+ "AllowedMethods": [
+ "GET"
+ ],
+ "AllowedOrigins": [
+ "*"
+ ],
+ "MaxAgeSeconds": 3000
+ }
+ ]
+ },
+ "ContentMD5": ""
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example enables PUT, POST, and DELETE requests from www.example.com, and enables GET requests from any domain.",
+ "id": "to-set-cors-configuration-on-a-bucket-1483037818805",
+ "title": "To set cors configuration on a bucket."
+ }
+ ],
+ "PutBucketLifecycleConfiguration": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "LifecycleConfiguration": {
+ "Rules": [
+ {
+ "Expiration": {
+ "Days": 3650
+ },
+ "Filter": {
+ "Prefix": "documents/"
+ },
+ "ID": "TestOnly",
+ "Status": "Enabled",
+ "Transitions": [
+ {
+ "Days": 365,
+ "StorageClass": "GLACIER"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example replaces existing lifecycle configuration, if any, on the specified bucket. ",
+ "id": "put-bucket-lifecycle-1482264533092",
+ "title": "Put bucket lifecycle"
+ }
+ ],
+ "PutBucketLogging": [
+ {
+ "input": {
+ "Bucket": "sourcebucket",
+ "BucketLoggingStatus": {
+ "LoggingEnabled": {
+ "TargetBucket": "targetbucket",
+ "TargetGrants": [
+ {
+ "Grantee": {
+ "Type": "Group",
+ "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
+ },
+ "Permission": "READ"
+ }
+ ],
+ "TargetPrefix": "MyBucketLogs/"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets logging policy on a bucket. For the Log Delivery group to deliver logs to the destination bucket, it needs permission for the READ_ACP action which the policy grants.",
+ "id": "set-logging-configuration-for-a-bucket-1482269119909",
+ "title": "Set logging configuration for a bucket"
+ }
+ ],
+ "PutBucketNotificationConfiguration": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "NotificationConfiguration": {
+ "TopicConfigurations": [
+ {
+ "Events": [
+ "s3:ObjectCreated:*"
+ ],
+ "TopicArn": "arn:aws:sns:us-west-2:123456789012:s3-notification-topic"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets notification configuration on a bucket to publish the object created events to an SNS topic.",
+ "id": "set-notification-configuration-for-a-bucket-1482270296426",
+ "title": "Set notification configuration for a bucket"
+ }
+ ],
+ "PutBucketPolicy": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Policy": "{\"Version\": \"2012-10-17\", \"Statement\": [{ \"Sid\": \"id-1\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::123456789012:root\"}, \"Action\": [ \"s3:PutObject\",\"s3:PutObjectAcl\"], \"Resource\": [\"arn:aws:s3:::acl3/*\" ] } ]}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets a permission policy on a bucket.",
+ "id": "set-bucket-policy-1482448903302",
+ "title": "Set bucket policy"
+ }
+ ],
+ "PutBucketReplication": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "ReplicationConfiguration": {
+ "Role": "arn:aws:iam::123456789012:role/examplerole",
+ "Rules": [
+ {
+ "Destination": {
+ "Bucket": "arn:aws:s3:::destinationbucket",
+ "StorageClass": "STANDARD"
+ },
+ "Prefix": "",
+ "Status": "Enabled"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets replication configuration on a bucket.",
+ "id": "id-1",
+ "title": "Set replication configuration on a bucket"
+ }
+ ],
+ "PutBucketRequestPayment": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "RequestPaymentConfiguration": {
+ "Payer": "Requester"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets request payment configuration on a bucket so that person requesting the download is charged.",
+ "id": "set-request-payment-configuration-on-a-bucket-1482343596680",
+ "title": "Set request payment configuration on a bucket."
+ }
+ ],
+ "PutBucketTagging": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Tagging": {
+ "TagSet": [
+ {
+ "Key": "Key1",
+ "Value": "Value1"
+ },
+ {
+ "Key": "Key2",
+ "Value": "Value2"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets tags on a bucket. Any existing tags are replaced.",
+ "id": "set-tags-on-a-bucket-1482346269066",
+ "title": "Set tags on a bucket"
+ }
+ ],
+ "PutBucketVersioning": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "VersioningConfiguration": {
+ "MFADelete": "Disabled",
+ "Status": "Enabled"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets versioning configuration on bucket. The configuration enables versioning on the bucket.",
+ "id": "set-versioning-configuration-on-a-bucket-1482344186279",
+ "title": "Set versioning configuration on a bucket"
+ }
+ ],
+ "PutBucketWebsite": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "ContentMD5": "",
+ "WebsiteConfiguration": {
+ "ErrorDocument": {
+ "Key": "error.html"
+ },
+ "IndexDocument": {
+ "Suffix": "index.html"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds website configuration to a bucket.",
+ "id": "set-website-configuration-on-a-bucket-1482346836261",
+ "title": "Set website configuration on a bucket"
+ }
+ ],
+ "PutObject": [
+ {
+ "input": {
+ "Body": "filetoupload",
+ "Bucket": "examplebucket",
+ "Key": "objectkey"
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "VersionId": "Bvq0EDKxOcXLJXNo_Lkz37eM3R4pfzyQ"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an object. If the bucket is versioning enabled, S3 returns version ID in response.",
+ "id": "to-create-an-object-1483147613675",
+ "title": "To create an object."
+ },
+ {
+ "input": {
+ "Body": "HappyFace.jpg",
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg",
+ "ServerSideEncryption": "AES256",
+ "StorageClass": "STANDARD_IA"
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "ServerSideEncryption": "AES256",
+ "VersionId": "CG612hodqujkf8FaaNfp8U..FIhLROcp"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads an object. The request specifies optional request headers to directs S3 to use specific storage class and use server-side encryption.",
+ "id": "to-upload-an-object-(specify-optional-headers)",
+ "title": "To upload an object (specify optional headers)"
+ },
+ {
+ "input": {
+ "ACL": "authenticated-read",
+ "Body": "filetoupload",
+ "Bucket": "examplebucket",
+ "Key": "exampleobject"
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "VersionId": "Kirh.unyZwjQ69YxcQLA8z4F5j3kJJKr"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads and object. The request specifies optional canned ACL (access control list) to all READ access to authenticated users. If the bucket is versioning enabled, S3 returns version ID in response.",
+ "id": "to-upload-an-object-and-specify-canned-acl-1483397779571",
+ "title": "To upload an object and specify canned ACL."
+ },
+ {
+ "input": {
+ "Body": "HappyFace.jpg",
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "VersionId": "tpf3zF08nBplQK1XLOefGskR7mGDwcDk"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads an object to a versioning-enabled bucket. The source file is specified using Windows file syntax. S3 returns VersionId of the newly created object.",
+ "id": "to-upload-an-object-1481760101010",
+ "title": "To upload an object"
+ },
+ {
+ "input": {
+ "Body": "filetoupload",
+ "Bucket": "examplebucket",
+ "Key": "exampleobject",
+ "Metadata": {
+ "metadata1": "value1",
+ "metadata2": "value2"
+ }
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "VersionId": "pSKidl4pHBiNwukdbcPXAIs.sshFFOc0"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an object. The request also specifies optional metadata. If the bucket is versioning enabled, S3 returns version ID in response.",
+ "id": "to-upload-object-and-specify-user-defined-metadata-1483396974757",
+ "title": "To upload object and specify user-defined metadata"
+ },
+ {
+ "input": {
+ "Body": "c:\\HappyFace.jpg",
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg",
+ "Tagging": "key1=value1&key2=value2"
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "VersionId": "psM2sYY4.o1501dSx8wMvnkOzSBB.V4a"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads an object. The request specifies optional object tags. The bucket is versioned, therefore S3 returns version ID of the newly created object.",
+ "id": "to-upload-an-object-and-specify-optional-tags-1481762310955",
+ "title": "To upload an object and specify optional tags"
+ },
+ {
+ "input": {
+ "Body": "filetoupload",
+ "Bucket": "examplebucket",
+ "Key": "exampleobject",
+ "ServerSideEncryption": "AES256",
+ "Tagging": "key1=value1&key2=value2"
+ },
+ "output": {
+ "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"",
+ "ServerSideEncryption": "AES256",
+ "VersionId": "Ri.vC6qVlA4dEnjgRV4ZHsHoFIjqEMNt"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads and object. The request specifies the optional server-side encryption option. The request also specifies optional object tags. If the bucket is versioning enabled, S3 returns version ID in response.",
+ "id": "to-upload-an-object-and-specify-server-side-encryption-and-object-tags-1483398331831",
+ "title": "To upload an object and specify server-side encryption and object tags"
+ }
+ ],
+ "PutObjectAcl": [
+ {
+ "input": {
+ "AccessControlPolicy": {
+ },
+ "Bucket": "examplebucket",
+ "GrantFullControl": "emailaddress=user1@example.com,emailaddress=user2@example.com",
+ "GrantRead": "uri=http://acs.amazonaws.com/groups/global/AllUsers",
+ "Key": "HappyFace.jpg"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds grants to an object ACL. The first permission grants user1 and user2 FULL_CONTROL and the AllUsers group READ permission.",
+ "id": "to-grant-permissions-using-object-acl-1481835549285",
+ "title": "To grant permissions using object ACL"
+ }
+ ],
+ "PutObjectTagging": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "HappyFace.jpg",
+ "Tagging": {
+ "TagSet": [
+ {
+ "Key": "Key3",
+ "Value": "Value3"
+ },
+ {
+ "Key": "Key4",
+ "Value": "Value4"
+ }
+ ]
+ }
+ },
+ "output": {
+ "VersionId": "null"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds tags to an existing object.",
+ "id": "to-add-tags-to-an-existing-object-1481764668793",
+ "title": "To add tags to an existing object"
+ }
+ ],
+ "RestoreObject": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "Key": "archivedobjectkey",
+ "RestoreRequest": {
+ "Days": 1,
+ "GlacierJobParameters": {
+ "Tier": "Expedited"
+ }
+ }
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example restores for one day an archived copy of an object back into Amazon S3 bucket.",
+ "id": "to-restore-an-archived-object-1483049329953",
+ "title": "To restore an archived object"
+ }
+ ],
+ "UploadPart": [
+ {
+ "input": {
+ "Body": "fileToUpload",
+ "Bucket": "examplebucket",
+ "Key": "examplelargeobject",
+ "PartNumber": "1",
+ "UploadId": "xadcOB_7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--"
+ },
+ "output": {
+ "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\""
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads part 1 of a multipart upload. The example specifies a file name for the part data. The Upload ID is same that is returned by the initiate multipart upload.",
+ "id": "to-upload-a-part-1481847914943",
+ "title": "To upload a part"
+ }
+ ],
+ "UploadPartCopy": [
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "CopySource": "/bucketname/sourceobjectkey",
+ "Key": "examplelargeobject",
+ "PartNumber": "1",
+ "UploadId": "exampleuoh_10OhKhT7YukE9bjzTPRiuaCotmZM_pFngJFir9OZNrSr5cWa3cq3LZSUsfjI4FI7PkP91We7Nrw--"
+ },
+ "output": {
+ "CopyPartResult": {
+ "ETag": "\"b0c6f0e7e054ab8fa2536a2677f8734d\"",
+ "LastModified": "2016-12-29T21:24:43.000Z"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads a part of a multipart upload by copying data from an existing object as data source.",
+ "id": "to-upload-a-part-by-copying-data-from-an-existing-object-as-data-source-1483046746348",
+ "title": "To upload a part by copying data from an existing object as data source"
+ },
+ {
+ "input": {
+ "Bucket": "examplebucket",
+ "CopySource": "/bucketname/sourceobjectkey",
+ "CopySourceRange": "bytes=1-100000",
+ "Key": "examplelargeobject",
+ "PartNumber": "2",
+ "UploadId": "exampleuoh_10OhKhT7YukE9bjzTPRiuaCotmZM_pFngJFir9OZNrSr5cWa3cq3LZSUsfjI4FI7PkP91We7Nrw--"
+ },
+ "output": {
+ "CopyPartResult": {
+ "ETag": "\"65d16d19e65a7508a51f043180edcc36\"",
+ "LastModified": "2016-12-29T21:44:28.000Z"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example uploads a part of a multipart upload by copying a specified byte range from an existing object as data source.",
+ "id": "to-upload-a-part-by-copying-byte-range-from-an-existing-object-as-data-source-1483048068594",
+ "title": "To upload a part by copying byte range from an existing object as data source"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/paginators-1.json
new file mode 100644
index 0000000000..1f061380f3
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/paginators-1.json
@@ -0,0 +1,64 @@
+{
+ "pagination": {
+ "ListMultipartUploads": {
+ "limit_key": "MaxUploads",
+ "more_results": "IsTruncated",
+ "output_token": [
+ "NextKeyMarker",
+ "NextUploadIdMarker"
+ ],
+ "input_token": [
+ "KeyMarker",
+ "UploadIdMarker"
+ ],
+ "result_key": [
+ "Uploads",
+ "CommonPrefixes"
+ ]
+ },
+ "ListObjectVersions": {
+ "more_results": "IsTruncated",
+ "limit_key": "MaxKeys",
+ "output_token": [
+ "NextKeyMarker",
+ "NextVersionIdMarker"
+ ],
+ "input_token": [
+ "KeyMarker",
+ "VersionIdMarker"
+ ],
+ "result_key": [
+ "Versions",
+ "DeleteMarkers",
+ "CommonPrefixes"
+ ]
+ },
+ "ListObjects": {
+ "more_results": "IsTruncated",
+ "limit_key": "MaxKeys",
+ "output_token": "NextMarker || Contents[-1].Key",
+ "input_token": "Marker",
+ "result_key": [
+ "Contents",
+ "CommonPrefixes"
+ ]
+ },
+ "ListObjectsV2": {
+ "more_results": "IsTruncated",
+ "limit_key": "MaxKeys",
+ "output_token": "NextContinuationToken",
+ "input_token": "ContinuationToken",
+ "result_key": [
+ "Contents",
+ "CommonPrefixes"
+ ]
+ },
+ "ListParts": {
+ "more_results": "IsTruncated",
+ "limit_key": "MaxParts",
+ "output_token": "NextPartNumberMarker",
+ "input_token": "PartNumberMarker",
+ "result_key": "Parts"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..67a92132a7
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/paginators-1.sdk-extras.json
@@ -0,0 +1,35 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "ListMultipartUploads": {
+ "non_aggregate_keys": [
+ "RequestCharged"
+ ]
+ },
+ "ListObjectVersions": {
+ "non_aggregate_keys": [
+ "RequestCharged"
+ ]
+ },
+ "ListObjects": {
+ "non_aggregate_keys": [
+ "RequestCharged"
+ ]
+ },
+ "ListObjectsV2": {
+ "non_aggregate_keys": [
+ "RequestCharged"
+ ]
+ },
+ "ListParts": {
+ "non_aggregate_keys": [
+ "ChecksumAlgorithm",
+ "Initiator",
+ "Owner",
+ "StorageClass"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/service-2.json.gz
new file mode 100644
index 0000000000..30b5e87d3b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/waiters-2.json
new file mode 100644
index 0000000000..b508a8f5b0
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3/2006-03-01/waiters-2.json
@@ -0,0 +1,73 @@
+{
+ "version": 2,
+ "waiters": {
+ "BucketExists": {
+ "delay": 5,
+ "operation": "HeadBucket",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": 200,
+ "matcher": "status",
+ "state": "success"
+ },
+ {
+ "expected": 301,
+ "matcher": "status",
+ "state": "success"
+ },
+ {
+ "expected": 403,
+ "matcher": "status",
+ "state": "success"
+ },
+ {
+ "expected": 404,
+ "matcher": "status",
+ "state": "retry"
+ }
+ ]
+ },
+ "BucketNotExists": {
+ "delay": 5,
+ "operation": "HeadBucket",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": 404,
+ "matcher": "status",
+ "state": "success"
+ }
+ ]
+ },
+ "ObjectExists": {
+ "delay": 5,
+ "operation": "HeadObject",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": 200,
+ "matcher": "status",
+ "state": "success"
+ },
+ {
+ "expected": 404,
+ "matcher": "status",
+ "state": "retry"
+ }
+ ]
+ },
+ "ObjectNotExists": {
+ "delay": 5,
+ "operation": "HeadObject",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": 404,
+ "matcher": "status",
+ "state": "success"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..7ba0159904
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/paginators-1.json
new file mode 100644
index 0000000000..873eb23bcf
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListAccessPointsForObjectLambda": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ObjectLambdaAccessPointList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/service-2.json.gz
new file mode 100644
index 0000000000..e4877155be
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3control/2018-08-20/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..781286713c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/paginators-1.json
new file mode 100644
index 0000000000..5a8fa86cc7
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListEndpoints": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Endpoints"
+ },
+ "ListSharedEndpoints": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Endpoints"
+ },
+ "ListOutpostsWithS3": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Outposts"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/service-2.json.gz
new file mode 100644
index 0000000000..c2154f5b22
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/s3outposts/2017-07-25/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..ed40896918
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/paginators-1.json
new file mode 100644
index 0000000000..b19128c262
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListHumanLoops": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "HumanLoopSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/service-2.json.gz
new file mode 100644
index 0000000000..f670d265ff
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-a2i-runtime/2019-11-07/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5256063578
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/service-2.json.gz
new file mode 100644
index 0000000000..adc70fea4e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-edge/2020-09-23/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4a97b5fef1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/service-2.json.gz
new file mode 100644
index 0000000000..4a139c08e5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-featurestore-runtime/2020-07-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..c707d16b0d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/paginators-1.json
new file mode 100644
index 0000000000..8802d9431c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListEarthObservationJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EarthObservationJobSummaries"
+ },
+ "ListRasterDataCollections": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "RasterDataCollectionSummaries"
+ },
+ "ListVectorEnrichmentJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "VectorEnrichmentJobSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/service-2.json.gz
new file mode 100644
index 0000000000..77e108fedc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-geospatial/2020-05-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5ceebe09e3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/service-2.json.gz
new file mode 100644
index 0000000000..4b06a418f7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-metrics/2022-09-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..998f4efe2f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/service-2.json.gz
new file mode 100644
index 0000000000..4e7489674c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker-runtime/2017-05-13/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..995cac0dae
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/paginators-1.json
new file mode 100644
index 0000000000..c7af276317
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/paginators-1.json
@@ -0,0 +1,418 @@
+{
+ "pagination": {
+ "ListTrainingJobs": {
+ "result_key": "TrainingJobSummaries",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListEndpoints": {
+ "result_key": "Endpoints",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListEndpointConfigs": {
+ "result_key": "EndpointConfigs",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListNotebookInstances": {
+ "result_key": "NotebookInstances",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListTags": {
+ "result_key": "Tags",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListModels": {
+ "result_key": "Models",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListAlgorithms": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AlgorithmSummaryList"
+ },
+ "ListCodeRepositories": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CodeRepositorySummaryList"
+ },
+ "ListCompilationJobs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CompilationJobSummaries"
+ },
+ "ListHyperParameterTuningJobs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "HyperParameterTuningJobSummaries"
+ },
+ "ListLabelingJobs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LabelingJobSummaryList"
+ },
+ "ListLabelingJobsForWorkteam": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LabelingJobSummaryList"
+ },
+ "ListModelPackages": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ModelPackageSummaryList"
+ },
+ "ListNotebookInstanceLifecycleConfigs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "NotebookInstanceLifecycleConfigs"
+ },
+ "ListSubscribedWorkteams": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "SubscribedWorkteams"
+ },
+ "ListTrainingJobsForHyperParameterTuningJob": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "TrainingJobSummaries"
+ },
+ "ListTransformJobs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "TransformJobSummaries"
+ },
+ "ListWorkteams": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Workteams"
+ },
+ "Search": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Results"
+ },
+ "ListApps": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Apps"
+ },
+ "ListAutoMLJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AutoMLJobSummaries"
+ },
+ "ListCandidatesForAutoMLJob": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Candidates"
+ },
+ "ListDomains": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Domains"
+ },
+ "ListExperiments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ExperimentSummaries"
+ },
+ "ListFlowDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FlowDefinitionSummaries"
+ },
+ "ListHumanTaskUis": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "HumanTaskUiSummaries"
+ },
+ "ListMonitoringExecutions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MonitoringExecutionSummaries"
+ },
+ "ListMonitoringSchedules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MonitoringScheduleSummaries"
+ },
+ "ListProcessingJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ProcessingJobSummaries"
+ },
+ "ListTrialComponents": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TrialComponentSummaries"
+ },
+ "ListTrials": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TrialSummaries"
+ },
+ "ListUserProfiles": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "UserProfiles"
+ },
+ "ListWorkforces": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Workforces"
+ },
+ "ListImageVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ImageVersions"
+ },
+ "ListImages": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Images"
+ },
+ "ListActions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ActionSummaries"
+ },
+ "ListAppImageConfigs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AppImageConfigs"
+ },
+ "ListArtifacts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ArtifactSummaries"
+ },
+ "ListAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AssociationSummaries"
+ },
+ "ListContexts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ContextSummaries"
+ },
+ "ListFeatureGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FeatureGroupSummaries"
+ },
+ "ListModelPackageGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ModelPackageGroupSummaryList"
+ },
+ "ListPipelineExecutionSteps": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PipelineExecutionSteps"
+ },
+ "ListPipelineExecutions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PipelineExecutionSummaries"
+ },
+ "ListPipelineParametersForExecution": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PipelineParameters"
+ },
+ "ListPipelines": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "PipelineSummaries"
+ },
+ "ListDataQualityJobDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobDefinitionSummaries"
+ },
+ "ListDeviceFleets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DeviceFleetSummaries"
+ },
+ "ListDevices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DeviceSummaries"
+ },
+ "ListEdgePackagingJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EdgePackagingJobSummaries"
+ },
+ "ListModelBiasJobDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobDefinitionSummaries"
+ },
+ "ListModelExplainabilityJobDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobDefinitionSummaries"
+ },
+ "ListModelQualityJobDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobDefinitionSummaries"
+ },
+ "ListStudioLifecycleConfigs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "StudioLifecycleConfigs"
+ },
+ "ListInferenceRecommendationsJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InferenceRecommendationsJobs"
+ },
+ "ListLineageGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "LineageGroupSummaries"
+ },
+ "ListModelMetadata": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ModelMetadataSummaries"
+ },
+ "ListEdgeDeploymentPlans": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "EdgeDeploymentPlanSummaries"
+ },
+ "ListStageDevices": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DeviceDeploymentSummaries"
+ },
+ "ListInferenceRecommendationsJobSteps": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Steps"
+ },
+ "ListInferenceExperiments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InferenceExperiments"
+ },
+ "ListModelCardExportJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ModelCardExportJobSummaries"
+ },
+ "ListModelCardVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ModelCardVersionSummaryList"
+ },
+ "ListModelCards": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ModelCardSummaries"
+ },
+ "ListMonitoringAlertHistory": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MonitoringAlertHistory"
+ },
+ "ListMonitoringAlerts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "MonitoringAlertSummaries"
+ },
+ "ListSpaces": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Spaces"
+ },
+ "ListAliases": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "SageMakerImageVersionAliases"
+ },
+ "ListResourceCatalogs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ResourceCatalogs"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/service-2.json.gz
new file mode 100644
index 0000000000..52de3a07a7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/waiters-2.json
new file mode 100644
index 0000000000..8677924da1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sagemaker/2017-07-24/waiters-2.json
@@ -0,0 +1,311 @@
+{
+ "version": 2,
+ "waiters": {
+ "NotebookInstanceInService": {
+ "delay": 30,
+ "maxAttempts": 60,
+ "operation": "DescribeNotebookInstance",
+ "acceptors": [
+ {
+ "expected": "InService",
+ "matcher": "path",
+ "state": "success",
+ "argument": "NotebookInstanceStatus"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "NotebookInstanceStatus"
+ }
+ ]
+ },
+ "NotebookInstanceStopped": {
+ "delay": 30,
+ "operation": "DescribeNotebookInstance",
+ "maxAttempts": 60,
+ "acceptors": [
+ {
+ "expected": "Stopped",
+ "matcher": "path",
+ "state": "success",
+ "argument": "NotebookInstanceStatus"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "NotebookInstanceStatus"
+ }
+ ]
+ },
+ "NotebookInstanceDeleted": {
+ "delay": 30,
+ "maxAttempts": 60,
+ "operation": "DescribeNotebookInstance",
+ "acceptors": [
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "NotebookInstanceStatus"
+ }
+ ]
+ },
+ "TrainingJobCompletedOrStopped": {
+ "delay": 120,
+ "maxAttempts": 180,
+ "operation": "DescribeTrainingJob",
+ "acceptors": [
+ {
+ "expected": "Completed",
+ "matcher": "path",
+ "state": "success",
+ "argument": "TrainingJobStatus"
+ },
+ {
+ "expected": "Stopped",
+ "matcher": "path",
+ "state": "success",
+ "argument": "TrainingJobStatus"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "TrainingJobStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "EndpointInService": {
+ "delay": 30,
+ "maxAttempts": 120,
+ "operation": "DescribeEndpoint",
+ "acceptors": [
+ {
+ "expected": "InService",
+ "matcher": "path",
+ "state": "success",
+ "argument": "EndpointStatus"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "EndpointStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "EndpointDeleted": {
+ "delay": 30,
+ "maxAttempts": 60,
+ "operation": "DescribeEndpoint",
+ "acceptors": [
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "EndpointStatus"
+ }
+ ]
+ },
+ "TransformJobCompletedOrStopped": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeTransformJob",
+ "acceptors": [
+ {
+ "expected": "Completed",
+ "matcher": "path",
+ "state": "success",
+ "argument": "TransformJobStatus"
+ },
+ {
+ "expected": "Stopped",
+ "matcher": "path",
+ "state": "success",
+ "argument": "TransformJobStatus"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "TransformJobStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "ProcessingJobCompletedOrStopped": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeProcessingJob",
+ "acceptors": [
+ {
+ "expected": "Completed",
+ "matcher": "path",
+ "state": "success",
+ "argument": "ProcessingJobStatus"
+ },
+ {
+ "expected": "Stopped",
+ "matcher": "path",
+ "state": "success",
+ "argument": "ProcessingJobStatus"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "ProcessingJobStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "ImageCreated": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeImage",
+ "acceptors": [
+ {
+ "expected": "CREATED",
+ "matcher": "path",
+ "state": "success",
+ "argument": "ImageStatus"
+ },
+ {
+ "expected": "CREATE_FAILED",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "ImageStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "ImageUpdated": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeImage",
+ "acceptors": [
+ {
+ "expected": "CREATED",
+ "matcher": "path",
+ "state": "success",
+ "argument": "ImageStatus"
+ },
+ {
+ "expected": "UPDATE_FAILED",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "ImageStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "ImageDeleted": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeImage",
+ "acceptors": [
+ {
+ "expected": "ResourceNotFoundException",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "DELETE_FAILED",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "ImageStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "ImageVersionCreated": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeImageVersion",
+ "acceptors": [
+ {
+ "expected": "CREATED",
+ "matcher": "path",
+ "state": "success",
+ "argument": "ImageVersionStatus"
+ },
+ {
+ "expected": "CREATE_FAILED",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "ImageVersionStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ },
+ "ImageVersionDeleted": {
+ "delay": 60,
+ "maxAttempts": 60,
+ "operation": "DescribeImageVersion",
+ "acceptors": [
+ {
+ "expected": "ResourceNotFoundException",
+ "matcher": "error",
+ "state": "success"
+ },
+ {
+ "expected": "DELETE_FAILED",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "ImageVersionStatus"
+ },
+ {
+ "expected": "ValidationException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0f53220fff
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/service-2.json.gz
new file mode 100644
index 0000000000..2ab67aef31
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/savingsplans/2019-06-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5f289a662a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/paginators-1.json
new file mode 100644
index 0000000000..93b98ee2e0
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListScheduleGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ScheduleGroups"
+ },
+ "ListSchedules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Schedules"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/service-2.json.gz
new file mode 100644
index 0000000000..9f3ced984d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/scheduler/2021-06-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..541c450532
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/paginators-1.json
new file mode 100644
index 0000000000..ef2fe19d19
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListDiscoverers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "Limit",
+ "result_key": "Discoverers"
+ },
+ "ListRegistries": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "Limit",
+ "result_key": "Registries"
+ },
+ "ListSchemaVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "Limit",
+ "result_key": "SchemaVersions"
+ },
+ "ListSchemas": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "Limit",
+ "result_key": "Schemas"
+ },
+ "SearchSchemas": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "Limit",
+ "result_key": "Schemas"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/service-2.json.gz
new file mode 100644
index 0000000000..d97d6288d5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/waiters-2.json
new file mode 100644
index 0000000000..4f642f615c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/schemas/2019-12-02/waiters-2.json
@@ -0,0 +1,36 @@
+{
+ "version": 2,
+ "waiters": {
+ "CodeBindingExists": {
+ "description": "Wait until code binding is generated",
+ "delay": 2,
+ "operation": "DescribeCodeBinding",
+ "maxAttempts": 30,
+ "acceptors": [
+ {
+ "expected": "CREATE_COMPLETE",
+ "matcher": "path",
+ "state": "success",
+ "argument": "Status"
+ },
+ {
+ "expected": "CREATE_IN_PROGRESS",
+ "matcher": "path",
+ "state": "retry",
+ "argument": "Status"
+ },
+ {
+ "expected": "CREATE_FAILED",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "Status"
+ },
+ {
+ "matcher": "error",
+ "expected": "NotFoundException",
+ "state": "failure"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2716bee184
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/paginators-1.json
new file mode 100644
index 0000000000..2362098870
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/paginators-1.json
@@ -0,0 +1,15 @@
+{
+ "pagination": {
+ "ListDomains": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxNumberOfDomains",
+ "result_key": "DomainNames"
+ },
+ "Select": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/service-2.json.gz
new file mode 100644
index 0000000000..7a68dd0f40
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdb/2009-04-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdk-default-configuration.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdk-default-configuration.json
new file mode 100644
index 0000000000..3db13b26cc
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sdk-default-configuration.json
@@ -0,0 +1,55 @@
+{
+ "version": 1,
+ "base": {
+ "retryMode": "standard",
+ "stsRegionalEndpoints": "regional",
+ "s3UsEast1RegionalEndpoints": "regional",
+ "connectTimeoutInMillis": 1100,
+ "tlsNegotiationTimeoutInMillis": 1100
+ },
+ "modes": {
+ "standard": {
+ "connectTimeoutInMillis": {
+ "override": 3100
+ },
+ "tlsNegotiationTimeoutInMillis": {
+ "override": 3100
+ }
+ },
+ "in-region": {
+ },
+ "cross-region": {
+ "connectTimeoutInMillis": {
+ "override": 3100
+ },
+ "tlsNegotiationTimeoutInMillis": {
+ "override": 3100
+ }
+ },
+ "mobile": {
+ "connectTimeoutInMillis": {
+ "override": 30000
+ },
+ "tlsNegotiationTimeoutInMillis": {
+ "override": 30000
+ }
+ }
+ },
+ "documentation": {
+ "modes": {
+ "standard": "The STANDARD mode provides the latest recommended default values that should be safe to run in most scenarios
Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK
",
+ "in-region": "The IN_REGION mode builds on the standard mode and includes optimization tailored for applications which call AWS services from within the same AWS region
Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK
",
+ "cross-region": "The CROSS_REGION mode builds on the standard mode and includes optimization tailored for applications which call AWS services in a different region
Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK
",
+ "mobile": "The MOBILE mode builds on the standard mode and includes optimization tailored for mobile applications
Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK
",
+ "auto": "The AUTO mode is an experimental mode that builds on the standard mode. The SDK will attempt to discover the execution environment to determine the appropriate settings automatically.
Note that the auto detection is heuristics-based and does not guarantee 100% accuracy. STANDARD mode will be used if the execution environment cannot be determined. The auto detection might query EC2 Instance Metadata service, which might introduce latency. Therefore we recommend choosing an explicit defaults_mode instead if startup latency is critical to your application
",
+ "legacy": "The LEGACY mode provides default settings that vary per SDK and were used prior to establishment of defaults_mode
"
+ },
+ "configuration": {
+ "retryMode": "A retry mode specifies how the SDK attempts retries. See Retry Mode
",
+ "stsRegionalEndpoints": "Specifies how the SDK determines the AWS service endpoint that it uses to talk to the AWS Security Token Service (AWS STS). See Setting STS Regional endpoints
",
+ "s3UsEast1RegionalEndpoints": "Specifies how the SDK determines the AWS service endpoint that it uses to talk to the Amazon S3 for the us-east-1 region
",
+ "connectTimeoutInMillis": "The amount of time after making an initial connection attempt on a socket, where if the client does not receive a completion of the connect handshake, the client gives up and fails the operation
",
+ "tlsNegotiationTimeoutInMillis": "The maximum amount of time that a TLS handshake is allowed to take from the time the CLIENT HELLO message is sent to ethe time the client and server have fully negotiated ciphers and exchanged keys
"
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0825367092
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/examples-1.json
new file mode 100644
index 0000000000..43a3ec4fd4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/examples-1.json
@@ -0,0 +1,596 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CancelRotateSecret": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "Name"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to cancel rotation for a secret. The operation sets the RotationEnabled field to false and cancels all scheduled rotations. To resume scheduled rotations, you must re-enable rotation by calling the rotate-secret operation.",
+ "id": "to-cancel-scheduled-rotation-for-a-secret-1523996016032",
+ "title": "To cancel scheduled rotation for a secret"
+ }
+ ],
+ "CreateSecret": [
+ {
+ "input": {
+ "ClientRequestToken": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1",
+ "Description": "My test database secret created with the CLI",
+ "Name": "MyTestDatabaseSecret",
+ "SecretString": "{\"username\":\"david\",\"password\":\"EXAMPLE-PASSWORD\"}"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to create a secret. The credentials stored in the encrypted secret value are retrieved from a file on disk named mycreds.json.",
+ "id": "to-create-a-basic-secret-1523996473658",
+ "title": "To create a basic secret"
+ }
+ ],
+ "DeleteResourcePolicy": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseMasterSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to delete the resource-based policy that is attached to a secret.",
+ "id": "to-delete-the-resource-based-policy-attached-to-a-secret-1530209419204",
+ "title": "To delete the resource-based policy attached to a secret"
+ }
+ ],
+ "DeleteSecret": [
+ {
+ "input": {
+ "RecoveryWindowInDays": 7,
+ "SecretId": "MyTestDatabaseSecret1"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "DeletionDate": "1524085349.095",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to delete a secret. The secret stays in your account in a deprecated and inaccessible state until the recovery window ends. After the date and time in the DeletionDate response field has passed, you can no longer recover this secret with restore-secret.",
+ "id": "to-delete-a-secret-1523996905092",
+ "title": "To delete a secret"
+ }
+ ],
+ "DescribeSecret": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Description": "My test database secret",
+ "KmsKeyId": "arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987KMSKEY1",
+ "LastAccessedDate": "1523923200",
+ "LastChangedDate": 1523477145.729,
+ "LastRotatedDate": 1525747253.72,
+ "Name": "MyTestDatabaseSecret",
+ "RotationEnabled": true,
+ "RotationLambdaARN": "arn:aws:lambda:us-west-2:123456789012:function:MyTestRotationLambda",
+ "RotationRules": {
+ "AutomaticallyAfterDays": 14,
+ "Duration": "2h",
+ "ScheduleExpression": "cron(0 16 1,15 * ? *)"
+ },
+ "Tags": [
+ {
+ "Key": "SecondTag",
+ "Value": "AnotherValue"
+ },
+ {
+ "Key": "FirstTag",
+ "Value": "SomeValue"
+ }
+ ],
+ "VersionIdsToStages": {
+ "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE": [
+ "AWSPREVIOUS"
+ ],
+ "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE": [
+ "AWSCURRENT"
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to get the details about a secret.",
+ "id": "to-retrieve-the-details-of-a-secret-1524000138629",
+ "title": "To retrieve the details of a secret"
+ }
+ ],
+ "GetRandomPassword": [
+ {
+ "input": {
+ "IncludeSpace": true,
+ "PasswordLength": 20,
+ "RequireEachIncludedType": true
+ },
+ "output": {
+ "RandomPassword": "EXAMPLE-PASSWORD"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to request a randomly generated password. This example includes the optional flags to require spaces and at least one character of each included type. It specifies a length of 20 characters.",
+ "id": "to-generate-a-random-password-1524000546092",
+ "title": "To generate a random password"
+ }
+ ],
+ "GetResourcePolicy": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "ResourcePolicy": "{\n\"Version\":\"2012-10-17\",\n\"Statement\":[{\n\"Effect\":\"Allow\",\n\"Principal\":{\n\"AWS\":\"arn:aws:iam::123456789012:root\"\n},\n\"Action\":\"secretsmanager:GetSecretValue\",\n\"Resource\":\"*\"\n}]\n}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to retrieve the resource-based policy that is attached to a secret.",
+ "id": "to-retrieve-the-resource-based-policy-attached-to-a-secret-1530209677536",
+ "title": "To retrieve the resource-based policy attached to a secret"
+ }
+ ],
+ "GetSecretValue": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "CreatedDate": 1523477145.713,
+ "Name": "MyTestDatabaseSecret",
+ "SecretString": "{\n \"username\":\"david\",\n \"password\":\"EXAMPLE-PASSWORD\"\n}\n",
+ "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1",
+ "VersionStages": [
+ "AWSPREVIOUS"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to retrieve a secret string value.",
+ "id": "to-retrieve-the-encrypted-secret-value-of-a-secret-1524000702484",
+ "title": "To retrieve the encrypted secret value of a secret"
+ }
+ ],
+ "ListSecretVersionIds": [
+ {
+ "input": {
+ "IncludeDeprecated": true,
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "Versions": [
+ {
+ "CreatedDate": 1523477145.713,
+ "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE",
+ "VersionStages": [
+ "AWSPREVIOUS"
+ ]
+ },
+ {
+ "CreatedDate": 1523486221.391,
+ "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE",
+ "VersionStages": [
+ "AWSCURRENT"
+ ]
+ },
+ {
+ "CreatedDate": 1511974462.36,
+ "VersionId": "EXAMPLE3-90ab-cdef-fedc-ba987EXAMPLE;"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to retrieve a list of all of the versions of a secret, including those without any staging labels.",
+ "id": "to-list-all-of-the-secret-versions-associated-with-a-secret-1524000999164",
+ "title": "To list all of the secret versions associated with a secret"
+ }
+ ],
+ "ListSecrets": [
+ {
+ "input": {
+ },
+ "output": {
+ "SecretList": [
+ {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Description": "My test database secret",
+ "LastChangedDate": 1523477145.729,
+ "Name": "MyTestDatabaseSecret",
+ "SecretVersionsToStages": {
+ "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE": [
+ "AWSCURRENT"
+ ]
+ }
+ },
+ {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret1-d4e5f6",
+ "Description": "Another secret created for a different database",
+ "LastChangedDate": 1523482025.685,
+ "Name": "MyTestDatabaseSecret1",
+ "SecretVersionsToStages": {
+ "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE": [
+ "AWSCURRENT"
+ ]
+ }
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to list all of the secrets in your account.",
+ "id": "to-list-the-secrets-in-your-account-1524001246087",
+ "title": "To list the secrets in your account"
+ }
+ ],
+ "PutResourcePolicy": [
+ {
+ "input": {
+ "ResourcePolicy": "{\n\"Version\":\"2012-10-17\",\n\"Statement\":[{\n\"Effect\":\"Allow\",\n\"Principal\":{\n\"AWS\":\"arn:aws:iam::123456789012:root\"\n},\n\"Action\":\"secretsmanager:GetSecretValue\",\n\"Resource\":\"*\"\n}]\n}",
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to add a resource-based policy to a secret.",
+ "id": "to-add-a-resource-based-policy-to-a-secret-1530209881839",
+ "title": "To add a resource-based policy to a secret"
+ }
+ ],
+ "PutSecretValue": [
+ {
+ "input": {
+ "ClientRequestToken": "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE",
+ "SecretId": "MyTestDatabaseSecret",
+ "SecretString": "{\"username\":\"david\",\"password\":\"EXAMPLE-PASSWORD\"}"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE",
+ "VersionStages": [
+ "AWSCURRENT"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to create a new version of the secret. Alternatively, you can use the update-secret command.",
+ "id": "to-store-a-secret-value-in-a-new-version-of-a-secret-1524001393971",
+ "title": "To store a secret value in a new version of a secret"
+ }
+ ],
+ "RestoreSecret": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to restore a secret that you previously scheduled for deletion.",
+ "id": "to-restore-a-previously-deleted-secret-1524001513930",
+ "title": "To restore a previously deleted secret"
+ }
+ ],
+ "RotateSecret": [
+ {
+ "input": {
+ "RotationLambdaARN": "arn:aws:lambda:us-west-2:123456789012:function:MyTestDatabaseRotationLambda",
+ "RotationRules": {
+ "Duration": "2h",
+ "ScheduleExpression": "cron(0 16 1,15 * ? *)"
+ },
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example configures rotation for a secret using a cron expression. The first rotation happens immediately after the changes are stored in the secret. The rotation schedule is the first and 15th day of every month. The rotation window begins at 4:00 PM UTC and ends at 6:00 PM.",
+ "id": "to-configure-rotation-for-a-secret-1524001629475",
+ "title": "To configure rotation for a secret"
+ },
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example requests an immediate invocation of the secret's Lambda rotation function. It assumes that the specified secret already has rotation configured. The rotation function runs asynchronously in the background.",
+ "id": "to-request-an-immediate-rotation-for-a-secret-1524001949004",
+ "title": "To request an immediate rotation for a secret"
+ }
+ ],
+ "TagResource": [
+ {
+ "input": {
+ "SecretId": "MyExampleSecret",
+ "Tags": [
+ {
+ "Key": "FirstTag",
+ "Value": "SomeValue"
+ },
+ {
+ "Key": "SecondTag",
+ "Value": "AnotherValue"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to attach two tags each with a Key and Value to a secret. There is no output from this API. To see the result, use the DescribeSecret operation.",
+ "id": "to-add-tags-to-a-secret-1524002106718",
+ "title": "To add tags to a secret"
+ }
+ ],
+ "UntagResource": [
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret",
+ "TagKeys": [
+ "FirstTag",
+ "SecondTag"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to remove two tags from a secret's metadata. For each, both the tag and the associated value are removed. There is no output from this API. To see the result, use the DescribeSecret operation.",
+ "id": "to-remove-tags-from-a-secret-1524002239065",
+ "title": "To remove tags from a secret"
+ }
+ ],
+ "UpdateSecret": [
+ {
+ "input": {
+ "ClientRequestToken": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE",
+ "Description": "This is a new description for the secret.",
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to modify the description of a secret.",
+ "id": "to-update-the-description-of-a-secret-1524002349094",
+ "title": "To update the description of a secret"
+ },
+ {
+ "input": {
+ "KmsKeyId": "arn:aws:kms:us-west-2:123456789012:key/EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE",
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows how to update the KMS customer managed key (CMK) used to encrypt the secret value. The KMS CMK must be in the same region as the secret.",
+ "id": "to-update-the-kms-key-associated-with-a-secret-1524002421563",
+ "title": "To update the KMS key associated with a secret"
+ },
+ {
+ "input": {
+ "SecretId": "MyTestDatabaseSecret",
+ "SecretString": "{JSON STRING WITH CREDENTIALS}"
+ },
+ "output": {
+ "ARN": "aws:arn:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret",
+ "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to create a new version of the secret by updating the SecretString field. Alternatively, you can use the put-secret-value operation.",
+ "id": "to-create-a-new-version-of-the-encrypted-secret-value-1524004651836",
+ "title": "To create a new version of the encrypted secret value"
+ }
+ ],
+ "UpdateSecretVersionStage": [
+ {
+ "input": {
+ "MoveToVersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1",
+ "SecretId": "MyTestDatabaseSecret",
+ "VersionStage": "STAGINGLABEL1"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to add a staging label to a version of a secret. You can review the results by running the operation ListSecretVersionIds and viewing the VersionStages response field for the affected version.",
+ "id": "to-add-a-staging-label-attached-to-a-version-of-a-secret-1524004783841",
+ "title": "To add a staging label attached to a version of a secret"
+ },
+ {
+ "input": {
+ "RemoveFromVersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1",
+ "SecretId": "MyTestDatabaseSecret",
+ "VersionStage": "STAGINGLABEL1"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to delete a staging label that is attached to a version of a secret. You can review the results by running the operation ListSecretVersionIds and viewing the VersionStages response field for the affected version.",
+ "id": "to-delete-a-staging-label-attached-to-a-version-of-a-secret-1524004862181",
+ "title": "To delete a staging label attached to a version of a secret"
+ },
+ {
+ "input": {
+ "MoveToVersionId": "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2",
+ "RemoveFromVersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1",
+ "SecretId": "MyTestDatabaseSecret",
+ "VersionStage": "AWSCURRENT"
+ },
+ "output": {
+ "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
+ "Name": "MyTestDatabaseSecret"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows you how to move a staging label that is attached to one version of a secret to a different version. You can review the results by running the operation ListSecretVersionIds and viewing the VersionStages response field for the affected version.",
+ "id": "to-move-a-staging-label-from-one-version-of-a-secret-to-another-1524004963841",
+ "title": "To move a staging label from one version of a secret to another"
+ }
+ ],
+ "ValidateResourcePolicy": [
+ {
+ "input": {
+ "ResourcePolicy": "{\n\"Version\":\"2012-10-17\",\n\"Statement\":[{\n\"Effect\":\"Allow\",\n\"Principal\":{\n\"AWS\":\"arn:aws:iam::123456789012:root\"\n},\n\"Action\":\"secretsmanager:GetSecretValue\",\n\"Resource\":\"*\"\n}]\n}",
+ "SecretId": "MyTestDatabaseSecret"
+ },
+ "output": {
+ "PolicyValidationPassed": true,
+ "ValidationErrors": [
+
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows how to validate a resource-based policy to a secret.",
+ "id": "to-validate-the-resource-policy-of-a-secret-1524000138629",
+ "title": "To validate a resource-based policy to a secret"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/paginators-1.json
new file mode 100644
index 0000000000..0f62e8e1d1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListSecrets": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "SecretList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/service-2.json.gz
new file mode 100644
index 0000000000..8d01a3d48b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/service-2.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/service-2.sdk-extras.json
new file mode 100644
index 0000000000..dc78f8922c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/secretsmanager/2017-10-17/service-2.sdk-extras.json
@@ -0,0 +1,8 @@
+{
+ "version": 1.0,
+ "merge": {
+ "metadata": {
+ "serviceId": "Secrets Manager"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..7615df57da
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/paginators-1.json
new file mode 100644
index 0000000000..0ee879dd24
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/paginators-1.json
@@ -0,0 +1,94 @@
+{
+ "pagination": {
+ "GetEnabledStandards": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "StandardsSubscriptions"
+ },
+ "GetFindings": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Findings"
+ },
+ "GetInsights": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Insights"
+ },
+ "ListEnabledProductsForImport": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ProductSubscriptions"
+ },
+ "ListInvitations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Invitations"
+ },
+ "ListMembers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Members"
+ },
+ "DescribeActionTargets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ActionTargets"
+ },
+ "DescribeProducts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Products"
+ },
+ "DescribeStandards": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Standards"
+ },
+ "DescribeStandardsControls": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Controls"
+ },
+ "ListOrganizationAdminAccounts": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AdminAccounts"
+ },
+ "ListFindingAggregators": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FindingAggregators"
+ },
+ "ListSecurityControlDefinitions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "SecurityControlDefinitions"
+ },
+ "ListStandardsControlAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "StandardsControlAssociationSummaries"
+ },
+ "GetFindingHistory": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Records"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/service-2.json.gz
new file mode 100644
index 0000000000..9cd73eb066
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securityhub/2018-10-26/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..c3633c951d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..19e482b211
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "GetDataLakeSources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "dataLakeSources"
+ },
+ "ListDataLakeExceptions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "exceptions"
+ },
+ "ListLogSources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "sources"
+ },
+ "ListSubscribers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "subscribers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/paginators-1.sdk-extras.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/paginators-1.sdk-extras.json
new file mode 100644
index 0000000000..41ae7fe618
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/paginators-1.sdk-extras.json
@@ -0,0 +1,12 @@
+{
+ "version": 1.0,
+ "merge": {
+ "pagination": {
+ "GetDataLakeSources": {
+ "non_aggregate_keys": [
+ "dataLakeArn"
+ ]
+ }
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..115d15f17a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/securitylake/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..55051b7660
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/paginators-1.json
new file mode 100644
index 0000000000..a39e547796
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListApplicationDependencies": {
+ "input_token": "NextToken",
+ "limit_key": "MaxItems",
+ "output_token": "NextToken",
+ "result_key": "Dependencies"
+ },
+ "ListApplicationVersions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxItems",
+ "output_token": "NextToken",
+ "result_key": "Versions"
+ },
+ "ListApplications": {
+ "input_token": "NextToken",
+ "limit_key": "MaxItems",
+ "output_token": "NextToken",
+ "result_key": "Applications"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/service-2.json.gz
new file mode 100644
index 0000000000..a296f82ef8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/serverlessrepo/2017-09-08/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..1b2ae7f8ea
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/paginators-1.json
new file mode 100644
index 0000000000..e0d4547601
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "ListAWSDefaultServiceQuotas": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Quotas"
+ },
+ "ListRequestedServiceQuotaChangeHistory": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "RequestedQuotas"
+ },
+ "ListRequestedServiceQuotaChangeHistoryByQuota": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "RequestedQuotas"
+ },
+ "ListServiceQuotaIncreaseRequestsInTemplate": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ServiceQuotaIncreaseRequestInTemplateList"
+ },
+ "ListServiceQuotas": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Quotas"
+ },
+ "ListServices": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Services"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/service-2.json.gz
new file mode 100644
index 0000000000..382f41bdb6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/service-quotas/2019-06-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..811b29eccf
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/paginators-1.json
new file mode 100644
index 0000000000..55281fb779
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListApplications": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "applications"
+ },
+ "ListAssociatedAttributeGroups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "attributeGroups"
+ },
+ "ListAssociatedResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "resources"
+ },
+ "ListAttributeGroups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "attributeGroups"
+ },
+ "ListAttributeGroupsForApplication": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "attributeGroupsDetails"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/service-2.json.gz
new file mode 100644
index 0000000000..eab9d79c22
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog-appregistry/2020-06-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8367fb5b17
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/paginators-1.json
new file mode 100644
index 0000000000..5770fefa64
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/paginators-1.json
@@ -0,0 +1,100 @@
+{
+ "pagination": {
+ "SearchProductsAsAdmin": {
+ "result_key": "ProductViewDetails",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListAcceptedPortfolioShares": {
+ "result_key": "PortfolioDetails",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListPortfolios": {
+ "result_key": "PortfolioDetails",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListConstraintsForPortfolio": {
+ "result_key": "ConstraintDetails",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListLaunchPaths": {
+ "result_key": "LaunchPathSummaries",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListTagOptions": {
+ "result_key": "TagOptionDetails",
+ "output_token": "PageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListPortfoliosForProduct": {
+ "result_key": "PortfolioDetails",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListPrincipalsForPortfolio": {
+ "result_key": "Principals",
+ "output_token": "NextPageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListResourcesForTagOption": {
+ "result_key": "ResourceDetails",
+ "output_token": "PageToken",
+ "input_token": "PageToken",
+ "limit_key": "PageSize"
+ },
+ "ListOrganizationPortfolioAccess": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "OrganizationNodes"
+ },
+ "ListProvisionedProductPlans": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "ProvisionedProductPlans"
+ },
+ "ListProvisioningArtifactsForServiceAction": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "ProvisioningArtifactViews"
+ },
+ "ListRecordHistory": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "RecordDetails"
+ },
+ "ListServiceActions": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "ServiceActionSummaries"
+ },
+ "ListServiceActionsForProvisioningArtifact": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "ServiceActionSummaries"
+ },
+ "ScanProvisionedProducts": {
+ "input_token": "PageToken",
+ "limit_key": "PageSize",
+ "output_token": "NextPageToken",
+ "result_key": "ProvisionedProducts"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/service-2.json.gz
new file mode 100644
index 0000000000..9fea55f592
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicecatalog/2015-12-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..39afffb8b8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/examples-1.json
new file mode 100644
index 0000000000..cc99fe4cb4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/examples-1.json
@@ -0,0 +1,672 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CreateHttpNamespace": [
+ {
+ "input": {
+ "CreatorRequestId": "example-creator-request-id-0001",
+ "Description": "Example.com AWS Cloud Map HTTP Namespace",
+ "Name": "example-http.com"
+ },
+ "output": {
+ "OperationId": "httpvoqozuhfet5kzxoxg-a-response-example"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates an HTTP namespace.",
+ "id": "createhttpnamespace-example-1590114811304",
+ "title": "CreateHttpNamespace example"
+ }
+ ],
+ "CreatePrivateDnsNamespace": [
+ {
+ "input": {
+ "CreatorRequestId": "eedd6892-50f3-41b2-8af9-611d6e1d1a8c",
+ "Name": "example.com",
+ "Vpc": "vpc-1c56417b"
+ },
+ "output": {
+ "OperationId": "gv4g5meo7ndmeh4fqskygvk23d2fijwa-k9302yzd"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Create private DNS namespace",
+ "id": "example-create-private-dns-namespace-1587058592930",
+ "title": "Example: Create private DNS namespace"
+ }
+ ],
+ "CreatePublicDnsNamespace": [
+ {
+ "input": {
+ "CreatorRequestId": "example-creator-request-id-0003",
+ "Description": "Example.com AWS Cloud Map Public DNS Namespace",
+ "Name": "example-public-dns.com"
+ },
+ "output": {
+ "OperationId": "dns2voqozuhfet5kzxoxg-a-response-example"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example creates a public namespace based on DNS.",
+ "id": "createpublicdnsnamespace-example-1590114940910",
+ "title": "CreatePublicDnsNamespace example"
+ }
+ ],
+ "CreateService": [
+ {
+ "input": {
+ "CreatorRequestId": "567c1193-6b00-4308-bd57-ad38a8822d25",
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 60,
+ "Type": "A"
+ }
+ ],
+ "NamespaceId": "ns-ylexjili4cdxy3xm",
+ "RoutingPolicy": "MULTIVALUE"
+ },
+ "Name": "myservice",
+ "NamespaceId": "ns-ylexjili4cdxy3xm"
+ },
+ "output": {
+ "Service": {
+ "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:service/srv-p5zdwlg5uvvzjita",
+ "CreateDate": 1587081768.334,
+ "CreatorRequestId": "567c1193-6b00-4308-bd57-ad38a8822d25",
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 60,
+ "Type": "A"
+ }
+ ],
+ "NamespaceId": "ns-ylexjili4cdxy3xm",
+ "RoutingPolicy": "MULTIVALUE"
+ },
+ "Id": "srv-p5zdwlg5uvvzjita",
+ "Name": "myservice",
+ "NamespaceId": "ns-ylexjili4cdxy3xm"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Create service",
+ "id": "example-create-service-1587235913584",
+ "title": "Example: Create service"
+ }
+ ],
+ "DeleteNamespace": [
+ {
+ "input": {
+ "Id": "ns-ylexjili4cdxy3xm"
+ },
+ "output": {
+ "OperationId": "gv4g5meo7ndmeh4fqskygvk23d2fijwa-k98y6drk"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Delete namespace",
+ "id": "example-delete-namespace-1587416093508",
+ "title": "Example: Delete namespace"
+ }
+ ],
+ "DeleteService": [
+ {
+ "input": {
+ "Id": "srv-p5zdwlg5uvvzjita"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Delete service",
+ "id": "example-delete-service-1587416462902",
+ "title": "Example: Delete service"
+ }
+ ],
+ "DeregisterInstance": [
+ {
+ "input": {
+ "InstanceId": "myservice-53",
+ "ServiceId": "srv-p5zdwlg5uvvzjita"
+ },
+ "output": {
+ "OperationId": "4yejorelbukcjzpnr6tlmrghsjwpngf4-k98rnaiq"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Deregister a service instance",
+ "id": "example-deregister-a-service-instance-1587416305738",
+ "title": "Example: Deregister a service instance"
+ }
+ ],
+ "DiscoverInstances": [
+ {
+ "input": {
+ "HealthStatus": "ALL",
+ "MaxResults": 10,
+ "NamespaceName": "example.com",
+ "ServiceName": "myservice"
+ },
+ "output": {
+ "Instances": [
+ {
+ "Attributes": {
+ "AWS_INSTANCE_IPV4": "172.2.1.3",
+ "AWS_INSTANCE_PORT": "808"
+ },
+ "HealthStatus": "UNKNOWN",
+ "InstanceId": "myservice-53",
+ "NamespaceName": "example.com",
+ "ServiceName": "myservice"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Discover registered instances",
+ "id": "example-discover-registered-instances-1587236343568",
+ "title": "Example: Discover registered instances"
+ }
+ ],
+ "GetInstance": [
+ {
+ "input": {
+ "InstanceId": "i-abcd1234",
+ "ServiceId": "srv-e4anhexample0004"
+ },
+ "output": {
+ "Instance": {
+ "Attributes": {
+ "AWS_INSTANCE_IPV4": "192.0.2.44",
+ "AWS_INSTANCE_PORT": "80",
+ "color": "green",
+ "region": "us-west-2",
+ "stage": "beta"
+ },
+ "Id": "i-abcd1234"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example gets information about a specified instance.",
+ "id": "getinstance-example-1590115065598",
+ "title": "GetInstance example"
+ }
+ ],
+ "GetInstancesHealthStatus": [
+ {
+ "input": {
+ "ServiceId": "srv-e4anhexample0004"
+ },
+ "output": {
+ "Status": {
+ "i-abcd1234": "HEALTHY",
+ "i-abcd1235": "UNHEALTHY"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example gets the current health status of one or more instances that are associate with a specified service.",
+ "id": "getinstanceshealthstatus-example-1590115176146",
+ "title": "GetInstancesHealthStatus example"
+ }
+ ],
+ "GetNamespace": [
+ {
+ "input": {
+ "Id": "ns-e4anhexample0004"
+ },
+ "output": {
+ "Namespace": {
+ "Arn": "arn:aws:servicediscovery:us-west-2: 123456789120:namespace/ns-e1tpmexample0001",
+ "CreateDate": "20181118T211712Z",
+ "CreatorRequestId": "example-creator-request-id-0001",
+ "Description": "Example.com AWS Cloud Map HTTP Namespace",
+ "Id": "ns-e1tpmexample0001",
+ "Name": "example-http.com",
+ "Properties": {
+ "DnsProperties": {
+ },
+ "HttpProperties": {
+ "HttpName": "example-http.com"
+ }
+ },
+ "Type": "HTTP"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example gets information about a specified namespace.",
+ "id": "getnamespace-example-1590115383708",
+ "title": "GetNamespace example"
+ }
+ ],
+ "GetOperation": [
+ {
+ "input": {
+ "OperationId": "gv4g5meo7ndmeh4fqskygvk23d2fijwa-k9302yzd"
+ },
+ "output": {
+ "Operation": {
+ "CreateDate": 1587055860.121,
+ "Id": "gv4g5meo7ndmeh4fqskygvk23d2fijwa-k9302yzd",
+ "Status": "SUCCESS",
+ "Targets": {
+ "NAMESPACE": "ns-ylexjili4cdxy3xm"
+ },
+ "Type": "CREATE_NAMESPACE",
+ "UpdateDate": 1587055900.469
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Get operation result",
+ "id": "example-get-operation-result-1587073807124",
+ "title": "Example: Get operation result"
+ }
+ ],
+ "GetService": [
+ {
+ "input": {
+ "Id": "srv-e4anhexample0004"
+ },
+ "output": {
+ "Service": {
+ "Arn": "arn:aws:servicediscovery:us-west-2:123456789120:service/srv-e4anhexample0004",
+ "CreateDate": "20181118T211707Z",
+ "CreatorRequestId": "example-creator-request-id-0004",
+ "Description": "Example.com AWS Cloud Map HTTP Service",
+ "HealthCheckConfig": {
+ "FailureThreshold": 3,
+ "ResourcePath": "/",
+ "Type": "HTTPS"
+ },
+ "Id": "srv-e4anhexample0004",
+ "Name": "example-http-service",
+ "NamespaceId": "ns-e4anhexample0004"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example gets the settings for a specified service.",
+ "id": "getservice-example-1590117234294",
+ "title": "GetService Example"
+ }
+ ],
+ "ListInstances": [
+ {
+ "input": {
+ "ServiceId": "srv-qzpwvt2tfqcegapy"
+ },
+ "output": {
+ "Instances": [
+ {
+ "Attributes": {
+ "AWS_INSTANCE_IPV4": "172.2.1.3",
+ "AWS_INSTANCE_PORT": "808"
+ },
+ "Id": "i-06bdabbae60f65a4e"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: List service instances",
+ "id": "example-list-service-instances-1587236237008",
+ "title": "Example: List service instances"
+ }
+ ],
+ "ListNamespaces": [
+ {
+ "input": {
+ },
+ "output": {
+ "Namespaces": [
+ {
+ "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-a3ccy2e7e3a7rile",
+ "CreateDate": 1585354387.357,
+ "Id": "ns-a3ccy2e7e3a7rile",
+ "Name": "local",
+ "Properties": {
+ "DnsProperties": {
+ "HostedZoneId": "Z06752353VBUDTC32S84S"
+ },
+ "HttpProperties": {
+ "HttpName": "local"
+ }
+ },
+ "Type": "DNS_PRIVATE"
+ },
+ {
+ "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-pocfyjtrsmwtvcxx",
+ "CreateDate": 1586468974.698,
+ "Description": "My second namespace",
+ "Id": "ns-pocfyjtrsmwtvcxx",
+ "Name": "My-second-namespace",
+ "Properties": {
+ "DnsProperties": {
+ },
+ "HttpProperties": {
+ "HttpName": "My-second-namespace"
+ }
+ },
+ "Type": "HTTP"
+ },
+ {
+ "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-ylexjili4cdxy3xm",
+ "CreateDate": 1587055896.798,
+ "Id": "ns-ylexjili4cdxy3xm",
+ "Name": "example.com",
+ "Properties": {
+ "DnsProperties": {
+ "HostedZoneId": "Z09983722P0QME1B3KC8I"
+ },
+ "HttpProperties": {
+ "HttpName": "example.com"
+ }
+ },
+ "Type": "DNS_PRIVATE"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: List namespaces",
+ "id": "example-list-namespaces-1587401553154",
+ "title": "Example: List namespaces"
+ }
+ ],
+ "ListOperations": [
+ {
+ "input": {
+ "Filters": [
+ {
+ "Condition": "IN",
+ "Name": "STATUS",
+ "Values": [
+ "PENDING",
+ "SUCCESS"
+ ]
+ }
+ ]
+ },
+ "output": {
+ "Operations": [
+ {
+ "Id": "76yy8ovhpdz0plmjzbsnqgnrqvpv2qdt-kexample",
+ "Status": "SUCCESS"
+ },
+ {
+ "Id": "prysnyzpji3u2ciy45nke83x2zanl7yk-dexample",
+ "Status": "SUCCESS"
+ },
+ {
+ "Id": "ko4ekftir7kzlbechsh7xvcdgcpk66gh-7example",
+ "Status": "PENDING"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example gets the operations that have a STATUS of either PENDING or SUCCESS.",
+ "id": "listoperations-example-1590117354396",
+ "title": "ListOperations Example"
+ }
+ ],
+ "ListServices": [
+ {
+ "input": {
+ },
+ "output": {
+ "Services": [
+ {
+ "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:service/srv-p5zdwlg5uvvzjita",
+ "CreateDate": 1587081768.334,
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 60,
+ "Type": "A"
+ }
+ ],
+ "RoutingPolicy": "MULTIVALUE"
+ },
+ "Id": "srv-p5zdwlg5uvvzjita",
+ "Name": "myservice"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: List services",
+ "id": "example-list-services-1587236889840",
+ "title": "Example: List services"
+ }
+ ],
+ "ListTagsForResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:servicediscovery:us-east-1:123456789012:namespace/ns-ylexjili4cdxy3xm"
+ },
+ "output": {
+ "Tags": [
+ {
+ "Key": "Project",
+ "Value": "Zeta"
+ },
+ {
+ "Key": "Department",
+ "Value": "Engineering"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example lists the tags of a resource.",
+ "id": "listtagsforresource-example-1590093928416",
+ "title": "ListTagsForResource example"
+ }
+ ],
+ "RegisterInstance": [
+ {
+ "input": {
+ "Attributes": {
+ "AWS_INSTANCE_IPV4": "172.2.1.3",
+ "AWS_INSTANCE_PORT": "808"
+ },
+ "CreatorRequestId": "7a48a98a-72e6-4849-bfa7-1a458e030d7b",
+ "InstanceId": "myservice-53",
+ "ServiceId": "srv-p5zdwlg5uvvzjita"
+ },
+ "output": {
+ "OperationId": "4yejorelbukcjzpnr6tlmrghsjwpngf4-k95yg2u7"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Example: Register Instance",
+ "id": "example-register-instance-1587236116314",
+ "title": "Example: Register Instance"
+ }
+ ],
+ "TagResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:servicediscovery:us-east-1:123456789012:namespace/ns-ylexjili4cdxy3xm",
+ "Tags": [
+ {
+ "Key": "Department",
+ "Value": "Engineering"
+ },
+ {
+ "Key": "Project",
+ "Value": "Zeta"
+ }
+ ]
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example adds \"Department\" and \"Project\" tags to a resource.",
+ "id": "tagresource-example-1590093532240",
+ "title": "TagResource example"
+ }
+ ],
+ "UntagResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:servicediscovery:us-east-1:123456789012:namespace/ns-ylexjili4cdxy3xm",
+ "TagKeys": [
+ "Project",
+ "Department"
+ ]
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example removes the \"Department\" and \"Project\" tags from a resource.",
+ "id": "untagresource-example-1590094024672",
+ "title": "UntagResource example"
+ }
+ ],
+ "UpdateInstanceCustomHealthStatus": [
+ {
+ "input": {
+ "InstanceId": "i-abcd1234",
+ "ServiceId": "srv-e4anhexample0004",
+ "Status": "HEALTHY"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example submits a request to change the health status of an instance associated with a service with a custom health check to HEALTHY.",
+ "id": "updateinstancecustomhealthstatus-example-1590118408574",
+ "title": "UpdateInstanceCustomHealthStatus Example"
+ }
+ ],
+ "UpdateService": [
+ {
+ "input": {
+ "Id": "srv-e4anhexample0004",
+ "Service": {
+ "DnsConfig": {
+ "DnsRecords": [
+ {
+ "TTL": 60,
+ "Type": "A"
+ }
+ ]
+ },
+ "HealthCheckConfig": {
+ "FailureThreshold": 2,
+ "ResourcePath": "/",
+ "Type": "HTTP"
+ }
+ }
+ },
+ "output": {
+ "OperationId": "m35hsdrkxwjffm3xef4bxyy6vc3ewakx-jdn3y5g5"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example submits a request to replace the DnsConfig and HealthCheckConfig settings of a specified service.",
+ "id": "updateservice-example-1590117830880",
+ "title": "UpdateService Example"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/paginators-1.json
new file mode 100644
index 0000000000..f58df70e65
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListServices": {
+ "result_key": "Services",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListInstances": {
+ "result_key": "Instances",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListNamespaces": {
+ "result_key": "Namespaces",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListOperations": {
+ "result_key": "Operations",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/service-2.json.gz
new file mode 100644
index 0000000000..50ad1c9bd0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/servicediscovery/2017-03-14/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0aac014e2d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/examples-1.json
new file mode 100644
index 0000000000..e56903308d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/examples-1.json
@@ -0,0 +1,1021 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CloneReceiptRuleSet": [
+ {
+ "input": {
+ "OriginalRuleSetName": "RuleSetToClone",
+ "RuleSetName": "RuleSetToCreate"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a receipt rule set by cloning an existing one:",
+ "id": "clonereceiptruleset-1469055039770",
+ "title": "CloneReceiptRuleSet"
+ }
+ ],
+ "CreateReceiptFilter": [
+ {
+ "input": {
+ "Filter": {
+ "IpFilter": {
+ "Cidr": "1.2.3.4/24",
+ "Policy": "Allow"
+ },
+ "Name": "MyFilter"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a new IP address filter:",
+ "id": "createreceiptfilter-1469122681253",
+ "title": "CreateReceiptFilter"
+ }
+ ],
+ "CreateReceiptRule": [
+ {
+ "input": {
+ "After": "",
+ "Rule": {
+ "Actions": [
+ {
+ "S3Action": {
+ "BucketName": "MyBucket",
+ "ObjectKeyPrefix": "email"
+ }
+ }
+ ],
+ "Enabled": true,
+ "Name": "MyRule",
+ "ScanEnabled": true,
+ "TlsPolicy": "Optional"
+ },
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a new receipt rule:",
+ "id": "createreceiptrule-1469122946515",
+ "title": "CreateReceiptRule"
+ }
+ ],
+ "CreateReceiptRuleSet": [
+ {
+ "input": {
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an empty receipt rule set:",
+ "id": "createreceiptruleset-1469058761646",
+ "title": "CreateReceiptRuleSet"
+ }
+ ],
+ "DeleteIdentity": [
+ {
+ "input": {
+ "Identity": "user@example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an identity from the list of identities that have been submitted for verification with Amazon SES:",
+ "id": "deleteidentity-1469047858906",
+ "title": "DeleteIdentity"
+ }
+ ],
+ "DeleteIdentityPolicy": [
+ {
+ "input": {
+ "Identity": "user@example.com",
+ "PolicyName": "MyPolicy"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a sending authorization policy for an identity:",
+ "id": "deleteidentitypolicy-1469055282499",
+ "title": "DeleteIdentityPolicy"
+ }
+ ],
+ "DeleteReceiptFilter": [
+ {
+ "input": {
+ "FilterName": "MyFilter"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an IP address filter:",
+ "id": "deletereceiptfilter-1469055456835",
+ "title": "DeleteReceiptFilter"
+ }
+ ],
+ "DeleteReceiptRule": [
+ {
+ "input": {
+ "RuleName": "MyRule",
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a receipt rule:",
+ "id": "deletereceiptrule-1469055563599",
+ "title": "DeleteReceiptRule"
+ }
+ ],
+ "DeleteReceiptRuleSet": [
+ {
+ "input": {
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a receipt rule set:",
+ "id": "deletereceiptruleset-1469055713690",
+ "title": "DeleteReceiptRuleSet"
+ }
+ ],
+ "DeleteVerifiedEmailAddress": [
+ {
+ "input": {
+ "EmailAddress": "user@example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an email address from the list of identities that have been submitted for verification with Amazon SES:",
+ "id": "deleteverifiedemailaddress-1469051086444",
+ "title": "DeleteVerifiedEmailAddress"
+ }
+ ],
+ "DescribeActiveReceiptRuleSet": [
+ {
+ "input": {
+ },
+ "output": {
+ "Metadata": {
+ "CreatedTimestamp": "2016-07-15T16:25:59.607Z",
+ "Name": "default-rule-set"
+ },
+ "Rules": [
+ {
+ "Actions": [
+ {
+ "S3Action": {
+ "BucketName": "MyBucket",
+ "ObjectKeyPrefix": "email"
+ }
+ }
+ ],
+ "Enabled": true,
+ "Name": "MyRule",
+ "ScanEnabled": true,
+ "TlsPolicy": "Optional"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the metadata and receipt rules for the receipt rule set that is currently active:",
+ "id": "describeactivereceiptruleset-1469121611502",
+ "title": "DescribeActiveReceiptRuleSet"
+ }
+ ],
+ "DescribeReceiptRule": [
+ {
+ "input": {
+ "RuleName": "MyRule",
+ "RuleSetName": "MyRuleSet"
+ },
+ "output": {
+ "Rule": {
+ "Actions": [
+ {
+ "S3Action": {
+ "BucketName": "MyBucket",
+ "ObjectKeyPrefix": "email"
+ }
+ }
+ ],
+ "Enabled": true,
+ "Name": "MyRule",
+ "ScanEnabled": true,
+ "TlsPolicy": "Optional"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a receipt rule:",
+ "id": "describereceiptrule-1469055813118",
+ "title": "DescribeReceiptRule"
+ }
+ ],
+ "DescribeReceiptRuleSet": [
+ {
+ "input": {
+ "RuleSetName": "MyRuleSet"
+ },
+ "output": {
+ "Metadata": {
+ "CreatedTimestamp": "2016-07-15T16:25:59.607Z",
+ "Name": "MyRuleSet"
+ },
+ "Rules": [
+ {
+ "Actions": [
+ {
+ "S3Action": {
+ "BucketName": "MyBucket",
+ "ObjectKeyPrefix": "email"
+ }
+ }
+ ],
+ "Enabled": true,
+ "Name": "MyRule",
+ "ScanEnabled": true,
+ "TlsPolicy": "Optional"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the metadata and receipt rules of a receipt rule set:",
+ "id": "describereceiptruleset-1469121240385",
+ "title": "DescribeReceiptRuleSet"
+ }
+ ],
+ "GetAccountSendingEnabled": [
+ {
+ "output": {
+ "Enabled": true
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns if sending status for an account is enabled. (true / false):",
+ "id": "getaccountsendingenabled-1469047741333",
+ "title": "GetAccountSendingEnabled"
+ }
+ ],
+ "GetIdentityDkimAttributes": [
+ {
+ "input": {
+ "Identities": [
+ "example.com",
+ "user@example.com"
+ ]
+ },
+ "output": {
+ "DkimAttributes": {
+ "example.com": {
+ "DkimEnabled": true,
+ "DkimTokens": [
+ "EXAMPLEjcs5xoyqytjsotsijas7236gr",
+ "EXAMPLEjr76cvoc6mysspnioorxsn6ep",
+ "EXAMPLEkbmkqkhlm2lyz77ppkulerm4k"
+ ],
+ "DkimVerificationStatus": "Success"
+ },
+ "user@example.com": {
+ "DkimEnabled": false,
+ "DkimVerificationStatus": "NotStarted"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example retrieves the Amazon SES Easy DKIM attributes for a list of identities:",
+ "id": "getidentitydkimattributes-1469050695628",
+ "title": "GetIdentityDkimAttributes"
+ }
+ ],
+ "GetIdentityMailFromDomainAttributes": [
+ {
+ "input": {
+ "Identities": [
+ "example.com"
+ ]
+ },
+ "output": {
+ "MailFromDomainAttributes": {
+ "example.com": {
+ "BehaviorOnMXFailure": "UseDefaultValue",
+ "MailFromDomain": "bounces.example.com",
+ "MailFromDomainStatus": "Success"
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the custom MAIL FROM attributes for an identity:",
+ "id": "getidentitymailfromdomainattributes-1469123114860",
+ "title": "GetIdentityMailFromDomainAttributes"
+ }
+ ],
+ "GetIdentityNotificationAttributes": [
+ {
+ "input": {
+ "Identities": [
+ "example.com"
+ ]
+ },
+ "output": {
+ "NotificationAttributes": {
+ "example.com": {
+ "BounceTopic": "arn:aws:sns:us-east-1:EXAMPLE65304:ExampleTopic",
+ "ComplaintTopic": "arn:aws:sns:us-east-1:EXAMPLE65304:ExampleTopic",
+ "DeliveryTopic": "arn:aws:sns:us-east-1:EXAMPLE65304:ExampleTopic",
+ "ForwardingEnabled": true,
+ "HeadersInBounceNotificationsEnabled": false,
+ "HeadersInComplaintNotificationsEnabled": false,
+ "HeadersInDeliveryNotificationsEnabled": false
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the notification attributes for an identity:",
+ "id": "getidentitynotificationattributes-1469123466947",
+ "title": "GetIdentityNotificationAttributes"
+ }
+ ],
+ "GetIdentityPolicies": [
+ {
+ "input": {
+ "Identity": "example.com",
+ "PolicyNames": [
+ "MyPolicy"
+ ]
+ },
+ "output": {
+ "Policies": {
+ "MyPolicy": "{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"stmt1469123904194\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"},\"Action\":[\"ses:SendEmail\",\"ses:SendRawEmail\"],\"Resource\":\"arn:aws:ses:us-east-1:EXAMPLE65304:identity/example.com\"}]}"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a sending authorization policy for an identity:",
+ "id": "getidentitypolicies-1469123949351",
+ "title": "GetIdentityPolicies"
+ }
+ ],
+ "GetIdentityVerificationAttributes": [
+ {
+ "input": {
+ "Identities": [
+ "example.com"
+ ]
+ },
+ "output": {
+ "VerificationAttributes": {
+ "example.com": {
+ "VerificationStatus": "Success",
+ "VerificationToken": "EXAMPLE3VYb9EDI2nTOQRi/Tf6MI/6bD6THIGiP1MVY="
+ }
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the verification status and the verification token for a domain identity:",
+ "id": "getidentityverificationattributes-1469124205897",
+ "title": "GetIdentityVerificationAttributes"
+ }
+ ],
+ "GetSendQuota": [
+ {
+ "output": {
+ "Max24HourSend": 200,
+ "MaxSendRate": 1,
+ "SentLast24Hours": 1
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the Amazon SES sending limits for an AWS account:",
+ "id": "getsendquota-1469047324508",
+ "title": "GetSendQuota"
+ }
+ ],
+ "GetSendStatistics": [
+ {
+ "output": {
+ "SendDataPoints": [
+ {
+ "Bounces": 0,
+ "Complaints": 0,
+ "DeliveryAttempts": 5,
+ "Rejects": 0,
+ "Timestamp": "2016-07-13T22:43:00Z"
+ },
+ {
+ "Bounces": 0,
+ "Complaints": 0,
+ "DeliveryAttempts": 3,
+ "Rejects": 0,
+ "Timestamp": "2016-07-13T23:13:00Z"
+ },
+ {
+ "Bounces": 0,
+ "Complaints": 0,
+ "DeliveryAttempts": 1,
+ "Rejects": 0,
+ "Timestamp": "2016-07-13T21:13:00Z"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns Amazon SES sending statistics:",
+ "id": "getsendstatistics-1469047741329",
+ "title": "GetSendStatistics"
+ }
+ ],
+ "ListIdentities": [
+ {
+ "input": {
+ "IdentityType": "EmailAddress",
+ "MaxItems": 123,
+ "NextToken": ""
+ },
+ "output": {
+ "Identities": [
+ "user@example.com"
+ ],
+ "NextToken": ""
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example lists the email address identities that have been submitted for verification with Amazon SES:",
+ "id": "listidentities-1469048638493",
+ "title": "ListIdentities"
+ }
+ ],
+ "ListIdentityPolicies": [
+ {
+ "input": {
+ "Identity": "example.com"
+ },
+ "output": {
+ "PolicyNames": [
+ "MyPolicy"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a list of sending authorization policies that are attached to an identity:",
+ "id": "listidentitypolicies-1469124417674",
+ "title": "ListIdentityPolicies"
+ }
+ ],
+ "ListReceiptFilters": [
+ {
+ "output": {
+ "Filters": [
+ {
+ "IpFilter": {
+ "Cidr": "1.2.3.4/24",
+ "Policy": "Block"
+ },
+ "Name": "MyFilter"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example lists the IP address filters that are associated with an AWS account:",
+ "id": "listreceiptfilters-1469120786789",
+ "title": "ListReceiptFilters"
+ }
+ ],
+ "ListReceiptRuleSets": [
+ {
+ "input": {
+ "NextToken": ""
+ },
+ "output": {
+ "NextToken": "",
+ "RuleSets": [
+ {
+ "CreatedTimestamp": "2016-07-15T16:25:59.607Z",
+ "Name": "MyRuleSet"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example lists the receipt rule sets that exist under an AWS account:",
+ "id": "listreceiptrulesets-1469121037235",
+ "title": "ListReceiptRuleSets"
+ }
+ ],
+ "ListVerifiedEmailAddresses": [
+ {
+ "output": {
+ "VerifiedEmailAddresses": [
+ "user1@example.com",
+ "user2@example.com"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example lists all email addresses that have been submitted for verification with Amazon SES:",
+ "id": "listverifiedemailaddresses-1469051402570",
+ "title": "ListVerifiedEmailAddresses"
+ }
+ ],
+ "PutIdentityPolicy": [
+ {
+ "input": {
+ "Identity": "example.com",
+ "Policy": "{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"stmt1469123904194\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"},\"Action\":[\"ses:SendEmail\",\"ses:SendRawEmail\"],\"Resource\":\"arn:aws:ses:us-east-1:EXAMPLE65304:identity/example.com\"}]}",
+ "PolicyName": "MyPolicy"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example adds a sending authorization policy to an identity:",
+ "id": "putidentitypolicy-1469124560016",
+ "title": "PutIdentityPolicy"
+ }
+ ],
+ "ReorderReceiptRuleSet": [
+ {
+ "input": {
+ "RuleNames": [
+ "MyRule",
+ "MyOtherRule"
+ ],
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example reorders the receipt rules within a receipt rule set:",
+ "id": "reorderreceiptruleset-1469058156806",
+ "title": "ReorderReceiptRuleSet"
+ }
+ ],
+ "SendEmail": [
+ {
+ "input": {
+ "Destination": {
+ "BccAddresses": [
+
+ ],
+ "CcAddresses": [
+ "recipient3@example.com"
+ ],
+ "ToAddresses": [
+ "recipient1@example.com",
+ "recipient2@example.com"
+ ]
+ },
+ "Message": {
+ "Body": {
+ "Html": {
+ "Charset": "UTF-8",
+ "Data": "This message body contains HTML formatting. It can, for example, contain links like this one: Amazon SES Developer Guide."
+ },
+ "Text": {
+ "Charset": "UTF-8",
+ "Data": "This is the message body in text format."
+ }
+ },
+ "Subject": {
+ "Charset": "UTF-8",
+ "Data": "Test email"
+ }
+ },
+ "ReplyToAddresses": [
+
+ ],
+ "ReturnPath": "",
+ "ReturnPathArn": "",
+ "Source": "sender@example.com",
+ "SourceArn": ""
+ },
+ "output": {
+ "MessageId": "EXAMPLE78603177f-7a5433e7-8edb-42ae-af10-f0181f34d6ee-000000"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sends a formatted email:",
+ "id": "sendemail-1469049656296",
+ "title": "SendEmail"
+ }
+ ],
+ "SendRawEmail": [
+ {
+ "input": {
+ "Destinations": [
+
+ ],
+ "FromArn": "",
+ "RawMessage": {
+ "Data": "From: sender@example.com\\nTo: recipient@example.com\\nSubject: Test email (contains an attachment)\\nMIME-Version: 1.0\\nContent-type: Multipart/Mixed; boundary=\"NextPart\"\\n\\n--NextPart\\nContent-Type: text/plain\\n\\nThis is the message body.\\n\\n--NextPart\\nContent-Type: text/plain;\\nContent-Disposition: attachment; filename=\"attachment.txt\"\\n\\nThis is the text in the attachment.\\n\\n--NextPart--"
+ },
+ "ReturnPathArn": "",
+ "Source": "",
+ "SourceArn": ""
+ },
+ "output": {
+ "MessageId": "EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sends an email with an attachment:",
+ "id": "sendrawemail-1469118548649",
+ "title": "SendRawEmail"
+ }
+ ],
+ "SetActiveReceiptRuleSet": [
+ {
+ "input": {
+ "RuleSetName": "RuleSetToActivate"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets the active receipt rule set:",
+ "id": "setactivereceiptruleset-1469058391329",
+ "title": "SetActiveReceiptRuleSet"
+ }
+ ],
+ "SetIdentityDkimEnabled": [
+ {
+ "input": {
+ "DkimEnabled": true,
+ "Identity": "user@example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example configures Amazon SES to Easy DKIM-sign the email sent from an identity:",
+ "id": "setidentitydkimenabled-1469057485202",
+ "title": "SetIdentityDkimEnabled"
+ }
+ ],
+ "SetIdentityFeedbackForwardingEnabled": [
+ {
+ "input": {
+ "ForwardingEnabled": true,
+ "Identity": "user@example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example configures Amazon SES to forward an identity's bounces and complaints via email:",
+ "id": "setidentityfeedbackforwardingenabled-1469056811329",
+ "title": "SetIdentityFeedbackForwardingEnabled"
+ }
+ ],
+ "SetIdentityHeadersInNotificationsEnabled": [
+ {
+ "input": {
+ "Enabled": true,
+ "Identity": "user@example.com",
+ "NotificationType": "Bounce"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example configures Amazon SES to include the original email headers in the Amazon SNS bounce notifications for an identity:",
+ "id": "setidentityheadersinnotificationsenabled-1469057295001",
+ "title": "SetIdentityHeadersInNotificationsEnabled"
+ }
+ ],
+ "SetIdentityMailFromDomain": [
+ {
+ "input": {
+ "BehaviorOnMXFailure": "UseDefaultValue",
+ "Identity": "user@example.com",
+ "MailFromDomain": "bounces.example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example configures Amazon SES to use a custom MAIL FROM domain for an identity:",
+ "id": "setidentitymailfromdomain-1469057693908",
+ "title": "SetIdentityMailFromDomain"
+ }
+ ],
+ "SetIdentityNotificationTopic": [
+ {
+ "input": {
+ "Identity": "user@example.com",
+ "NotificationType": "Bounce",
+ "SnsTopic": "arn:aws:sns:us-west-2:111122223333:MyTopic"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets the Amazon SNS topic to which Amazon SES will publish bounce, complaint, and/or delivery notifications for emails sent with the specified identity as the Source:",
+ "id": "setidentitynotificationtopic-1469057854966",
+ "title": "SetIdentityNotificationTopic"
+ }
+ ],
+ "SetReceiptRulePosition": [
+ {
+ "input": {
+ "After": "PutRuleAfterThisRule",
+ "RuleName": "RuleToReposition",
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example sets the position of a receipt rule in a receipt rule set:",
+ "id": "setreceiptruleposition-1469058530550",
+ "title": "SetReceiptRulePosition"
+ }
+ ],
+ "UpdateAccountSendingEnabled": [
+ {
+ "input": {
+ "Enabled": true
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example updated the sending status for this account.",
+ "id": "updateaccountsendingenabled-1469047741333",
+ "title": "UpdateAccountSendingEnabled"
+ }
+ ],
+ "UpdateConfigurationSetReputationMetricsEnabled": [
+ {
+ "input": {
+ "ConfigurationSetName": "foo",
+ "Enabled": true
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Set the reputationMetricsEnabled flag for a specific configuration set.",
+ "id": "updateconfigurationsetreputationmetricsenabled-2362747741333",
+ "title": "UpdateConfigurationSetReputationMetricsEnabled"
+ }
+ ],
+ "UpdateConfigurationSetSendingEnabled": [
+ {
+ "input": {
+ "ConfigurationSetName": "foo",
+ "Enabled": true
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Set the sending enabled flag for a specific configuration set.",
+ "id": "updateconfigurationsetsendingenabled-2362747741333",
+ "title": "UpdateConfigurationSetReputationMetricsEnabled"
+ }
+ ],
+ "UpdateReceiptRule": [
+ {
+ "input": {
+ "Rule": {
+ "Actions": [
+ {
+ "S3Action": {
+ "BucketName": "MyBucket",
+ "ObjectKeyPrefix": "email"
+ }
+ }
+ ],
+ "Enabled": true,
+ "Name": "MyRule",
+ "ScanEnabled": true,
+ "TlsPolicy": "Optional"
+ },
+ "RuleSetName": "MyRuleSet"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example updates a receipt rule to use an Amazon S3 action:",
+ "id": "updatereceiptrule-1469051756940",
+ "title": "UpdateReceiptRule"
+ }
+ ],
+ "VerifyDomainDkim": [
+ {
+ "input": {
+ "Domain": "example.com"
+ },
+ "output": {
+ "DkimTokens": [
+ "EXAMPLEq76owjnks3lnluwg65scbemvw",
+ "EXAMPLEi3dnsj67hstzaj673klariwx2",
+ "EXAMPLEwfbtcukvimehexktmdtaz6naj"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example generates DKIM tokens for a domain that has been verified with Amazon SES:",
+ "id": "verifydomaindkim-1469049503083",
+ "title": "VerifyDomainDkim"
+ }
+ ],
+ "VerifyDomainIdentity": [
+ {
+ "input": {
+ "Domain": "example.com"
+ },
+ "output": {
+ "VerificationToken": "eoEmxw+YaYhb3h3iVJHuXMJXqeu1q1/wwmvjuEXAMPLE"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example starts the domain verification process with Amazon SES:",
+ "id": "verifydomainidentity-1469049165936",
+ "title": "VerifyDomainIdentity"
+ }
+ ],
+ "VerifyEmailAddress": [
+ {
+ "input": {
+ "EmailAddress": "user@example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example starts the email address verification process with Amazon SES:",
+ "id": "verifyemailaddress-1469048849187",
+ "title": "VerifyEmailAddress"
+ }
+ ],
+ "VerifyEmailIdentity": [
+ {
+ "input": {
+ "EmailAddress": "user@example.com"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example starts the email address verification process with Amazon SES:",
+ "id": "verifyemailidentity-1469049068623",
+ "title": "VerifyEmailIdentity"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/paginators-1.json
new file mode 100644
index 0000000000..1eb0054fcb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/paginators-1.json
@@ -0,0 +1,33 @@
+{
+ "pagination": {
+ "ListIdentities": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxItems",
+ "result_key": "Identities"
+ },
+ "ListCustomVerificationEmailTemplates": {
+ "result_key": "CustomVerificationEmailTemplates",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListConfigurationSets": {
+ "input_token": "NextToken",
+ "limit_key": "MaxItems",
+ "output_token": "NextToken",
+ "result_key": "ConfigurationSets"
+ },
+ "ListReceiptRuleSets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "RuleSets"
+ },
+ "ListTemplates": {
+ "input_token": "NextToken",
+ "limit_key": "MaxItems",
+ "output_token": "NextToken",
+ "result_key": "TemplatesMetadata"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/service-2.json.gz
new file mode 100644
index 0000000000..d6e1c76504
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/waiters-2.json
new file mode 100644
index 0000000000..b585d309ef
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ses/2010-12-01/waiters-2.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "waiters": {
+ "IdentityExists": {
+ "delay": 3,
+ "operation": "GetIdentityVerificationAttributes",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": "Success",
+ "matcher": "pathAll",
+ "state": "success",
+ "argument": "VerificationAttributes.*.VerificationStatus"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0ddbea5ac2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/service-2.json.gz
new file mode 100644
index 0000000000..f129dad712
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sesv2/2019-09-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..11a4093f14
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/paginators-1.json
new file mode 100644
index 0000000000..c5ded64262
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListProtections": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Protections"
+ },
+ "ListAttacks": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AttackSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/service-2.json.gz
new file mode 100644
index 0000000000..7045ad1ee6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/shield/2016-06-02/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0c9d8e627d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/paginators-1.json
new file mode 100644
index 0000000000..1e049e7dec
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListSigningJobs": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "jobs"
+ },
+ "ListSigningPlatforms": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "platforms"
+ },
+ "ListSigningProfiles": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "profiles"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/service-2.json.gz
new file mode 100644
index 0000000000..f5a055352b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/waiters-2.json
new file mode 100644
index 0000000000..a0890ade37
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/signer/2017-08-25/waiters-2.json
@@ -0,0 +1,29 @@
+{
+ "version": 2,
+ "waiters": {
+ "SuccessfulSigningJob": {
+ "delay": 20,
+ "operation": "DescribeSigningJob",
+ "maxAttempts": 25,
+ "acceptors": [
+ {
+ "expected": "Succeeded",
+ "matcher": "path",
+ "state": "success",
+ "argument": "status"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "status"
+ },
+ {
+ "expected": "ResourceNotFoundException",
+ "matcher": "error",
+ "state": "failure"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..c58ddf2c7b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/service-2.json.gz
new file mode 100644
index 0000000000..229a426932
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/simspaceweaver/2022-10-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms-voice/2018-09-05/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms-voice/2018-09-05/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4dfe7254a1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms-voice/2018-09-05/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms-voice/2018-09-05/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms-voice/2018-09-05/service-2.json.gz
new file mode 100644
index 0000000000..3ae7ef2495
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms-voice/2018-09-05/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..eeb5db13e4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/paginators-1.json
new file mode 100644
index 0000000000..52a8d570e9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "GetReplicationJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "replicationJobList"
+ },
+ "GetReplicationRuns": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "replicationRunList"
+ },
+ "GetConnectors": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "connectorList"
+ },
+ "GetServers": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "serverList"
+ },
+ "ListApps": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "apps"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/service-2.json.gz
new file mode 100644
index 0000000000..199d2b0e10
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sms/2016-10-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..415db97e90
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/paginators-1.json
new file mode 100644
index 0000000000..8b112099e7
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListDeviceResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "resources"
+ },
+ "ListDevices": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "devices"
+ },
+ "ListExecutions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "executions"
+ },
+ "ListTasks": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "tasks"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/service-2.json.gz
new file mode 100644
index 0000000000..d5a6c25de3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snow-device-management/2021-08-04/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e9eedab188
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/examples-1.json
new file mode 100644
index 0000000000..2b13f7b443
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/examples-1.json
@@ -0,0 +1,442 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CancelCluster": [
+ {
+ "input": {
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "comments": {
+ },
+ "description": "This operation cancels a cluster job. You can only cancel a cluster job while it's in the AwaitingQuorum status.",
+ "id": "to-cancel-a-cluster-job-1482533760554",
+ "title": "To cancel a cluster job"
+ }
+ ],
+ "CancelJob": [
+ {
+ "input": {
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "comments": {
+ },
+ "description": "This operation cancels a job. You can only cancel a job before its JobState value changes to PreparingAppliance.",
+ "id": "to-cancel-a-job-for-a-snowball-device-1482534699477",
+ "title": "To cancel a job for a Snowball device"
+ }
+ ],
+ "CreateAddress": [
+ {
+ "input": {
+ "Address": {
+ "City": "Seattle",
+ "Company": "My Company's Name",
+ "Country": "USA",
+ "Name": "My Name",
+ "PhoneNumber": "425-555-5555",
+ "PostalCode": "98101",
+ "StateOrProvince": "WA",
+ "Street1": "123 Main Street"
+ }
+ },
+ "output": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b"
+ },
+ "comments": {
+ },
+ "description": "This operation creates an address for a job. Addresses are validated at the time of creation. The address you provide must be located within the serviceable area of your region. If the address is invalid or unsupported, then an exception is thrown.",
+ "id": "to-create-an-address-for-a-job-1482535416294",
+ "title": "To create an address for a job"
+ }
+ ],
+ "CreateCluster": [
+ {
+ "input": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "Description": "MyCluster",
+ "JobType": "LOCAL_USE",
+ "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456",
+ "Notification": {
+ "JobStatesToNotify": [
+
+ ],
+ "NotifyAll": false
+ },
+ "Resources": {
+ "S3Resources": [
+ {
+ "BucketArn": "arn:aws:s3:::MyBucket",
+ "KeyRange": {
+ }
+ }
+ ]
+ },
+ "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role",
+ "ShippingOption": "SECOND_DAY",
+ "SnowballType": "EDGE"
+ },
+ "output": {
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "comments": {
+ },
+ "description": "Creates an empty cluster. Each cluster supports five nodes. You use the CreateJob action separately to create the jobs for each of these nodes. The cluster does not ship until these five node jobs have been created.",
+ "id": "to-create-a-cluster-1482864724077",
+ "title": "To create a cluster"
+ }
+ ],
+ "CreateJob": [
+ {
+ "input": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "Description": "My Job",
+ "JobType": "IMPORT",
+ "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456",
+ "Notification": {
+ "JobStatesToNotify": [
+
+ ],
+ "NotifyAll": false
+ },
+ "Resources": {
+ "S3Resources": [
+ {
+ "BucketArn": "arn:aws:s3:::MyBucket",
+ "KeyRange": {
+ }
+ }
+ ]
+ },
+ "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role",
+ "ShippingOption": "SECOND_DAY",
+ "SnowballCapacityPreference": "T80",
+ "SnowballType": "STANDARD"
+ },
+ "output": {
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "comments": {
+ },
+ "description": "Creates a job to import or export data between Amazon S3 and your on-premises data center. Your AWS account must have the right trust policies and permissions in place to create a job for Snowball. If you're creating a job for a node in a cluster, you only need to provide the clusterId value; the other job attributes are inherited from the cluster.",
+ "id": "to-create-a-job-1482864834886",
+ "title": "To create a job"
+ }
+ ],
+ "DescribeAddress": [
+ {
+ "input": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b"
+ },
+ "output": {
+ "Address": {
+ "AddressId": "ADID5643ec50-3eec-4eb3-9be6-9374c10eb51b",
+ "City": "Seattle",
+ "Company": "My Company",
+ "Country": "US",
+ "Name": "My Name",
+ "PhoneNumber": "425-555-5555",
+ "PostalCode": "98101",
+ "StateOrProvince": "WA",
+ "Street1": "123 Main Street"
+ }
+ },
+ "comments": {
+ },
+ "description": "This operation describes an address for a job.",
+ "id": "to-describe-an-address-for-a-job-1482538608745",
+ "title": "To describe an address for a job"
+ }
+ ],
+ "DescribeAddresses": [
+ {
+ "input": {
+ },
+ "output": {
+ "Addresses": [
+ {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "City": "Seattle",
+ "Company": "My Company",
+ "Country": "US",
+ "Name": "My Name",
+ "PhoneNumber": "425-555-5555",
+ "PostalCode": "98101",
+ "StateOrProvince": "WA",
+ "Street1": "123 Main Street"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "This operation describes all the addresses that you've created for AWS Snowball. Calling this API in one of the US regions will return addresses from the list of all addresses associated with this account in all US regions.",
+ "id": "to-describe-all-the-addresses-youve-created-for-aws-snowball-1482538936603",
+ "title": "To describe all the addresses you've created for AWS Snowball"
+ }
+ ],
+ "DescribeCluster": [
+ {
+ "input": {
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "output": {
+ "ClusterMetadata": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000",
+ "ClusterState": "Pending",
+ "CreationDate": "1480475517.0",
+ "Description": "MyCluster",
+ "JobType": "LOCAL_USE",
+ "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456",
+ "Notification": {
+ "JobStatesToNotify": [
+
+ ],
+ "NotifyAll": false
+ },
+ "Resources": {
+ "S3Resources": [
+ {
+ "BucketArn": "arn:aws:s3:::MyBucket",
+ "KeyRange": {
+ }
+ }
+ ]
+ },
+ "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role",
+ "ShippingOption": "SECOND_DAY"
+ }
+ },
+ "comments": {
+ },
+ "description": "Returns information about a specific cluster including shipping information, cluster status, and other important metadata.",
+ "id": "to-describe-a-cluster-1482864218396",
+ "title": "To describe a cluster"
+ }
+ ],
+ "DescribeJob": [
+ {
+ "input": {
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "output": {
+ "JobMetadata": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "CreationDate": "1475626164",
+ "Description": "My Job",
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000",
+ "JobState": "New",
+ "JobType": "IMPORT",
+ "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456",
+ "Notification": {
+ "JobStatesToNotify": [
+
+ ],
+ "NotifyAll": false
+ },
+ "Resources": {
+ "S3Resources": [
+ {
+ "BucketArn": "arn:aws:s3:::MyBucket",
+ "KeyRange": {
+ }
+ }
+ ]
+ },
+ "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role",
+ "ShippingDetails": {
+ "ShippingOption": "SECOND_DAY"
+ },
+ "SnowballCapacityPreference": "T80",
+ "SnowballType": "STANDARD"
+ }
+ },
+ "comments": {
+ },
+ "description": "This operation describes a job you've created for AWS Snowball.",
+ "id": "to-describe-a-job-youve-created-for-aws-snowball-1482539500180",
+ "title": "To describe a job you've created for AWS Snowball"
+ }
+ ],
+ "GetJobManifest": [
+ {
+ "input": {
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "output": {
+ "ManifestURI": "https://awsie-frosty-manifests-prod.s3.amazonaws.com/JID123e4567-e89b-12d3-a456-426655440000_manifest.bin?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20161224T005115Z&X-Amz-SignedHeaders=..."
+ },
+ "comments": {
+ },
+ "description": "Returns a link to an Amazon S3 presigned URL for the manifest file associated with the specified JobId value. You can access the manifest file for up to 60 minutes after this request has been made. To access the manifest file after 60 minutes have passed, you'll have to make another call to the GetJobManifest action.\n\nThe manifest is an encrypted file that you can download after your job enters the WithCustomer status. The manifest is decrypted by using the UnlockCode code value, when you pass both values to the Snowball through the Snowball client when the client is started for the first time.\n\nAs a best practice, we recommend that you don't save a copy of an UnlockCode value in the same location as the manifest file for that job. Saving these separately helps prevent unauthorized parties from gaining access to the Snowball associated with that job.\n\nThe credentials of a given job, including its manifest file and unlock code, expire 90 days after the job is created.",
+ "id": "to-get-the-manifest-for-a-job-youve-created-for-aws-snowball-1482540389246",
+ "title": "To get the manifest for a job you've created for AWS Snowball"
+ }
+ ],
+ "GetJobUnlockCode": [
+ {
+ "input": {
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "output": {
+ "UnlockCode": "12345-abcde-56789-fghij-01234"
+ },
+ "comments": {
+ },
+ "description": "Returns the UnlockCode code value for the specified job. A particular UnlockCode value can be accessed for up to 90 days after the associated job has been created.\n\nThe UnlockCode value is a 29-character code with 25 alphanumeric characters and 4 hyphens. This code is used to decrypt the manifest file when it is passed along with the manifest to the Snowball through the Snowball client when the client is started for the first time.\n\nAs a best practice, we recommend that you don't save a copy of the UnlockCode in the same location as the manifest file for that job. Saving these separately helps prevent unauthorized parties from gaining access to the Snowball associated with that job.",
+ "id": "to-get-the-unlock-code-for-a-job-youve-created-for-aws-snowball-1482541987286",
+ "title": "To get the unlock code for a job you've created for AWS Snowball"
+ }
+ ],
+ "GetSnowballUsage": [
+ {
+ "input": {
+ },
+ "output": {
+ "SnowballLimit": 1,
+ "SnowballsInUse": 0
+ },
+ "comments": {
+ },
+ "description": "Returns information about the Snowball service limit for your account, and also the number of Snowballs your account has in use.\n\nThe default service limit for the number of Snowballs that you can have at one time is 1. If you want to increase your service limit, contact AWS Support.",
+ "id": "to-see-your-snowball-service-limit-and-the-number-of-snowballs-you-have-in-use-1482863394588",
+ "title": "To see your Snowball service limit and the number of Snowballs you have in use"
+ }
+ ],
+ "ListClusterJobs": [
+ {
+ "input": {
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000"
+ },
+ "output": {
+ "JobListEntries": [
+ {
+ "CreationDate": "1480475524.0",
+ "Description": "MyClustrer-node-001",
+ "IsMaster": false,
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000",
+ "JobState": "New",
+ "JobType": "LOCAL_USE",
+ "SnowballType": "EDGE"
+ },
+ {
+ "CreationDate": "1480475525.0",
+ "Description": "MyClustrer-node-002",
+ "IsMaster": false,
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440001",
+ "JobState": "New",
+ "JobType": "LOCAL_USE",
+ "SnowballType": "EDGE"
+ },
+ {
+ "CreationDate": "1480475525.0",
+ "Description": "MyClustrer-node-003",
+ "IsMaster": false,
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440002",
+ "JobState": "New",
+ "JobType": "LOCAL_USE",
+ "SnowballType": "EDGE"
+ },
+ {
+ "CreationDate": "1480475525.0",
+ "Description": "MyClustrer-node-004",
+ "IsMaster": false,
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440003",
+ "JobState": "New",
+ "JobType": "LOCAL_USE",
+ "SnowballType": "EDGE"
+ },
+ {
+ "CreationDate": "1480475525.0",
+ "Description": "MyClustrer-node-005",
+ "IsMaster": false,
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440004",
+ "JobState": "New",
+ "JobType": "LOCAL_USE",
+ "SnowballType": "EDGE"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "Returns an array of JobListEntry objects of the specified length. Each JobListEntry object is for a job in the specified cluster and contains a job's state, a job's ID, and other information.",
+ "id": "to-get-a-list-of-jobs-in-a-cluster-that-youve-created-for-aws-snowball-1482863105773",
+ "title": "To get a list of jobs in a cluster that you've created for AWS Snowball"
+ }
+ ],
+ "ListClusters": [
+ {
+ "input": {
+ },
+ "output": {
+ "ClusterListEntries": [
+ {
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000",
+ "ClusterState": "Pending",
+ "CreationDate": "1480475517.0",
+ "Description": "MyCluster"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "Returns an array of ClusterListEntry objects of the specified length. Each ClusterListEntry object contains a cluster's state, a cluster's ID, and other important status information.",
+ "id": "to-get-a-list-of-clusters-that-youve-created-for-aws-snowball-1482862223003",
+ "title": "To get a list of clusters that you've created for AWS Snowball"
+ }
+ ],
+ "ListJobs": [
+ {
+ "input": {
+ },
+ "output": {
+ "JobListEntries": [
+ {
+ "CreationDate": "1460678186.0",
+ "Description": "MyJob",
+ "IsMaster": false,
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000",
+ "JobState": "New",
+ "JobType": "IMPORT",
+ "SnowballType": "STANDARD"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "Returns an array of JobListEntry objects of the specified length. Each JobListEntry object contains a job's state, a job's ID, and a value that indicates whether the job is a job part, in the case of export jobs. Calling this API action in one of the US regions will return jobs from the list of all jobs associated with this account in all US regions.",
+ "id": "to-get-a-list-of-jobs-that-youve-created-for-aws-snowball-1482542167627",
+ "title": "To get a list of jobs that you've created for AWS Snowball"
+ }
+ ],
+ "UpdateCluster": [
+ {
+ "input": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000",
+ "Description": "updated-cluster-name"
+ },
+ "comments": {
+ },
+ "description": "This action allows you to update certain parameters for a cluster. Once the cluster changes to a different state, usually within 60 minutes of it being created, this action is no longer available.",
+ "id": "to-update-a-cluster-1482863900595",
+ "title": "To update a cluster"
+ }
+ ],
+ "UpdateJob": [
+ {
+ "input": {
+ "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b",
+ "Description": "updated-job-name",
+ "JobId": "JID123e4567-e89b-12d3-a456-426655440000",
+ "ShippingOption": "NEXT_DAY",
+ "SnowballCapacityPreference": "T100"
+ },
+ "comments": {
+ },
+ "description": "This action allows you to update certain parameters for a job. Once the job changes to a different job state, usually within 60 minutes of the job being created, this action is no longer available.",
+ "id": "to-update-a-job-1482863556886",
+ "title": "To update a job"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/paginators-1.json
new file mode 100644
index 0000000000..05a7ea8482
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "ListJobs": {
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "result_key": "JobListEntries"
+ },
+ "DescribeAddresses": {
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "result_key": "Addresses"
+ },
+ "ListClusterJobs": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "JobListEntries"
+ },
+ "ListClusters": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ClusterListEntries"
+ },
+ "ListCompatibleImages": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CompatibleImages"
+ },
+ "ListLongTermPricing": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "LongTermPricingEntries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/service-2.json.gz
new file mode 100644
index 0000000000..87bb577f50
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/snowball/2016-06-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..335a8e53b4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/paginators-1.json
new file mode 100644
index 0000000000..5be5250dc6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/paginators-1.json
@@ -0,0 +1,46 @@
+{
+ "pagination": {
+ "ListEndpointsByPlatformApplication": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Endpoints"
+ },
+ "ListPlatformApplications": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "PlatformApplications"
+ },
+ "ListSubscriptions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Subscriptions"
+ },
+ "ListSubscriptionsByTopic": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Subscriptions"
+ },
+ "ListTopics": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Topics"
+ },
+ "ListPhoneNumbersOptedOut": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "result_key": "phoneNumbers"
+ },
+ "ListOriginationNumbers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PhoneNumbers"
+ },
+ "ListSMSSandboxPhoneNumbers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PhoneNumbers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/service-2.json.gz
new file mode 100644
index 0000000000..f8062e6f4a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sns/2010-03-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..11651c7b4a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/paginators-1.json
new file mode 100644
index 0000000000..7c22d43a95
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListDeadLetterSourceQueues": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "queueUrls"
+ },
+ "ListQueues": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "QueueUrls"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/service-2.json.gz
new file mode 100644
index 0000000000..64306e24b8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sqs/2012-11-05/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..aee2f47048
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/examples-1.json
new file mode 100644
index 0000000000..d7c714d8fe
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/examples-1.json
@@ -0,0 +1,714 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AcceptPage": [
+ {
+ "input": {
+ "AcceptCode": "425440",
+ "AcceptType": "READ",
+ "PageId": "arn:aws:ssm-contacts:us-east-2:682428703967:page/akuam/94ea0c7b-56d9-46c3-b84a-a37c8b067ad3"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following accept-page operation uses an accept code sent to the contact channel to accept a page.",
+ "id": "to-accept-a-page-during-and-engagement-1630357840187",
+ "title": "To accept a page during and engagement"
+ }
+ ],
+ "ActivateContactChannel": [
+ {
+ "input": {
+ "ActivationCode": "466136",
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following activate-contact-channel example activates a contact channel and makes it usable as part of an incident.",
+ "id": "activate-a-contacts-contact-channel-1630359780075",
+ "title": "Activate a contact's contact channel"
+ }
+ ],
+ "CreateContact": [
+ {
+ "input": {
+ "Alias": "akuam",
+ "DisplayName": "Akua Mansa",
+ "Plan": {
+ "Stages": [
+
+ ]
+ },
+ "Type": "PERSONAL"
+ },
+ "output": {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam"
+ },
+ "comments": {
+ },
+ "description": "The following create-contact example creates a contact in your environment with a blank plan. The plan can be updated after creating contact channels. Use the create-contact-channel operation with the output ARN of this command. After you have created contact channels for this contact use update-contact to update the plan.",
+ "id": "to-create-a-contact-1630360152750",
+ "title": "To create a contact"
+ }
+ ],
+ "CreateContactChannel": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam",
+ "DeliveryAddress": {
+ "SimpleAddress": "+15005550199"
+ },
+ "Name": "akuas sms-test",
+ "Type": "SMS"
+ },
+ "output": {
+ "ContactChannelArn": "arn:aws:ssm-contacts:us-east-1:111122223333:contact-channel/akuam/02f506b9-ea5d-4764-af89-2daa793ff024"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Creates a contact channel of type SMS for the contact Akua Mansa. Contact channels can be created of type SMS, EMAIL, or VOICE.",
+ "id": "to-create-a-contact-channel-1630360447010",
+ "title": "To create a contact channel"
+ }
+ ],
+ "DeactivateContactChannel": [
+ {
+ "input": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following ``deactivate-contact-channel`` example deactivates a contact channel. Deactivating a contact channel means the contact channel will no longer be paged during an incident. You can also reactivate a contact channel at any time using the activate-contact-channel operation.",
+ "id": "to-deactivate-a-contact-channel-1630360853894",
+ "title": "To deactivate a contact channel"
+ }
+ ],
+ "DeleteContact": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/alejr"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following delete-contact example deletes a contact. The contact will no longer be reachable from any escalation plan that refers to them.",
+ "id": "to-delete-a-contact-1630361093863",
+ "title": "To delete a contact"
+ }
+ ],
+ "DeleteContactChannel": [
+ {
+ "input": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-1:111122223333:contact-channel/akuam/13149bad-52ee-45ea-ae1e-45857f78f9b2"
+ },
+ "output": {
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following delete-contact-channel example deletes a contact channel. Deleting a contact channel ensures the contact channel will not be paged during an incident.",
+ "id": "to-delete-a-contact-channel-1630364616682",
+ "title": "To delete a contact channel"
+ }
+ ],
+ "DescribeEngagement": [
+ {
+ "input": {
+ "EngagementId": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/example_escalation/69e40ce1-8dbb-4d57-8962-5fbe7fc53356"
+ },
+ "output": {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/example_escalation",
+ "Content": "Testing engagements",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/example_escalation/69e40ce1-8dbb-4d57-8962-5fbe7fc53356",
+ "PublicContent": "Testing engagements",
+ "PublicSubject": "test",
+ "Sender": "tester",
+ "StartTime": "2021-05-18T18:25:41.151000+00:00",
+ "Subject": "test"
+ },
+ "comments": {
+ },
+ "description": "The following describe-engagement example lists the details of an engagement to a contact or escalation plan. The subject and content are sent to the contact channels.",
+ "id": "to-describe-the-details-of-an-engagement-1630364719475",
+ "title": "To describe the details of an engagement"
+ }
+ ],
+ "DescribePage": [
+ {
+ "input": {
+ "PageId": "arn:aws:ssm-contacts:us-east-2:111122223333:page/akuam/ad0052bd-e606-498a-861b-25726292eb93"
+ },
+ "output": {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "Content": "Testing engagements",
+ "DeliveryTime": "2021-05-18T18:43:55.265000+00:00",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/78a29753-3674-4ac5-9f83-0468563567f0",
+ "PageArn": "arn:aws:ssm-contacts:us-east-2:111122223333:page/akuam/ad0052bd-e606-498a-861b-25726292eb93",
+ "PublicContent": "Testing engagements",
+ "PublicSubject": "test",
+ "ReadTime": "2021-05-18T18:43:55.708000+00:00",
+ "Sender": "tester",
+ "SentTime": "2021-05-18T18:43:29.301000+00:00",
+ "Subject": "test"
+ },
+ "comments": {
+ },
+ "description": "The following describe-page example lists details of a page to a contact channel. The page will include the subject and content provided.",
+ "id": "to-list-the-details-of-a-page-to-a-contact-channel-1630364907282",
+ "title": "To list the details of a page to a contact channel"
+ }
+ ],
+ "GetContact": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam"
+ },
+ "output": {
+ "Alias": "akuam",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "DisplayName": "Akua Mansa",
+ "Plan": {
+ "Stages": [
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ChannelTargetInfo": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/beb25840-5ac8-4644-95cc-7a8de390fa65",
+ "RetryIntervalInMinutes": 1
+ }
+ }
+ ]
+ },
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ChannelTargetInfo": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/49f3c24d-5f9f-4638-ae25-3f49e04229ad",
+ "RetryIntervalInMinutes": 1
+ }
+ }
+ ]
+ },
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ChannelTargetInfo": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/77d4f447-f619-4954-afff-85551e369c2a",
+ "RetryIntervalInMinutes": 1
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "Type": "PERSONAL"
+ },
+ "comments": {
+ },
+ "description": "The following get-contact example describes a contact.",
+ "id": "example-1-to-describe-a-contact-plan-1630365360005",
+ "title": "Example 1: To describe a contact plan"
+ },
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/example_escalation"
+ },
+ "output": {
+ "Alias": "example_escalation",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/example_escalation",
+ "DisplayName": "Example Escalation Plan",
+ "Plan": {
+ "Stages": [
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ContactTargetInfo": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "IsEssential": true
+ }
+ }
+ ]
+ },
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ContactTargetInfo": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/alejr",
+ "IsEssential": false
+ }
+ }
+ ]
+ },
+ {
+ "DurationInMinutes": 0,
+ "Targets": [
+ {
+ "ContactTargetInfo": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/anasi",
+ "IsEssential": false
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "Type": "ESCALATION"
+ },
+ "comments": {
+ },
+ "description": "The following get-contact example describes an escalation plan.",
+ "id": "example-2-to-describe-an-escalation-plan-1630365515731",
+ "title": "Example 2: To describe an escalation plan"
+ }
+ ],
+ "GetContactChannel": [
+ {
+ "input": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d"
+ },
+ "output": {
+ "ActivationStatus": "ACTIVATED",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "ContactChannelArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d",
+ "DeliveryAddress": {
+ "SimpleAddress": "+15005550199"
+ },
+ "Name": "akuas sms",
+ "Type": "SMS"
+ },
+ "comments": {
+ },
+ "description": "The following get-contact-channel example lists the details of a contact channel.",
+ "id": "to-list-the-details-of-a-contact-channel-1630365682730",
+ "title": "To list the details of a contact channel"
+ }
+ ],
+ "GetContactPolicy": [
+ {
+ "input": {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam"
+ },
+ "output": {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam",
+ "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"SharePolicyForDocumentationDralia\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"222233334444\"},\"Action\":[\"ssm-contacts:GetContact\",\"ssm-contacts:StartEngagement\",\"ssm-contacts:DescribeEngagement\",\"ssm-contacts:ListPagesByEngagement\",\"ssm-contacts:StopEngagement\"],\"Resource\":[\"arn:aws:ssm-contacts:*:111122223333:contact/akuam\",\"arn:aws:ssm-contacts:*:111122223333:engagement/akuam/*\"]}]}"
+ },
+ "comments": {
+ },
+ "description": "The following get-contact-policy example lists the resource policies associated with the specified contact.",
+ "id": "to-list-the-details-of-a-contact-channel-1630365682730",
+ "title": "To list the resource policies of a contact"
+ }
+ ],
+ "ListContactChannels": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam"
+ },
+ "output": {
+ "ContactChannels": [
+ {
+ "ActivationStatus": "ACTIVATED",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "ContactChannelArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d",
+ "DeliveryAddress": {
+ "SimpleAddress": "+15005550100"
+ },
+ "Name": "akuas sms",
+ "Type": "SMS"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following list-contact-channels example lists the available contact channels of the specified contact.",
+ "id": "to-list-the-contact-channels-of-a-contact-1630366544252",
+ "title": "To list the contact channels of a contact"
+ }
+ ],
+ "ListContacts": [
+ {
+ "input": {
+ },
+ "output": {
+ "Contacts": [
+ {
+ "Alias": "akuam",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "DisplayName": "Akua Mansa",
+ "Type": "PERSONAL"
+ },
+ {
+ "Alias": "alejr",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/alejr",
+ "DisplayName": "Alejandro Rosalez",
+ "Type": "PERSONAL"
+ },
+ {
+ "Alias": "anasi",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/anasi",
+ "DisplayName": "Ana Carolina Silva",
+ "Type": "PERSONAL"
+ },
+ {
+ "Alias": "example_escalation",
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/example_escalation",
+ "DisplayName": "Example Escalation",
+ "Type": "ESCALATION"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following list-contacts example lists the contacts and escalation plans in your account.",
+ "id": "to-list-all-escalation-plans-and-contacts-1630367103082",
+ "title": "To list all escalation plans and contacts"
+ }
+ ],
+ "ListEngagements": [
+ {
+ "input": {
+ },
+ "output": {
+ "Engagements": [
+ {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/91792571-0b53-4821-9f73-d25d13d9e529",
+ "Sender": "cli",
+ "StartTime": "2021-05-18T20:37:50.300000+00:00"
+ },
+ {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/78a29753-3674-4ac5-9f83-0468563567f0",
+ "Sender": "cli",
+ "StartTime": "2021-05-18T18:40:26.666000+00:00"
+ },
+ {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/example_escalation",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/example_escalation/69e40ce1-8dbb-4d57-8962-5fbe7fc53356",
+ "Sender": "cli",
+ "StartTime": "2021-05-18T18:25:41.151000+00:00"
+ },
+ {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/607ced0e-e8fa-4ea7-8958-a237b8803f8f",
+ "Sender": "cli",
+ "StartTime": "2021-05-18T18:20:58.093000+00:00"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following list-engagements example lists engagements to escalation plans and contacts. You can also list engagements for a single incident.",
+ "id": "to-list-all-engagements-1630367432635",
+ "title": "To list all engagements"
+ }
+ ],
+ "ListPageReceipts": [
+ {
+ "input": {
+ "PageId": "arn:aws:ssm-contacts:us-east-2:111122223333:page/akuam/94ea0c7b-56d9-46c3-b84a-a37c8b067ad3"
+ },
+ "output": {
+ "Receipts": [
+ {
+ "ContactChannelArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d",
+ "ReceiptInfo": "425440",
+ "ReceiptTime": "2021-05-18T20:42:57.485000+00:00",
+ "ReceiptType": "DELIVERED"
+ },
+ {
+ "ContactChannelArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d",
+ "ReceiptInfo": "425440",
+ "ReceiptTime": "2021-05-18T20:42:57.907000+00:00",
+ "ReceiptType": "READ"
+ },
+ {
+ "ContactChannelArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/fc7405c4-46b2-48b7-87b2-93e2f225b90d",
+ "ReceiptInfo": "SM6656c19132f1465f9c9c1123a5dde7c9",
+ "ReceiptTime": "2021-05-18T20:40:52.962000+00:00",
+ "ReceiptType": "SENT"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following command-name example lists whether a page was received or not by a contact.",
+ "id": "to-list-page-receipts-1630367706869",
+ "title": "To list page receipts"
+ }
+ ],
+ "ListPagesByContact": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam"
+ },
+ "output": {
+ "Pages": [
+ {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "DeliveryTime": "2021-05-18T18:43:55.265000+00:00",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/78a29753-3674-4ac5-9f83-0468563567f0",
+ "PageArn": "arn:aws:ssm-contacts:us-east-2:111122223333:page/akuam/ad0052bd-e606-498a-861b-25726292eb93",
+ "ReadTime": "2021-05-18T18:43:55.708000+00:00",
+ "Sender": "cli",
+ "SentTime": "2021-05-18T18:43:29.301000+00:00"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following list-pages-by-contact example lists all pages to the specified contact.",
+ "id": "to-list-pages-by-contact-1630435789132",
+ "title": "To list pages by contact"
+ }
+ ],
+ "ListPagesByEngagement": [
+ {
+ "input": {
+ "EngagementId": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/78a29753-3674-4ac5-9f83-0468563567f0"
+ },
+ "output": {
+ "Pages": [
+ {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/78a29753-3674-4ac5-9f83-0468563567f0",
+ "PageArn": "arn:aws:ssm-contacts:us-east-2:111122223333:page/akuam/ad0052bd-e606-498a-861b-25726292eb93",
+ "Sender": "cli",
+ "SentTime": "2021-05-18T18:40:27.245000+00:00"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following list-pages-by-engagement example lists the pages that occurred while engaging the defined engagement plan.",
+ "id": "to-list-pages-to-contact-channels-started-from-an-engagement-1630435864674",
+ "title": "To list pages to contact channels started from an engagement."
+ }
+ ],
+ "ListTagsForResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam"
+ },
+ "output": {
+ "Tags": [
+ {
+ "Key": "group1",
+ "Value": "1"
+ }
+ ]
+ },
+ "comments": {
+ },
+ "description": "The following list-tags-for-resource example lists the tags of the specified contact.",
+ "id": "to-list-tags-for-a-contact-1630436051681",
+ "title": "To list tags for a contact"
+ }
+ ],
+ "PutContactPolicy": [
+ {
+ "input": {
+ "ContactArn": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam",
+ "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"ExampleResourcePolicy\",\"Action\":[\"ssm-contacts:GetContact\",\"ssm-contacts:StartEngagement\",\"ssm-contacts:DescribeEngagement\",\"ssm-contacts:ListPagesByEngagement\",\"ssm-contacts:StopEngagement\"],\"Principal\":{\"AWS\":\"222233334444\"},\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:ssm-contacts:*:111122223333:contact/akuam\",\"arn:aws:ssm-contacts:*:111122223333:engagement/akuam/*\"]}]}"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following put-contact-policy example adds a resource policy to the contact Akua that shares the contact and related engagements with the principal.",
+ "id": "to-share-a-contact-and-engagements-1630436278898",
+ "title": "To share a contact and engagements"
+ }
+ ],
+ "SendActivationCode": [
+ {
+ "input": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-1:111122223333:contact-channel/akuam/8ddae2d1-12c8-4e45-b852-c8587266c400"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following send-activation-code example sends an activation code and message to the specified contact channel.",
+ "id": "to-send-an-activation-code-1630436453574",
+ "title": "To send an activation code"
+ }
+ ],
+ "StartEngagement": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "Content": "Testing engagements",
+ "PublicContent": "Testing engagements",
+ "PublicSubject": "test",
+ "Sender": "tester",
+ "Subject": "test"
+ },
+ "output": {
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/akuam/607ced0e-e8fa-4ea7-8958-a237b8803f8f"
+ },
+ "comments": {
+ },
+ "description": "The following start-engagement pages contact's contact channels. Sender, subject, public-subject, and public-content are all free from fields. Incident Manager sends the subject and content to the provided VOICE or EMAIL contact channels. Incident Manager sends the public-subject and public-content to the provided SMS contact channels. Sender is used to track who started the engagement.",
+ "id": "example-1-to-page-a-contacts-contact-channels-1630436634872",
+ "title": "Example 1: To page a contact's contact channels"
+ },
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/example_escalation",
+ "Content": "Testing engagements",
+ "PublicContent": "Testing engagements",
+ "PublicSubject": "test",
+ "Sender": "tester",
+ "Subject": "test"
+ },
+ "output": {
+ "EngagementArn": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/example_escalation/69e40ce1-8dbb-4d57-8962-5fbe7fc53356"
+ },
+ "comments": {
+ },
+ "description": "The following start-engagement engages contact's through an escalation plan. Each contact is paged according to their engagement plan.",
+ "id": "example-2-to-page-a-contact-in-the-provided-escalation-plan-1630436808480",
+ "title": "Example 2: To page a contact in the provided escalation plan."
+ }
+ ],
+ "StopEngagement": [
+ {
+ "input": {
+ "EngagementId": "arn:aws:ssm-contacts:us-east-2:111122223333:engagement/example_escalation/69e40ce1-8dbb-4d57-8962-5fbe7fc53356"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following stop-engagement example stops an engagement from paging further contacts and contact channels.",
+ "id": "to-stop-an-engagement-1630436882864",
+ "title": "To stop an engagement"
+ }
+ ],
+ "TagResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam",
+ "Tags": [
+ {
+ "Key": "group1",
+ "Value": "1"
+ }
+ ]
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following tag-resource example tags a specified contact with the provided tag key value pair.",
+ "id": "to-tag-a-contact-1630437124572",
+ "title": "To tag a contact"
+ }
+ ],
+ "UntagResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:ssm-contacts:us-east-1:111122223333:contact/akuam",
+ "TagKeys": [
+ "group1"
+ ]
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following untag-resource example removes the group1 tag from the specified contact.",
+ "id": "to-remove-tags-from-a-contact-1630437251110",
+ "title": "To remove tags from a contact"
+ }
+ ],
+ "UpdateContact": [
+ {
+ "input": {
+ "ContactId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact/akuam",
+ "Plan": {
+ "Stages": [
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ChannelTargetInfo": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/beb25840-5ac8-4644-95cc-7a8de390fa65",
+ "RetryIntervalInMinutes": 1
+ }
+ }
+ ]
+ },
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ChannelTargetInfo": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/49f3c24d-5f9f-4638-ae25-3f49e04229ad",
+ "RetryIntervalInMinutes": 1
+ }
+ }
+ ]
+ },
+ {
+ "DurationInMinutes": 5,
+ "Targets": [
+ {
+ "ChannelTargetInfo": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/77d4f447-f619-4954-afff-85551e369c2a",
+ "RetryIntervalInMinutes": 1
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following update-contact example updates the engagement plan of the contact Akua to include the three types of contacts channels. This is done after creating contact channels for Akua.",
+ "id": "to-update-the-engagement-plan-of-contact-1630437436599",
+ "title": "To update the engagement plan of contact"
+ }
+ ],
+ "UpdateContactChannel": [
+ {
+ "input": {
+ "ContactChannelId": "arn:aws:ssm-contacts:us-east-2:111122223333:contact-channel/akuam/49f3c24d-5f9f-4638-ae25-3f49e04229ad",
+ "DeliveryAddress": {
+ "SimpleAddress": "+15005550198"
+ },
+ "Name": "akuas voice channel"
+ },
+ "output": {
+ },
+ "comments": {
+ },
+ "description": "The following update-contact-channel example updates the name and delivery address of a contact channel.",
+ "id": "to-update-a-contact-channel-1630437610256",
+ "title": "To update a contact channel"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/paginators-1.json
new file mode 100644
index 0000000000..621bde80ed
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/paginators-1.json
@@ -0,0 +1,69 @@
+{
+ "pagination": {
+ "ListContactChannels": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ContactChannels"
+ },
+ "ListContacts": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Contacts"
+ },
+ "ListEngagements": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Engagements"
+ },
+ "ListPageReceipts": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Receipts"
+ },
+ "ListPagesByContact": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Pages"
+ },
+ "ListPagesByEngagement": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Pages"
+ },
+ "ListPageResolutions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "PageResolutions"
+ },
+ "ListPreviewRotationShifts": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "RotationShifts"
+ },
+ "ListRotationOverrides": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "RotationOverrides"
+ },
+ "ListRotationShifts": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "RotationShifts"
+ },
+ "ListRotations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Rotations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/service-2.json.gz
new file mode 100644
index 0000000000..08371fb078
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-contacts/2021-05-03/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..45a71afc2d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..662c714f11
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/paginators-1.json
@@ -0,0 +1,46 @@
+{
+ "pagination": {
+ "GetResourcePolicies": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "resourcePolicies"
+ },
+ "ListIncidentRecords": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "incidentRecordSummaries"
+ },
+ "ListRelatedItems": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "relatedItems"
+ },
+ "ListReplicationSets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "replicationSetArns"
+ },
+ "ListResponsePlans": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "responsePlanSummaries"
+ },
+ "ListTimelineEvents": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "eventSummaries"
+ },
+ "ListIncidentFindings": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "findings"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..447866f74a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/waiters-2.json
new file mode 100644
index 0000000000..47c19b3a70
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-incidents/2018-05-10/waiters-2.json
@@ -0,0 +1,53 @@
+{
+ "version" : 2,
+ "waiters" : {
+ "WaitForReplicationSetActive" : {
+ "description" : "Wait for a replication set to become ACTIVE",
+ "delay" : 30,
+ "maxAttempts" : 5,
+ "operation" : "GetReplicationSet",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "replicationSet.status",
+ "state" : "success",
+ "expected" : "ACTIVE"
+ }, {
+ "matcher" : "path",
+ "argument" : "replicationSet.status",
+ "state" : "retry",
+ "expected" : "CREATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "replicationSet.status",
+ "state" : "retry",
+ "expected" : "UPDATING"
+ }, {
+ "matcher" : "path",
+ "argument" : "replicationSet.status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ },
+ "WaitForReplicationSetDeleted" : {
+ "description" : "Wait for a replication set to be deleted",
+ "delay" : 30,
+ "maxAttempts" : 5,
+ "operation" : "GetReplicationSet",
+ "acceptors" : [ {
+ "matcher" : "error",
+ "state" : "success",
+ "expected" : "ResourceNotFoundException"
+ }, {
+ "matcher" : "path",
+ "argument" : "replicationSet.status",
+ "state" : "retry",
+ "expected" : "DELETING"
+ }, {
+ "matcher" : "path",
+ "argument" : "replicationSet.status",
+ "state" : "failure",
+ "expected" : "FAILED"
+ } ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..d29ba82ab5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/paginators-1.json
new file mode 100644
index 0000000000..1b25777b54
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListApplications": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Applications"
+ },
+ "ListComponents": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Components"
+ },
+ "ListDatabases": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Databases"
+ },
+ "ListOperations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Operations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/service-2.json.gz
new file mode 100644
index 0000000000..756fc6c3e2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm-sap/2018-05-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2fab372d32
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/paginators-1.json
new file mode 100644
index 0000000000..871cef8b47
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/paginators-1.json
@@ -0,0 +1,286 @@
+{
+ "pagination": {
+ "ListAssociations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Associations"
+ },
+ "ListCommandInvocations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "CommandInvocations"
+ },
+ "ListCommands": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Commands"
+ },
+ "ListDocuments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DocumentIdentifiers"
+ },
+ "DescribeInstanceInformation": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "InstanceInformationList"
+ },
+ "DescribeActivations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ActivationList"
+ },
+ "DescribeParameters": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Parameters"
+ },
+ "DescribeAssociationExecutions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AssociationExecutions"
+ },
+ "DescribeAssociationExecutionTargets": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AssociationExecutionTargets"
+ },
+ "GetInventory": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Entities"
+ },
+ "GetParametersByPath": {
+ "result_key": "Parameters",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "GetParameterHistory": {
+ "result_key": "Parameters",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "DescribeAutomationExecutions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AutomationExecutionMetadataList"
+ },
+ "DescribeAutomationStepExecutions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "StepExecutions"
+ },
+ "DescribeAvailablePatches": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Patches"
+ },
+ "DescribeEffectiveInstanceAssociations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Associations"
+ },
+ "DescribeEffectivePatchesForPatchBaseline": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "EffectivePatches"
+ },
+ "DescribeInstanceAssociationsStatus": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "InstanceAssociationStatusInfos"
+ },
+ "DescribeInstancePatchStates": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "InstancePatchStates"
+ },
+ "DescribeInstancePatchStatesForPatchGroup": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "InstancePatchStates"
+ },
+ "DescribeInstancePatches": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Patches"
+ },
+ "DescribeInventoryDeletions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "InventoryDeletions"
+ },
+ "DescribeMaintenanceWindowExecutionTaskInvocations": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "WindowExecutionTaskInvocationIdentities"
+ },
+ "DescribeMaintenanceWindowExecutionTasks": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "WindowExecutionTaskIdentities"
+ },
+ "DescribeMaintenanceWindowExecutions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "WindowExecutions"
+ },
+ "DescribeMaintenanceWindowSchedule": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ScheduledWindowExecutions"
+ },
+ "DescribeMaintenanceWindowTargets": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Targets"
+ },
+ "DescribeMaintenanceWindowTasks": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Tasks"
+ },
+ "DescribeMaintenanceWindows": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "WindowIdentities"
+ },
+ "DescribeMaintenanceWindowsForTarget": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "WindowIdentities"
+ },
+ "DescribePatchBaselines": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "BaselineIdentities"
+ },
+ "DescribePatchGroups": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Mappings"
+ },
+ "DescribeSessions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Sessions"
+ },
+ "GetInventorySchema": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Schemas"
+ },
+ "ListAssociationVersions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AssociationVersions"
+ },
+ "ListComplianceItems": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ComplianceItems"
+ },
+ "ListComplianceSummaries": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ComplianceSummaryItems"
+ },
+ "ListDocumentVersions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "DocumentVersions"
+ },
+ "ListResourceComplianceSummaries": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ResourceComplianceSummaryItems"
+ },
+ "ListResourceDataSync": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ResourceDataSyncItems"
+ },
+ "DescribeOpsItems": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "OpsItemSummaries"
+ },
+ "DescribePatchProperties": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Properties"
+ },
+ "GetOpsSummary": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Entities"
+ },
+ "ListOpsItemEvents": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Summaries"
+ },
+ "ListOpsMetadata": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "OpsMetadataList"
+ },
+ "ListOpsItemRelatedItems": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Summaries"
+ },
+ "GetResourcePolicies": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Policies"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/service-2.json.gz
new file mode 100644
index 0000000000..ee270fbbd7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/waiters-2.json
new file mode 100644
index 0000000000..43f5237f89
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/ssm/2014-11-06/waiters-2.json
@@ -0,0 +1,65 @@
+{
+ "version": 2,
+ "waiters": {
+ "CommandExecuted": {
+ "delay": 5,
+ "operation": "GetCommandInvocation",
+ "maxAttempts": 20,
+ "acceptors": [
+ {
+ "expected": "Pending",
+ "matcher": "path",
+ "state": "retry",
+ "argument": "Status"
+ },
+ {
+ "expected": "InProgress",
+ "matcher": "path",
+ "state": "retry",
+ "argument": "Status"
+ },
+ {
+ "expected": "Delayed",
+ "matcher": "path",
+ "state": "retry",
+ "argument": "Status"
+ },
+ {
+ "expected": "Success",
+ "matcher": "path",
+ "state": "success",
+ "argument": "Status"
+ },
+ {
+ "expected": "Cancelled",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "Status"
+ },
+ {
+ "expected": "TimedOut",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "Status"
+ },
+ {
+ "expected": "Failed",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "Status"
+ },
+ {
+ "expected": "Cancelling",
+ "matcher": "path",
+ "state": "failure",
+ "argument": "Status"
+ },
+ {
+ "state": "retry",
+ "matcher": "error",
+ "expected": "InvocationDoesNotExist"
+ }
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..63461286c0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/paginators-1.json
new file mode 100644
index 0000000000..d2c8b68794
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/paginators-1.json
@@ -0,0 +1,121 @@
+{
+ "pagination": {
+ "ListAccountAssignmentCreationStatus": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AccountAssignmentsCreationStatus"
+ },
+ "ListAccountAssignmentDeletionStatus": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AccountAssignmentsDeletionStatus"
+ },
+ "ListAccountAssignments": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AccountAssignments"
+ },
+ "ListAccountsForProvisionedPermissionSet": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AccountIds"
+ },
+ "ListInstances": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Instances"
+ },
+ "ListManagedPoliciesInPermissionSet": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "AttachedManagedPolicies"
+ },
+ "ListPermissionSetProvisioningStatus": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PermissionSetsProvisioningStatus"
+ },
+ "ListPermissionSets": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PermissionSets"
+ },
+ "ListPermissionSetsProvisionedToAccount": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "PermissionSets"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ },
+ "ListCustomerManagedPolicyReferencesInPermissionSet": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "CustomerManagedPolicyReferences"
+ },
+ "ListAccountAssignmentsForPrincipal": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AccountAssignments"
+ },
+ "ListApplicationAccessScopes": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Scopes"
+ },
+ "ListApplicationAssignments": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ApplicationAssignments"
+ },
+ "ListApplicationAssignmentsForPrincipal": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ApplicationAssignments"
+ },
+ "ListApplicationAuthenticationMethods": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "AuthenticationMethods"
+ },
+ "ListApplicationGrants": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Grants"
+ },
+ "ListApplicationProviders": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "ApplicationProviders"
+ },
+ "ListApplications": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Applications"
+ },
+ "ListTrustedTokenIssuers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "TrustedTokenIssuers"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/service-2.json.gz
new file mode 100644
index 0000000000..6b29960c8a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-admin/2020-07-20/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e71cd806cd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/service-2.json.gz
new file mode 100644
index 0000000000..a457608dc3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso-oidc/2019-06-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..a61f80d932
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/paginators-1.json
new file mode 100644
index 0000000000..daaed6fe69
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListAccountRoles": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "roleList"
+ },
+ "ListAccounts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "accountList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/service-2.json.gz
new file mode 100644
index 0000000000..7af2d06695
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sso/2019-06-10/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5fb8cf8db4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/paginators-1.json
new file mode 100644
index 0000000000..fb8eb5e586
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "GetExecutionHistory": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "events"
+ },
+ "ListActivities": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "activities"
+ },
+ "ListExecutions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "executions"
+ },
+ "ListStateMachines": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "stateMachines"
+ },
+ "ListMapRuns": {
+ "input_token": "nextToken",
+ "limit_key": "maxResults",
+ "output_token": "nextToken",
+ "result_key": "mapRuns"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/service-2.json.gz
new file mode 100644
index 0000000000..99e2b12867
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/stepfunctions/2016-11-23/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..416638c605
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/examples-1.json
new file mode 100644
index 0000000000..7cc0d7d410
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/examples-1.json
@@ -0,0 +1,1381 @@
+{
+ "version": "1.0",
+ "examples": {
+ "ActivateGateway": [
+ {
+ "input": {
+ "ActivationKey": "29AV1-3OFV9-VVIUB-NKT0I-LRO6V",
+ "GatewayName": "My_Gateway",
+ "GatewayRegion": "us-east-1",
+ "GatewayTimezone": "GMT-12:00",
+ "GatewayType": "STORED",
+ "MediumChangerType": "AWS-Gateway-VTL",
+ "TapeDriveType": "IBM-ULT3580-TD5"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Activates the gateway you previously deployed on your host.",
+ "id": "to-activate-the-gateway-1471281611207",
+ "title": "To activate the gateway"
+ }
+ ],
+ "AddCache": [
+ {
+ "input": {
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:03:00.0-scsi-0:0:1:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example shows a request that activates a gateway-stored volume.",
+ "id": "to-add-a-cache-1471043606854",
+ "title": "To add a cache"
+ }
+ ],
+ "AddTagsToResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B",
+ "Tags": [
+ {
+ "Key": "Dev Gatgeway Region",
+ "Value": "East Coast"
+ }
+ ]
+ },
+ "output": {
+ "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Adds one or more tags to the specified resource.",
+ "id": "to-add-tags-to-resource-1471283689460",
+ "title": "To add tags to resource"
+ }
+ ],
+ "AddUploadBuffer": [
+ {
+ "input": {
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:03:00.0-scsi-0:0:1:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Configures one or more gateway local disks as upload buffer for a specified gateway.",
+ "id": "to-add-upload-buffer-on-local-disk-1471293902847",
+ "title": "To add upload buffer on local disk"
+ }
+ ],
+ "AddWorkingStorage": [
+ {
+ "input": {
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:03:00.0-scsi-0:0:1:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Configures one or more gateway local disks as working storage for a gateway. (Working storage is also referred to as upload buffer.)",
+ "id": "to-add-storage-on-local-disk-1471294305401",
+ "title": "To add storage on local disk"
+ }
+ ],
+ "CancelArchival": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4"
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Cancels archiving of a virtual tape to the virtual tape shelf (VTS) after the archiving process is initiated.",
+ "id": "to-cancel-virtual-tape-archiving-1471294865203",
+ "title": "To cancel virtual tape archiving"
+ }
+ ],
+ "CancelRetrieval": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4"
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Cancels retrieval of a virtual tape from the virtual tape shelf (VTS) to a gateway after the retrieval process is initiated.",
+ "id": "to-cancel-virtual-tape-retrieval-1471295704491",
+ "title": "To cancel virtual tape retrieval"
+ }
+ ],
+ "CreateCachediSCSIVolume": [
+ {
+ "input": {
+ "ClientToken": "cachedvol112233",
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "NetworkInterfaceId": "10.1.1.1",
+ "SnapshotId": "snap-f47b7b94",
+ "TargetName": "my-volume",
+ "VolumeSizeInBytes": 536870912000
+ },
+ "output": {
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Creates a cached volume on a specified cached gateway.",
+ "id": "to-create-a-cached-iscsi-volume-1471296661787",
+ "title": "To create a cached iSCSI volume"
+ }
+ ],
+ "CreateSnapshot": [
+ {
+ "input": {
+ "SnapshotDescription": "My root volume snapshot as of 10/03/2017",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "output": {
+ "SnapshotId": "snap-78e22663",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Initiates an ad-hoc snapshot of a gateway volume.",
+ "id": "to-create-a-snapshot-of-a-gateway-volume-1471301469561",
+ "title": "To create a snapshot of a gateway volume"
+ }
+ ],
+ "CreateSnapshotFromVolumeRecoveryPoint": [
+ {
+ "input": {
+ "SnapshotDescription": "My root volume snapshot as of 2017-06-30T10:10:10.000Z",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "output": {
+ "SnapshotId": "snap-78e22663",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB",
+ "VolumeRecoveryPointTime": "2017-06-30T10:10:10.000Z"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Initiates a snapshot of a gateway from a volume recovery point.",
+ "id": "to-create-a-snapshot-of-a-gateway-volume-1471301469561",
+ "title": "To create a snapshot of a gateway volume"
+ }
+ ],
+ "CreateStorediSCSIVolume": [
+ {
+ "input": {
+ "DiskId": "pci-0000:03:00.0-scsi-0:0:0:0",
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "NetworkInterfaceId": "10.1.1.1",
+ "PreserveExistingData": true,
+ "SnapshotId": "snap-f47b7b94",
+ "TargetName": "my-volume"
+ },
+ "output": {
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB",
+ "VolumeSizeInBytes": 1099511627776
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Creates a stored volume on a specified stored gateway.",
+ "id": "to-create-a-stored-iscsi-volume-1471367662813",
+ "title": "To create a stored iSCSI volume"
+ }
+ ],
+ "CreateTapeWithBarcode": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "TapeBarcode": "TEST12345",
+ "TapeSizeInBytes": 107374182400
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST12345"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Creates a virtual tape by using your own barcode.",
+ "id": "to-create-a-virtual-tape-using-a-barcode-1471371842452",
+ "title": "To create a virtual tape using a barcode"
+ }
+ ],
+ "CreateTapes": [
+ {
+ "input": {
+ "ClientToken": "77777",
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "NumTapesToCreate": 3,
+ "TapeBarcodePrefix": "TEST",
+ "TapeSizeInBytes": 107374182400
+ },
+ "output": {
+ "TapeARNs": [
+ "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST38A29D",
+ "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST3AA29F",
+ "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST3BA29E"
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Creates one or more virtual tapes.",
+ "id": "to-create-a-virtual-tape-1471372061659",
+ "title": "To create a virtual tape"
+ }
+ ],
+ "DeleteBandwidthRateLimit": [
+ {
+ "input": {
+ "BandwidthType": "All",
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Deletes the bandwidth rate limits of a gateway; either the upload or download limit, or both.",
+ "id": "to-delete-bandwidth-rate-limits-of-gateway-1471373225520",
+ "title": "To delete bandwidth rate limits of gateway"
+ }
+ ],
+ "DeleteChapCredentials": [
+ {
+ "input": {
+ "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com",
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ },
+ "output": {
+ "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com",
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Deletes Challenge-Handshake Authentication Protocol (CHAP) credentials for a specified iSCSI target and initiator pair.",
+ "id": "to-delete-chap-credentials-1471375025612",
+ "title": "To delete CHAP credentials"
+ }
+ ],
+ "DeleteGateway": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation deletes the gateway, but not the gateway's VM from the host computer.",
+ "id": "to-delete-a-gatgeway-1471381697333",
+ "title": "To delete a gatgeway"
+ }
+ ],
+ "DeleteSnapshotSchedule": [
+ {
+ "input": {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "output": {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This action enables you to delete a snapshot schedule for a volume.",
+ "id": "to-delete-a-snapshot-of-a-volume-1471382234377",
+ "title": "To delete a snapshot of a volume"
+ }
+ ],
+ "DeleteTape": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:204469490176:gateway/sgw-12A3456B",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0"
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example deletes the specified virtual tape.",
+ "id": "to-delete-a-virtual-tape-1471382444157",
+ "title": "To delete a virtual tape"
+ }
+ ],
+ "DeleteTapeArchive": [
+ {
+ "input": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0"
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Deletes the specified virtual tape from the virtual tape shelf (VTS).",
+ "id": "to-delete-a-virtual-tape-from-the-shelf-vts-1471383964329",
+ "title": "To delete a virtual tape from the shelf (VTS)"
+ }
+ ],
+ "DeleteVolume": [
+ {
+ "input": {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "output": {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Deletes the specified gateway volume that you previously created using the CreateCachediSCSIVolume or CreateStorediSCSIVolume API.",
+ "id": "to-delete-a-gateway-volume-1471384418416",
+ "title": "To delete a gateway volume"
+ }
+ ],
+ "DescribeBandwidthRateLimit": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "AverageDownloadRateLimitInBitsPerSec": 204800,
+ "AverageUploadRateLimitInBitsPerSec": 102400,
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a value for a bandwidth rate limit if set. If not set, then only the gateway ARN is returned.",
+ "id": "to-describe-the-bandwidth-rate-limits-of-a-gateway-1471384826404",
+ "title": "To describe the bandwidth rate limits of a gateway"
+ }
+ ],
+ "DescribeCache": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "CacheAllocatedInBytes": 2199023255552,
+ "CacheDirtyPercentage": 0.07,
+ "CacheHitPercentage": 99.68,
+ "CacheMissPercentage": 0.32,
+ "CacheUsedPercentage": 0.07,
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:04:00.0-scsi-0:1:0:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns information about the cache of a gateway.",
+ "id": "to-describe-cache-information-1471385756036",
+ "title": "To describe cache information"
+ }
+ ],
+ "DescribeCachediSCSIVolumes": [
+ {
+ "input": {
+ "VolumeARNs": [
+ "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ ]
+ },
+ "output": {
+ "CachediSCSIVolumes": [
+ {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB",
+ "VolumeId": "vol-1122AABB",
+ "VolumeSizeInBytes": 1099511627776,
+ "VolumeStatus": "AVAILABLE",
+ "VolumeType": "CACHED iSCSI",
+ "VolumeiSCSIAttributes": {
+ "ChapEnabled": true,
+ "LunNumber": 1,
+ "NetworkInterfaceId": "10.243.43.207",
+ "NetworkInterfacePort": 3260,
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ }
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a description of the gateway cached iSCSI volumes specified in the request.",
+ "id": "to-describe-gateway-cached-iscsi-volumes-1471458094649",
+ "title": "To describe gateway cached iSCSI volumes"
+ }
+ ],
+ "DescribeChapCredentials": [
+ {
+ "input": {
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ },
+ "output": {
+ "ChapCredentials": [
+ {
+ "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com",
+ "SecretToAuthenticateInitiator": "111111111111",
+ "SecretToAuthenticateTarget": "222222222222",
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns an array of Challenge-Handshake Authentication Protocol (CHAP) credentials information for a specified iSCSI target, one for each target-initiator pair.",
+ "id": "to-describe-chap-credetnitals-for-an-iscsi-1471467462967",
+ "title": "To describe CHAP credetnitals for an iSCSI"
+ }
+ ],
+ "DescribeGatewayInformation": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "GatewayId": "sgw-AABB1122",
+ "GatewayName": "My_Gateway",
+ "GatewayNetworkInterfaces": [
+ {
+ "Ipv4Address": "10.35.69.216"
+ }
+ ],
+ "GatewayState": "STATE_RUNNING",
+ "GatewayTimezone": "GMT-8:00",
+ "GatewayType": "STORED",
+ "LastSoftwareUpdate": "2016-01-02T16:00:00",
+ "NextUpdateAvailabilityDate": "2017-01-02T16:00:00"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns metadata about a gateway such as its name, network interfaces, configured time zone, and the state (whether the gateway is running or not).",
+ "id": "to-describe-metadata-about-the-gateway-1471467849079",
+ "title": "To describe metadata about the gateway"
+ }
+ ],
+ "DescribeMaintenanceStartTime": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "DayOfWeek": 2,
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "HourOfDay": 15,
+ "MinuteOfHour": 35,
+ "Timezone": "GMT+7:00"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns your gateway's weekly maintenance start time including the day and time of the week.",
+ "id": "to-describe-gateways-maintenance-start-time-1471470727387",
+ "title": "To describe gateway's maintenance start time"
+ }
+ ],
+ "DescribeSnapshotSchedule": [
+ {
+ "input": {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "output": {
+ "Description": "sgw-AABB1122:vol-AABB1122:Schedule",
+ "RecurrenceInHours": 24,
+ "StartAt": 6,
+ "Timezone": "GMT+7:00",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Describes the snapshot schedule for the specified gateway volume including intervals at which snapshots are automatically initiated.",
+ "id": "to-describe-snapshot-schedule-for-gateway-volume-1471471139538",
+ "title": "To describe snapshot schedule for gateway volume"
+ }
+ ],
+ "DescribeStorediSCSIVolumes": [
+ {
+ "input": {
+ "VolumeARNs": [
+ "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ ]
+ },
+ "output": {
+ "StorediSCSIVolumes": [
+ {
+ "PreservedExistingData": false,
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB",
+ "VolumeDiskId": "pci-0000:03:00.0-scsi-0:0:0:0",
+ "VolumeId": "vol-1122AABB",
+ "VolumeProgress": 23.7,
+ "VolumeSizeInBytes": 1099511627776,
+ "VolumeStatus": "BOOTSTRAPPING",
+ "VolumeiSCSIAttributes": {
+ "ChapEnabled": true,
+ "NetworkInterfaceId": "10.243.43.207",
+ "NetworkInterfacePort": 3260,
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ }
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns the description of the gateway volumes specified in the request belonging to the same gateway.",
+ "id": "to-describe-the-volumes-of-a-gateway-1471472640660",
+ "title": "To describe the volumes of a gateway"
+ }
+ ],
+ "DescribeTapeArchives": [
+ {
+ "input": {
+ "Limit": 123,
+ "Marker": "1",
+ "TapeARNs": [
+ "arn:aws:storagegateway:us-east-1:999999999999:tape/AM08A1AD",
+ "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4"
+ ]
+ },
+ "output": {
+ "Marker": "1",
+ "TapeArchives": [
+ {
+ "CompletionTime": "2016-12-16T13:50Z",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999:tape/AM08A1AD",
+ "TapeBarcode": "AM08A1AD",
+ "TapeSizeInBytes": 107374182400,
+ "TapeStatus": "ARCHIVED"
+ },
+ {
+ "CompletionTime": "2016-12-16T13:59Z",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999:tape/AMZN01A2A4",
+ "TapeBarcode": "AMZN01A2A4",
+ "TapeSizeInBytes": 429496729600,
+ "TapeStatus": "ARCHIVED"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a description of specified virtual tapes in the virtual tape shelf (VTS).",
+ "id": "to-describe-virtual-tapes-in-the-vts-1471473188198",
+ "title": "To describe virtual tapes in the VTS"
+ }
+ ],
+ "DescribeTapeRecoveryPoints": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "Limit": 1,
+ "Marker": "1"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "Marker": "1",
+ "TapeRecoveryPointInfos": [
+ {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999:tape/AMZN01A2A4",
+ "TapeRecoveryPointTime": "2016-12-16T13:50Z",
+ "TapeSizeInBytes": 1471550497,
+ "TapeStatus": "AVAILABLE"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a list of virtual tape recovery points that are available for the specified gateway-VTL.",
+ "id": "to-describe-virtual-tape-recovery-points-1471542042026",
+ "title": "To describe virtual tape recovery points"
+ }
+ ],
+ "DescribeTapes": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "Limit": 2,
+ "Marker": "1",
+ "TapeARNs": [
+ "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST04A2A1",
+ "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST05A2A0"
+ ]
+ },
+ "output": {
+ "Marker": "1",
+ "Tapes": [
+ {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST04A2A1",
+ "TapeBarcode": "TEST04A2A1",
+ "TapeSizeInBytes": 107374182400,
+ "TapeStatus": "AVAILABLE"
+ },
+ {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST05A2A0",
+ "TapeBarcode": "TEST05A2A0",
+ "TapeSizeInBytes": 107374182400,
+ "TapeStatus": "AVAILABLE"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a description of the specified Amazon Resource Name (ARN) of virtual tapes. If a TapeARN is not specified, returns a description of all virtual tapes.",
+ "id": "to-describe-virtual-tapes-associated-with-gateway-1471629287727",
+ "title": "To describe virtual tape(s) associated with gateway"
+ }
+ ],
+ "DescribeUploadBuffer": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:04:00.0-scsi-0:1:0:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "UploadBufferAllocatedInBytes": 0,
+ "UploadBufferUsedInBytes": 161061273600
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns information about the upload buffer of a gateway including disk IDs and the amount of upload buffer space allocated/used.",
+ "id": "to-describe-upload-buffer-of-gateway-1471631099003",
+ "title": "To describe upload buffer of gateway"
+ },
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:04:00.0-scsi-0:1:0:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "UploadBufferAllocatedInBytes": 161061273600,
+ "UploadBufferUsedInBytes": 0
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns information about the upload buffer of a gateway including disk IDs and the amount of upload buffer space allocated and used.",
+ "id": "to-describe-upload-buffer-of-a-gateway--1471904566370",
+ "title": "To describe upload buffer of a gateway"
+ }
+ ],
+ "DescribeVTLDevices": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "Limit": 123,
+ "Marker": "1",
+ "VTLDeviceARNs": [
+
+ ]
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "Marker": "1",
+ "VTLDevices": [
+ {
+ "DeviceiSCSIAttributes": {
+ "ChapEnabled": false,
+ "NetworkInterfaceId": "10.243.43.207",
+ "NetworkInterfacePort": 3260,
+ "TargetARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:sgw-1fad4876-mediachanger"
+ },
+ "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_MEDIACHANGER_00001",
+ "VTLDeviceProductIdentifier": "L700",
+ "VTLDeviceType": "Medium Changer",
+ "VTLDeviceVendor": "STK"
+ },
+ {
+ "DeviceiSCSIAttributes": {
+ "ChapEnabled": false,
+ "NetworkInterfaceId": "10.243.43.209",
+ "NetworkInterfacePort": 3260,
+ "TargetARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:sgw-1fad4876-tapedrive-01"
+ },
+ "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_TAPEDRIVE_00001",
+ "VTLDeviceProductIdentifier": "ULT3580-TD5",
+ "VTLDeviceType": "Tape Drive",
+ "VTLDeviceVendor": "IBM"
+ },
+ {
+ "DeviceiSCSIAttributes": {
+ "ChapEnabled": false,
+ "NetworkInterfaceId": "10.243.43.209",
+ "NetworkInterfacePort": 3260,
+ "TargetARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:sgw-1fad4876-tapedrive-02"
+ },
+ "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_TAPEDRIVE_00002",
+ "VTLDeviceProductIdentifier": "ULT3580-TD5",
+ "VTLDeviceType": "Tape Drive",
+ "VTLDeviceVendor": "IBM"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Returns a description of virtual tape library (VTL) devices for the specified gateway.",
+ "id": "to-describe-virtual-tape-library-vtl-devices-of-a-single-gateway-1471906071410",
+ "title": "To describe virtual tape library (VTL) devices of a single gateway"
+ }
+ ],
+ "DescribeWorkingStorage": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "DiskIds": [
+ "pci-0000:03:00.0-scsi-0:0:0:0",
+ "pci-0000:03:00.0-scsi-0:0:1:0"
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "WorkingStorageAllocatedInBytes": 2199023255552,
+ "WorkingStorageUsedInBytes": 789207040
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation is supported only for the gateway-stored volume architecture. This operation is deprecated in cached-volumes API version (20120630). Use DescribeUploadBuffer instead.",
+ "id": "to-describe-the-working-storage-of-a-gateway-depreciated-1472070842332",
+ "title": "To describe the working storage of a gateway [Depreciated]"
+ }
+ ],
+ "DisableGateway": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Disables a gateway when the gateway is no longer functioning. Use this operation for a gateway-VTL that is not reachable or not functioning.",
+ "id": "to-disable-a-gateway-when-it-is-no-longer-functioning-1472076046936",
+ "title": "To disable a gateway when it is no longer functioning"
+ }
+ ],
+ "ListGateways": [
+ {
+ "input": {
+ "Limit": 2,
+ "Marker": "1"
+ },
+ "output": {
+ "Gateways": [
+ {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-23A4567C"
+ }
+ ],
+ "Marker": "1"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Lists gateways owned by an AWS account in a specified region as requested. Results are sorted by gateway ARN up to a maximum of 100 gateways.",
+ "id": "to-lists-region-specific-gateways-per-aws-account-1472077860657",
+ "title": "To lists region specific gateways per AWS account"
+ }
+ ],
+ "ListLocalDisks": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "Disks": [
+ {
+ "DiskAllocationType": "CACHE_STORAGE",
+ "DiskId": "pci-0000:03:00.0-scsi-0:0:0:0",
+ "DiskNode": "SCSI(0:0)",
+ "DiskPath": "/dev/sda",
+ "DiskSizeInBytes": 1099511627776,
+ "DiskStatus": "missing"
+ },
+ {
+ "DiskAllocationResource": "",
+ "DiskAllocationType": "UPLOAD_BUFFER",
+ "DiskId": "pci-0000:03:00.0-scsi-0:0:1:0",
+ "DiskNode": "SCSI(0:1)",
+ "DiskPath": "/dev/sdb",
+ "DiskSizeInBytes": 1099511627776,
+ "DiskStatus": "present"
+ }
+ ],
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The request returns a list of all disks, specifying which are configured as working storage, cache storage, or stored volume or not configured at all.",
+ "id": "to-list-the-gateways-local-disks-1472079564618",
+ "title": "To list the gateway's local disks"
+ }
+ ],
+ "ListTagsForResource": [
+ {
+ "input": {
+ "Limit": 1,
+ "Marker": "1",
+ "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B"
+ },
+ "output": {
+ "Marker": "1",
+ "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B",
+ "Tags": [
+ {
+ "Key": "Dev Gatgeway Region",
+ "Value": "East Coast"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Lists the tags that have been added to the specified resource.",
+ "id": "to-list-tags-that-have-been-added-to-a-resource-1472080268972",
+ "title": "To list tags that have been added to a resource"
+ }
+ ],
+ "ListVolumeRecoveryPoints": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "VolumeRecoveryPointInfos": [
+ {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB",
+ "VolumeRecoveryPointTime": "2012-09-04T21:08:44.627Z",
+ "VolumeSizeInBytes": 536870912000
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Lists the recovery points for a specified gateway in which all data of the volume is consistent and can be used to create a snapshot.",
+ "id": "to-list-recovery-points-for-a-gateway-1472143015088",
+ "title": "To list recovery points for a gateway"
+ }
+ ],
+ "ListVolumes": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "Limit": 2,
+ "Marker": "1"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "Marker": "1",
+ "VolumeInfos": [
+ {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "GatewayId": "sgw-12A3456B",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB",
+ "VolumeId": "vol-1122AABB",
+ "VolumeSizeInBytes": 107374182400,
+ "VolumeType": "STORED"
+ },
+ {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C",
+ "GatewayId": "sgw-gw-13B4567C",
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C/volume/vol-3344CCDD",
+ "VolumeId": "vol-1122AABB",
+ "VolumeSizeInBytes": 107374182400,
+ "VolumeType": "STORED"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Lists the iSCSI stored volumes of a gateway. Results are sorted by volume ARN up to a maximum of 100 volumes.",
+ "id": "to-list-the-iscsi-stored-volumes-of-a-gateway-1472145723653",
+ "title": "To list the iSCSI stored volumes of a gateway"
+ }
+ ],
+ "RemoveTagsFromResource": [
+ {
+ "input": {
+ "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B",
+ "TagKeys": [
+ "Dev Gatgeway Region",
+ "East Coast"
+ ]
+ },
+ "output": {
+ "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Lists the iSCSI stored volumes of a gateway. Removes one or more tags from the specified resource.",
+ "id": "to-remove-tags-from-a-resource-1472147210553",
+ "title": "To remove tags from a resource"
+ }
+ ],
+ "ResetCache": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Resets all cache disks that have encountered a error and makes the disks available for reconfiguration as cache storage.",
+ "id": "to-reset-cache-disks-in-error-status-1472148909807",
+ "title": "To reset cache disks in error status"
+ }
+ ],
+ "RetrieveTapeArchive": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF"
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Retrieves an archived virtual tape from the virtual tape shelf (VTS) to a gateway-VTL. Virtual tapes archived in the VTS are not associated with any gateway.",
+ "id": "to-retrieve-an-archived-tape-from-the-vts-1472149812358",
+ "title": "To retrieve an archived tape from the VTS"
+ }
+ ],
+ "RetrieveTapeRecoveryPoint": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF"
+ },
+ "output": {
+ "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Retrieves the recovery point for the specified virtual tape.",
+ "id": "to-retrieve-the-recovery-point-of-a-virtual-tape-1472150014805",
+ "title": "To retrieve the recovery point of a virtual tape"
+ }
+ ],
+ "SetLocalConsolePassword": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B",
+ "LocalConsolePassword": "PassWordMustBeAtLeast6Chars."
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Sets the password for your VM local console.",
+ "id": "to-set-a-password-for-your-vm-1472150202632",
+ "title": "To set a password for your VM"
+ }
+ ],
+ "ShutdownGateway": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This operation shuts down the gateway service component running in the storage gateway's virtual machine (VM) and not the VM.",
+ "id": "to-shut-down-a-gateway-service-1472150508835",
+ "title": "To shut down a gateway service"
+ }
+ ],
+ "StartGateway": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Starts a gateway service that was previously shut down.",
+ "id": "to-start-a-gateway-service-1472150722315",
+ "title": "To start a gateway service"
+ }
+ ],
+ "UpdateBandwidthRateLimit": [
+ {
+ "input": {
+ "AverageDownloadRateLimitInBitsPerSec": 102400,
+ "AverageUploadRateLimitInBitsPerSec": 51200,
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates the bandwidth rate limits of a gateway. Both the upload and download bandwidth rate limit can be set, or either one of the two. If a new limit is not set, the existing rate limit remains.",
+ "id": "to-update-the-bandwidth-rate-limits-of-a-gateway-1472151016202",
+ "title": "To update the bandwidth rate limits of a gateway"
+ }
+ ],
+ "UpdateChapCredentials": [
+ {
+ "input": {
+ "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com",
+ "SecretToAuthenticateInitiator": "111111111111",
+ "SecretToAuthenticateTarget": "222222222222",
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ },
+ "output": {
+ "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com",
+ "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates the Challenge-Handshake Authentication Protocol (CHAP) credentials for a specified iSCSI target.",
+ "id": "to-update-chap-credentials-for-an-iscsi-target-1472151325795",
+ "title": "To update CHAP credentials for an iSCSI target"
+ }
+ ],
+ "UpdateGatewayInformation": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "GatewayName": "MyGateway2",
+ "GatewayTimezone": "GMT-12:00"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "GatewayName": ""
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates a gateway's metadata, which includes the gateway's name and time zone.",
+ "id": "to-update-a-gateways-metadata-1472151688693",
+ "title": "To update a gateway's metadata"
+ }
+ ],
+ "UpdateGatewaySoftwareNow": [
+ {
+ "input": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates the gateway virtual machine (VM) software. The request immediately triggers the software update.",
+ "id": "to-update-a-gateways-vm-software-1472152020929",
+ "title": "To update a gateway's VM software"
+ }
+ ],
+ "UpdateMaintenanceStartTime": [
+ {
+ "input": {
+ "DayOfWeek": 2,
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B",
+ "HourOfDay": 0,
+ "MinuteOfHour": 30
+ },
+ "output": {
+ "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates a gateway's weekly maintenance start time information, including day and time of the week. The maintenance time is in your gateway's time zone.",
+ "id": "to-update-a-gateways-maintenance-start-time-1472152552031",
+ "title": "To update a gateway's maintenance start time"
+ }
+ ],
+ "UpdateSnapshotSchedule": [
+ {
+ "input": {
+ "Description": "Hourly snapshot",
+ "RecurrenceInHours": 1,
+ "StartAt": 0,
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "output": {
+ "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates a snapshot schedule configured for a gateway volume.",
+ "id": "to-update-a-volume-snapshot-schedule-1472152757068",
+ "title": "To update a volume snapshot schedule"
+ }
+ ],
+ "UpdateVTLDeviceType": [
+ {
+ "input": {
+ "DeviceType": "Medium Changer",
+ "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_MEDIACHANGER_00001"
+ },
+ "output": {
+ "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_MEDIACHANGER_00001"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "Updates the type of medium changer in a gateway-VTL after a gateway-VTL is activated.",
+ "id": "to-update-a-vtl-device-type-1472153012967",
+ "title": "To update a VTL device type"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/paginators-1.json
new file mode 100644
index 0000000000..ef9e79e61d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/paginators-1.json
@@ -0,0 +1,79 @@
+{
+ "pagination": {
+ "DescribeTapeArchives": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "TapeArchives"
+ },
+ "DescribeTapeRecoveryPoints": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "TapeRecoveryPointInfos"
+ },
+ "DescribeTapes": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Tapes"
+ },
+ "DescribeVTLDevices": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "VTLDevices"
+ },
+ "ListGateways": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Gateways"
+ },
+ "ListVolumes": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "VolumeInfos"
+ },
+ "ListTapes": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "TapeInfos"
+ },
+ "ListFileShares": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "non_aggregate_keys": [
+ "Marker"
+ ],
+ "output_token": "NextMarker",
+ "result_key": "FileShareInfoList"
+ },
+ "ListTagsForResource": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "non_aggregate_keys": [
+ "ResourceARN"
+ ],
+ "output_token": "Marker",
+ "result_key": "Tags"
+ },
+ "ListTapePools": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "PoolInfos"
+ },
+ "ListFileSystemAssociations": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "non_aggregate_keys": [
+ "Marker"
+ ],
+ "output_token": "NextMarker",
+ "result_key": "FileSystemAssociationSummaryList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/service-2.json.gz
new file mode 100644
index 0000000000..e0191f3ec4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/storagegateway/2013-06-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..56204e2de1
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/examples-1.json
new file mode 100644
index 0000000000..7396aef579
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/examples-1.json
@@ -0,0 +1,271 @@
+{
+ "version": "1.0",
+ "examples": {
+ "AssumeRole": [
+ {
+ "input": {
+ "ExternalId": "123ABC",
+ "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1\",\"Effect\":\"Allow\",\"Action\":\"s3:ListAllMyBuckets\",\"Resource\":\"*\"}]}",
+ "RoleArn": "arn:aws:iam::123456789012:role/demo",
+ "RoleSessionName": "testAssumeRoleSession",
+ "Tags": [
+ {
+ "Key": "Project",
+ "Value": "Unicorn"
+ },
+ {
+ "Key": "Team",
+ "Value": "Automation"
+ },
+ {
+ "Key": "Cost-Center",
+ "Value": "12345"
+ }
+ ],
+ "TransitiveTagKeys": [
+ "Project",
+ "Cost-Center"
+ ]
+ },
+ "output": {
+ "AssumedRoleUser": {
+ "Arn": "arn:aws:sts::123456789012:assumed-role/demo/Bob",
+ "AssumedRoleId": "ARO123EXAMPLE123:Bob"
+ },
+ "Credentials": {
+ "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
+ "Expiration": "2011-07-15T23:28:33.359Z",
+ "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
+ "SessionToken": "AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA=="
+ },
+ "PackedPolicySize": 8
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "",
+ "id": "to-assume-a-role-1480532402212",
+ "title": "To assume a role"
+ }
+ ],
+ "AssumeRoleWithSAML": [
+ {
+ "input": {
+ "DurationSeconds": 3600,
+ "PrincipalArn": "arn:aws:iam::123456789012:saml-provider/SAML-test",
+ "RoleArn": "arn:aws:iam::123456789012:role/TestSaml",
+ "SAMLAssertion": "VERYLONGENCODEDASSERTIONEXAMPLExzYW1sOkF1ZGllbmNlPmJsYW5rPC9zYW1sOkF1ZGllbmNlPjwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDpDb25kaXRpb25zPjxzYW1sOlN1YmplY3Q+PHNhbWw6TmFtZUlEIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50Ij5TYW1sRXhhbXBsZTwvc2FtbDpOYW1lSUQ+PHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAxOS0xMS0wMVQyMDoyNTowNS4xNDVaIiBSZWNpcGllbnQ9Imh0dHBzOi8vc2lnbmluLmF3cy5hbWF6b24uY29tL3NhbWwiLz48L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj48L3NhbWw6U3ViamVjdD48c2FtbDpBdXRoblN0YXRlbWVudCBBdXRoPD94bWwgdmpSZXNwb25zZT4="
+ },
+ "output": {
+ "AssumedRoleUser": {
+ "Arn": "arn:aws:sts::123456789012:assumed-role/TestSaml",
+ "AssumedRoleId": "ARO456EXAMPLE789:TestSaml"
+ },
+ "Audience": "https://signin.aws.amazon.com/saml",
+ "Credentials": {
+ "AccessKeyId": "ASIAV3ZUEFP6EXAMPLE",
+ "Expiration": "2019-11-01T20:26:47Z",
+ "SecretAccessKey": "8P+SQvWIuLnKhh8d++jpw0nNmQRBZvNEXAMPLEKEY",
+ "SessionToken": "IQoJb3JpZ2luX2VjEOz////////////////////wEXAMPLEtMSJHMEUCIDoKK3JH9uGQE1z0sINr5M4jk+Na8KHDcCYRVjJCZEvOAiEA3OvJGtw1EcViOleS2vhs8VdCKFJQWPQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA=="
+ },
+ "Issuer": "https://integ.example.com/idp/shibboleth",
+ "NameQualifier": "SbdGOnUkh1i4+EXAMPLExL/jEvs=",
+ "PackedPolicySize": 6,
+ "Subject": "SamlExample",
+ "SubjectType": "transient"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "",
+ "id": "to-assume-role-with-saml-14882749597814",
+ "title": "To assume a role using a SAML assertion"
+ }
+ ],
+ "AssumeRoleWithWebIdentity": [
+ {
+ "input": {
+ "DurationSeconds": 3600,
+ "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1\",\"Effect\":\"Allow\",\"Action\":\"s3:ListAllMyBuckets\",\"Resource\":\"*\"}]}",
+ "ProviderId": "www.amazon.com",
+ "RoleArn": "arn:aws:iam::123456789012:role/FederatedWebIdentityRole",
+ "RoleSessionName": "app1",
+ "WebIdentityToken": "Atza%7CIQEBLjAsAhRFiXuWpUXuRvQ9PZL3GMFcYevydwIUFAHZwXZXXXXXXXXJnrulxKDHwy87oGKPznh0D6bEQZTSCzyoCtL_8S07pLpr0zMbn6w1lfVZKNTBdDansFBmtGnIsIapjI6xKR02Yc_2bQ8LZbUXSGm6Ry6_BG7PrtLZtj_dfCTj92xNGed-CrKqjG7nPBjNIL016GGvuS5gSvPRUxWES3VYfm1wl7WTI7jn-Pcb6M-buCgHhFOzTQxod27L9CqnOLio7N3gZAGpsp6n1-AJBOCJckcyXe2c6uD0srOJeZlKUm2eTDVMf8IehDVI0r1QOnTV6KzzAI3OY87Vd_cVMQ"
+ },
+ "output": {
+ "AssumedRoleUser": {
+ "Arn": "arn:aws:sts::123456789012:assumed-role/FederatedWebIdentityRole/app1",
+ "AssumedRoleId": "AROACLKWSDQRAOEXAMPLE:app1"
+ },
+ "Audience": "client.5498841531868486423.1548@apps.example.com",
+ "Credentials": {
+ "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
+ "Expiration": "2014-10-24T23:00:23Z",
+ "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
+ "SessionToken": "AQoDYXdzEE0a8ANXXXXXXXXNO1ewxE5TijQyp+IEXAMPLE"
+ },
+ "PackedPolicySize": 123,
+ "Provider": "www.amazon.com",
+ "SubjectFromWebIdentityToken": "amzn1.account.AF6RHO7KZU5XRVQJGXK6HEXAMPLE"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "",
+ "id": "to-assume-a-role-as-an-openid-connect-federated-user-1480533445696",
+ "title": "To assume a role as an OpenID Connect-federated user"
+ }
+ ],
+ "DecodeAuthorizationMessage": [
+ {
+ "input": {
+ "EncodedMessage": ""
+ },
+ "output": {
+ "DecodedMessage": "{\"allowed\": \"false\",\"explicitDeny\": \"false\",\"matchedStatements\": \"\",\"failures\": \"\",\"context\": {\"principal\": {\"id\": \"AIDACKCEVSQ6C2EXAMPLE\",\"name\": \"Bob\",\"arn\": \"arn:aws:iam::123456789012:user/Bob\"},\"action\": \"ec2:StopInstances\",\"resource\": \"arn:aws:ec2:us-east-1:123456789012:instance/i-dd01c9bd\",\"conditions\": [{\"item\": {\"key\": \"ec2:Tenancy\",\"values\": [\"default\"]},{\"item\": {\"key\": \"ec2:ResourceTag/elasticbeanstalk:environment-name\",\"values\": [\"Default-Environment\"]}},(Additional items ...)]}}"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "",
+ "id": "to-decode-information-about-an-authorization-status-of-a-request-1480533854499",
+ "title": "To decode information about an authorization status of a request"
+ }
+ ],
+ "GetCallerIdentity": [
+ {
+ "input": {
+ },
+ "output": {
+ "Account": "123456789012",
+ "Arn": "arn:aws:iam::123456789012:user/Alice",
+ "UserId": "AKIAI44QH8DHBEXAMPLE"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows a request and response made with the credentials for a user named Alice in the AWS account 123456789012.",
+ "id": "to-get-details-about-a-calling-iam-user-1480540050376",
+ "title": "To get details about a calling IAM user"
+ },
+ {
+ "input": {
+ },
+ "output": {
+ "Account": "123456789012",
+ "Arn": "arn:aws:sts::123456789012:assumed-role/my-role-name/my-role-session-name",
+ "UserId": "AKIAI44QH8DHBEXAMPLE:my-role-session-name"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows a request and response made with temporary credentials created by AssumeRole. The name of the assumed role is my-role-name, and the RoleSessionName is set to my-role-session-name.",
+ "id": "to-get-details-about-a-calling-user-federated-with-assumerole-1480540158545",
+ "title": "To get details about a calling user federated with AssumeRole"
+ },
+ {
+ "input": {
+ },
+ "output": {
+ "Account": "123456789012",
+ "Arn": "arn:aws:sts::123456789012:federated-user/my-federated-user-name",
+ "UserId": "123456789012:my-federated-user-name"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "This example shows a request and response made with temporary credentials created by using GetFederationToken. The Name parameter is set to my-federated-user-name.",
+ "id": "to-get-details-about-a-calling-user-federated-with-getfederationtoken-1480540231316",
+ "title": "To get details about a calling user federated with GetFederationToken"
+ }
+ ],
+ "GetFederationToken": [
+ {
+ "input": {
+ "DurationSeconds": 3600,
+ "Name": "testFedUserSession",
+ "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1\",\"Effect\":\"Allow\",\"Action\":\"s3:ListAllMyBuckets\",\"Resource\":\"*\"}]}",
+ "Tags": [
+ {
+ "Key": "Project",
+ "Value": "Pegasus"
+ },
+ {
+ "Key": "Cost-Center",
+ "Value": "98765"
+ }
+ ]
+ },
+ "output": {
+ "Credentials": {
+ "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
+ "Expiration": "2011-07-15T23:28:33.359Z",
+ "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
+ "SessionToken": "AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA=="
+ },
+ "FederatedUser": {
+ "Arn": "arn:aws:sts::123456789012:federated-user/Bob",
+ "FederatedUserId": "123456789012:Bob"
+ },
+ "PackedPolicySize": 8
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "",
+ "id": "to-get-temporary-credentials-for-a-role-by-using-getfederationtoken-1480540749900",
+ "title": "To get temporary credentials for a role by using GetFederationToken"
+ }
+ ],
+ "GetSessionToken": [
+ {
+ "input": {
+ "DurationSeconds": 3600,
+ "SerialNumber": "YourMFASerialNumber",
+ "TokenCode": "123456"
+ },
+ "output": {
+ "Credentials": {
+ "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
+ "Expiration": "2011-07-11T19:55:29.611Z",
+ "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
+ "SessionToken": "AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "",
+ "id": "to-get-temporary-credentials-for-an-iam-user-or-an-aws-account-1480540814038",
+ "title": "To get temporary credentials for an IAM user or an AWS account"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/service-2.json.gz
new file mode 100644
index 0000000000..57b0f34eab
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/sts/2011-06-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..0536861040
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/service-2.json.gz
new file mode 100644
index 0000000000..b4a1a95523
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support-app/2021-08-20/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..795df2472c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/paginators-1.json
new file mode 100644
index 0000000000..11bdb62cf1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "DescribeCases": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "cases"
+ },
+ "DescribeCommunications": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "communications"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/service-2.json.gz
new file mode 100644
index 0000000000..ddbe99a374
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/support/2013-04-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..84b781fdde
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/paginators-1.json
new file mode 100644
index 0000000000..e92bfebe6b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/paginators-1.json
@@ -0,0 +1,53 @@
+{
+ "pagination": {
+ "GetWorkflowExecutionHistory": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "events"
+ },
+ "ListActivityTypes": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "typeInfos"
+ },
+ "ListClosedWorkflowExecutions": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "executionInfos"
+ },
+ "ListDomains": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "domainInfos"
+ },
+ "ListOpenWorkflowExecutions": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "executionInfos"
+ },
+ "ListWorkflowTypes": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "typeInfos"
+ },
+ "PollForDecisionTask": {
+ "limit_key": "maximumPageSize",
+ "input_token": "nextPageToken",
+ "output_token": "nextPageToken",
+ "result_key": "events",
+ "non_aggregate_keys": [
+ "taskToken",
+ "startedEventId",
+ "workflowExecution",
+ "workflowType",
+ "previousStartedEventId"
+ ]
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/service-2.json.gz
new file mode 100644
index 0000000000..d3e369ee1e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/swf/2012-01-25/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8d94aef930
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/service-2.json.gz
new file mode 100644
index 0000000000..3850994538
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/synthetics/2017-10-11/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..180071f8f7
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/paginators-1.json
new file mode 100644
index 0000000000..f0d0405068
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/paginators-1.json
@@ -0,0 +1,16 @@
+{
+ "pagination": {
+ "ListAdapterVersions": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AdapterVersions"
+ },
+ "ListAdapters": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "Adapters"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/service-2.json.gz
new file mode 100644
index 0000000000..ed37dd3249
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/textract/2018-06-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..6d5d96bc88
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/paginators-1.json
new file mode 100644
index 0000000000..c497694235
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/paginators-1.json
@@ -0,0 +1,27 @@
+{
+ "pagination": {
+ "Query": {
+ "input_token": "NextToken",
+ "limit_key": "MaxRows",
+ "non_aggregate_keys": [
+ "ColumnInfo",
+ "QueryId",
+ "QueryStatus"
+ ],
+ "output_token": "NextToken",
+ "result_key": "Rows"
+ },
+ "ListScheduledQueries": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ScheduledQueries"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/service-2.json.gz
new file mode 100644
index 0000000000..16a397c9c9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-query/2018-11-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8404cb471d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/service-2.json.gz
new file mode 100644
index 0000000000..8f0d8e7f05
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/timestream-write/2018-11-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5af1e10d63
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/paginators-1.json
new file mode 100644
index 0000000000..18ac477bf6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/paginators-1.json
@@ -0,0 +1,34 @@
+{
+ "pagination": {
+ "ListSolFunctionInstances": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "functionInstances"
+ },
+ "ListSolFunctionPackages": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "functionPackages"
+ },
+ "ListSolNetworkInstances": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "networkInstances"
+ },
+ "ListSolNetworkOperations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "networkOperations"
+ },
+ "ListSolNetworkPackages": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "networkPackages"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/service-2.json.gz
new file mode 100644
index 0000000000..2156b1a1c4
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/tnb/2008-10-21/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..afd4ec3b4a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/service-2.json.gz
new file mode 100644
index 0000000000..d77830df8f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transcribe/2017-10-26/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..15ba89e855
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/paginators-1.json
new file mode 100644
index 0000000000..3fe23dc9f4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/paginators-1.json
@@ -0,0 +1,82 @@
+{
+ "pagination": {
+ "ListServers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Servers"
+ },
+ "ListAccesses": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "non_aggregate_keys": [
+ "ServerId"
+ ],
+ "output_token": "NextToken",
+ "result_key": "Accesses"
+ },
+ "ListExecutions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "non_aggregate_keys": [
+ "WorkflowId"
+ ],
+ "output_token": "NextToken",
+ "result_key": "Executions"
+ },
+ "ListSecurityPolicies": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "SecurityPolicyNames"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "non_aggregate_keys": [
+ "Arn"
+ ],
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ },
+ "ListUsers": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "non_aggregate_keys": [
+ "ServerId"
+ ],
+ "output_token": "NextToken",
+ "result_key": "Users"
+ },
+ "ListWorkflows": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Workflows"
+ },
+ "ListAgreements": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Agreements"
+ },
+ "ListCertificates": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Certificates"
+ },
+ "ListConnectors": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Connectors"
+ },
+ "ListProfiles": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Profiles"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/service-2.json.gz
new file mode 100644
index 0000000000..81bcd3c43a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/waiters-2.json
new file mode 100644
index 0000000000..ddcd604de0
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/transfer/2018-11-05/waiters-2.json
@@ -0,0 +1,37 @@
+{
+ "version" : 2,
+ "waiters" : {
+ "ServerOffline" : {
+ "delay" : 30,
+ "maxAttempts" : 120,
+ "operation" : "DescribeServer",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "Server.State",
+ "state" : "success",
+ "expected" : "OFFLINE"
+ }, {
+ "matcher" : "path",
+ "argument" : "Server.State",
+ "state" : "failure",
+ "expected" : "STOP_FAILED"
+ } ]
+ },
+ "ServerOnline" : {
+ "delay" : 30,
+ "maxAttempts" : 120,
+ "operation" : "DescribeServer",
+ "acceptors" : [ {
+ "matcher" : "path",
+ "argument" : "Server.State",
+ "state" : "success",
+ "expected" : "ONLINE"
+ }, {
+ "matcher" : "path",
+ "argument" : "Server.State",
+ "state" : "failure",
+ "expected" : "START_FAILED"
+ } ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..113306145b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/paginators-1.json
new file mode 100644
index 0000000000..6898cd44cf
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/paginators-1.json
@@ -0,0 +1,10 @@
+{
+ "pagination": {
+ "ListTerminologies": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "TerminologyPropertiesList"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/service-2.json.gz
new file mode 100644
index 0000000000..15e2e508b2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/translate/2017-07-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..b7bb7c0748
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/paginators-1.json
new file mode 100644
index 0000000000..0ac4c7b0e3
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "ListChecks": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "checkSummaries"
+ },
+ "ListOrganizationRecommendationAccounts": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "accountRecommendationLifecycleSummaries"
+ },
+ "ListOrganizationRecommendationResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "organizationRecommendationResourceSummaries"
+ },
+ "ListOrganizationRecommendations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "organizationRecommendationSummaries"
+ },
+ "ListRecommendationResources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "recommendationResourceSummaries"
+ },
+ "ListRecommendations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "recommendationSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/service-2.json.gz
new file mode 100644
index 0000000000..972383985e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/trustedadvisor/2022-09-15/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e3e0831561
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/paginators-1.json
new file mode 100644
index 0000000000..4314d715de
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/paginators-1.json
@@ -0,0 +1,28 @@
+{
+ "pagination": {
+ "ListIdentitySources": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "identitySources"
+ },
+ "ListPolicies": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "policies"
+ },
+ "ListPolicyStores": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "policyStores"
+ },
+ "ListPolicyTemplates": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "policyTemplates"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/service-2.json.gz
new file mode 100644
index 0000000000..0c0301d697
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/waiters-2.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/waiters-2.json
new file mode 100644
index 0000000000..13f60ee66b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/verifiedpermissions/2021-12-01/waiters-2.json
@@ -0,0 +1,5 @@
+{
+ "version": 2,
+ "waiters": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..50c626cdc8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/paginators-1.json
new file mode 100644
index 0000000000..49dd7ccabb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/paginators-1.json
@@ -0,0 +1,40 @@
+{
+ "pagination": {
+ "ListDomains": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "DomainSummaries"
+ },
+ "ListFraudsterRegistrationJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobSummaries"
+ },
+ "ListSpeakerEnrollmentJobs": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "JobSummaries"
+ },
+ "ListSpeakers": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "SpeakerSummaries"
+ },
+ "ListFraudsters": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "FraudsterSummaries"
+ },
+ "ListWatchlists": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "WatchlistSummaries"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/service-2.json.gz
new file mode 100644
index 0000000000..d26978bd74
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/voice-id/2021-09-27/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..8b74b6198b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/paginators-1.json
new file mode 100644
index 0000000000..3727cc35f0
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/paginators-1.json
@@ -0,0 +1,58 @@
+{
+ "pagination": {
+ "ListAccessLogSubscriptions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListListeners": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListRules": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListServiceNetworkServiceAssociations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListServiceNetworkVpcAssociations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListServiceNetworks": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListServices": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListTargetGroups": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ },
+ "ListTargets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/service-2.json.gz
new file mode 100644
index 0000000000..9a0c6947bf
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/vpc-lattice/2022-11-30/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..fd09fb1d8c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/examples-1.json
new file mode 100644
index 0000000000..eee5b6f4ff
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/examples-1.json
@@ -0,0 +1,1017 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CreateIPSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MyIPSetFriendlyName"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "IPSet": {
+ "IPSetDescriptors": [
+ {
+ "Type": "IPV4",
+ "Value": "192.0.2.44/32"
+ }
+ ],
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Name": "MyIPSetFriendlyName"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an IP match set named MyIPSetFriendlyName.",
+ "id": "createipset-1472501003122",
+ "title": "To create an IP set"
+ }
+ ],
+ "CreateRule": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "MetricName": "WAFByteHeaderRule",
+ "Name": "WAFByteHeaderRule"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Rule": {
+ "MetricName": "WAFByteHeaderRule",
+ "Name": "WAFByteHeaderRule",
+ "Predicates": [
+ {
+ "DataId": "MyByteMatchSetID",
+ "Negated": false,
+ "Type": "ByteMatch"
+ }
+ ],
+ "RuleId": "WAFRule-1-Example"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a rule named WAFByteHeaderRule.",
+ "id": "createrule-1474072675555",
+ "title": "To create a rule"
+ }
+ ],
+ "CreateSizeConstraintSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MySampleSizeConstraintSet"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SizeConstraintSet": {
+ "Name": "MySampleSizeConstraintSet",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SizeConstraints": [
+ {
+ "ComparisonOperator": "GT",
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "Size": 0,
+ "TextTransformation": "NONE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates size constraint set named MySampleSizeConstraintSet.",
+ "id": "createsizeconstraint-1474299140754",
+ "title": "To create a size constraint"
+ }
+ ],
+ "CreateSqlInjectionMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MySQLInjectionMatchSet"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SqlInjectionMatchSet": {
+ "Name": "MySQLInjectionMatchSet",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SqlInjectionMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a SQL injection match set named MySQLInjectionMatchSet.",
+ "id": "createsqlinjectionmatchset-1474492796105",
+ "title": "To create a SQL injection match set"
+ }
+ ],
+ "CreateWebACL": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "MetricName": "CreateExample",
+ "Name": "CreateExample"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "WebACL": {
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "MetricName": "CreateExample",
+ "Name": "CreateExample",
+ "Rules": [
+ {
+ "Action": {
+ "Type": "ALLOW"
+ },
+ "Priority": 1,
+ "RuleId": "WAFRule-1-Example"
+ }
+ ],
+ "WebACLId": "example-46da-4444-5555-example"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a web ACL named CreateExample.",
+ "id": "createwebacl-1472061481310",
+ "title": "To create a web ACL"
+ }
+ ],
+ "CreateXssMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MySampleXssMatchSet"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "XssMatchSet": {
+ "Name": "MySampleXssMatchSet",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "XssMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an XSS match set named MySampleXssMatchSet.",
+ "id": "createxssmatchset-1474560868500",
+ "title": "To create an XSS match set"
+ }
+ ],
+ "DeleteByteMatchSet": [
+ {
+ "input": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5",
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletebytematchset-1473367566229",
+ "title": "To delete a byte match set"
+ }
+ ],
+ "DeleteIPSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deleteipset-1472767434306",
+ "title": "To delete an IP set"
+ }
+ ],
+ "DeleteRule": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "RuleId": "WAFRule-1-Example"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a rule with the ID WAFRule-1-Example.",
+ "id": "deleterule-1474073108749",
+ "title": "To delete a rule"
+ }
+ ],
+ "DeleteSizeConstraintSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletesizeconstraintset-1474299857905",
+ "title": "To delete a size constraint set"
+ }
+ ],
+ "DeleteSqlInjectionMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletesqlinjectionmatchset-1474493373197",
+ "title": "To delete a SQL injection match set"
+ }
+ ],
+ "DeleteWebACL": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "WebACLId": "example-46da-4444-5555-example"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a web ACL with the ID example-46da-4444-5555-example.",
+ "id": "deletewebacl-1472767755931",
+ "title": "To delete a web ACL"
+ }
+ ],
+ "DeleteXssMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletexssmatchset-1474561302618",
+ "title": "To delete an XSS match set"
+ }
+ ],
+ "GetByteMatchSet": [
+ {
+ "input": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ByteMatchSet": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5",
+ "ByteMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Data": "referer",
+ "Type": "HEADER"
+ },
+ "PositionalConstraint": "CONTAINS",
+ "TargetString": "badrefer1",
+ "TextTransformation": "NONE"
+ }
+ ],
+ "Name": "ByteMatchNameExample"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getbytematchset-1473273311532",
+ "title": "To get a byte match set"
+ }
+ ],
+ "GetChangeToken": [
+ {
+ "input": {
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a change token to use for a create, update or delete operation.",
+ "id": "get-change-token-example-1471635120794",
+ "title": "To get a change token"
+ }
+ ],
+ "GetChangeTokenStatus": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "output": {
+ "ChangeTokenStatus": "PENDING"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the status of a change token with the ID abcd12f2-46da-4fdb-b8d5-fbd4c466928f.",
+ "id": "getchangetokenstatus-1474658417107",
+ "title": "To get the change token status"
+ }
+ ],
+ "GetIPSet": [
+ {
+ "input": {
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "IPSet": {
+ "IPSetDescriptors": [
+ {
+ "Type": "IPV4",
+ "Value": "192.0.2.44/32"
+ }
+ ],
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Name": "MyIPSetFriendlyName"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getipset-1474658688675",
+ "title": "To get an IP set"
+ }
+ ],
+ "GetRule": [
+ {
+ "input": {
+ "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "Rule": {
+ "MetricName": "WAFByteHeaderRule",
+ "Name": "WAFByteHeaderRule",
+ "Predicates": [
+ {
+ "DataId": "MyByteMatchSetID",
+ "Negated": false,
+ "Type": "ByteMatch"
+ }
+ ],
+ "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getrule-1474659238790",
+ "title": "To get a rule"
+ }
+ ],
+ "GetSampledRequests": [
+ {
+ "input": {
+ "MaxItems": 100,
+ "RuleId": "WAFRule-1-Example",
+ "TimeWindow": {
+ "EndTime": "2016-09-27T15:50Z",
+ "StartTime": "2016-09-27T15:50Z"
+ },
+ "WebAclId": "createwebacl-1472061481310"
+ },
+ "output": {
+ "PopulationSize": 50,
+ "SampledRequests": [
+ {
+ "Action": "BLOCK",
+ "Request": {
+ "ClientIP": "192.0.2.44",
+ "Country": "US",
+ "HTTPVersion": "HTTP/1.1",
+ "Headers": [
+ {
+ "Name": "User-Agent",
+ "Value": "BadBot "
+ }
+ ],
+ "Method": "HEAD"
+ },
+ "Timestamp": "2016-09-27T14:55Z",
+ "Weight": 1
+ }
+ ],
+ "TimeWindow": {
+ "EndTime": "2016-09-27T15:50Z",
+ "StartTime": "2016-09-27T14:50Z"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns detailed information about 100 requests --a sample-- that AWS WAF randomly selects from among the first 5,000 requests that your AWS resource received between the time period 2016-09-27T15:50Z to 2016-09-27T15:50Z.",
+ "id": "getsampledrequests-1474927997195",
+ "title": "To get a sampled requests"
+ }
+ ],
+ "GetSizeConstraintSet": [
+ {
+ "input": {
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "SizeConstraintSet": {
+ "Name": "MySampleSizeConstraintSet",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SizeConstraints": [
+ {
+ "ComparisonOperator": "GT",
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "Size": 0,
+ "TextTransformation": "NONE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a size constraint match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getsizeconstraintset-1475005422493",
+ "title": "To get a size constraint set"
+ }
+ ],
+ "GetSqlInjectionMatchSet": [
+ {
+ "input": {
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "SqlInjectionMatchSet": {
+ "Name": "MySQLInjectionMatchSet",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SqlInjectionMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getsqlinjectionmatchset-1475005940137",
+ "title": "To get a SQL injection match set"
+ }
+ ],
+ "GetWebACL": [
+ {
+ "input": {
+ "WebACLId": "createwebacl-1472061481310"
+ },
+ "output": {
+ "WebACL": {
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "MetricName": "CreateExample",
+ "Name": "CreateExample",
+ "Rules": [
+ {
+ "Action": {
+ "Type": "ALLOW"
+ },
+ "Priority": 1,
+ "RuleId": "WAFRule-1-Example"
+ }
+ ],
+ "WebACLId": "createwebacl-1472061481310"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a web ACL with the ID createwebacl-1472061481310.",
+ "id": "getwebacl-1475006348525",
+ "title": "To get a web ACL"
+ }
+ ],
+ "GetXssMatchSet": [
+ {
+ "input": {
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "XssMatchSet": {
+ "Name": "MySampleXssMatchSet",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "XssMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getxssmatchset-1475187879017",
+ "title": "To get an XSS match set"
+ }
+ ],
+ "ListIPSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "IPSets": [
+ {
+ "IPSetId": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MyIPSetFriendlyName"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 IP match sets.",
+ "id": "listipsets-1472235676229",
+ "title": "To list IP sets"
+ }
+ ],
+ "ListRules": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "Rules": [
+ {
+ "Name": "WAFByteHeaderRule",
+ "RuleId": "WAFRule-1-Example"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 rules.",
+ "id": "listrules-1475258406433",
+ "title": "To list rules"
+ }
+ ],
+ "ListSizeConstraintSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "SizeConstraintSets": [
+ {
+ "Name": "MySampleSizeConstraintSet",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 size contraint match sets.",
+ "id": "listsizeconstraintsets-1474300067597",
+ "title": "To list a size constraint sets"
+ }
+ ],
+ "ListSqlInjectionMatchSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "SqlInjectionMatchSets": [
+ {
+ "Name": "MySQLInjectionMatchSet",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 SQL injection match sets.",
+ "id": "listsqlinjectionmatchset-1474493560103",
+ "title": "To list SQL injection match sets"
+ }
+ ],
+ "ListWebACLs": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "WebACLs": [
+ {
+ "Name": "WebACLexample",
+ "WebACLId": "webacl-1472061481310"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 web ACLs.",
+ "id": "listwebacls-1475258732691",
+ "title": "To list Web ACLs"
+ }
+ ],
+ "ListXssMatchSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "XssMatchSets": [
+ {
+ "Name": "MySampleXssMatchSet",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 XSS match sets.",
+ "id": "listxssmatchsets-1474561481168",
+ "title": "To list XSS match sets"
+ }
+ ],
+ "UpdateByteMatchSet": [
+ {
+ "input": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5",
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "ByteMatchTuple": {
+ "FieldToMatch": {
+ "Data": "referer",
+ "Type": "HEADER"
+ },
+ "PositionalConstraint": "CONTAINS",
+ "TargetString": "badrefer1",
+ "TextTransformation": "NONE"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a ByteMatchTuple object (filters) in an byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatebytematchset-1475259074558",
+ "title": "To update a byte match set"
+ }
+ ],
+ "UpdateIPSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "IPSetDescriptor": {
+ "Type": "IPV4",
+ "Value": "192.0.2.44/32"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an IPSetDescriptor object in an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updateipset-1475259733625",
+ "title": "To update an IP set"
+ }
+ ],
+ "UpdateRule": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "Predicate": {
+ "DataId": "MyByteMatchSetID",
+ "Negated": false,
+ "Type": "ByteMatch"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a Predicate object in a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updaterule-1475260064720",
+ "title": "To update a rule"
+ }
+ ],
+ "UpdateSizeConstraintSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "SizeConstraint": {
+ "ComparisonOperator": "GT",
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "Size": 0,
+ "TextTransformation": "NONE"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a SizeConstraint object (filters) in a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatesizeconstraintset-1475531697891",
+ "title": "To update a size constraint set"
+ }
+ ],
+ "UpdateSqlInjectionMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "SqlInjectionMatchTuple": {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a SqlInjectionMatchTuple object (filters) in a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatesqlinjectionmatchset-1475532094686",
+ "title": "To update a SQL injection match set"
+ }
+ ],
+ "UpdateWebACL": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "ActivatedRule": {
+ "Action": {
+ "Type": "ALLOW"
+ },
+ "Priority": 1,
+ "RuleId": "WAFRule-1-Example"
+ }
+ }
+ ],
+ "WebACLId": "webacl-1472061481310"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an ActivatedRule object in a WebACL with the ID webacl-1472061481310.",
+ "id": "updatewebacl-1475533627385",
+ "title": "To update a Web ACL"
+ }
+ ],
+ "UpdateXssMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "XssMatchTuple": {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ }
+ ],
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an XssMatchTuple object (filters) in an XssMatchSet with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatexssmatchset-1475534098881",
+ "title": "To update an XSS match set"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/service-2.json.gz
new file mode 100644
index 0000000000..d0e844789f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf-regional/2016-11-28/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..b95b133963
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/examples-1.json
new file mode 100644
index 0000000000..eee5b6f4ff
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/examples-1.json
@@ -0,0 +1,1017 @@
+{
+ "version": "1.0",
+ "examples": {
+ "CreateIPSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MyIPSetFriendlyName"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "IPSet": {
+ "IPSetDescriptors": [
+ {
+ "Type": "IPV4",
+ "Value": "192.0.2.44/32"
+ }
+ ],
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Name": "MyIPSetFriendlyName"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an IP match set named MyIPSetFriendlyName.",
+ "id": "createipset-1472501003122",
+ "title": "To create an IP set"
+ }
+ ],
+ "CreateRule": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "MetricName": "WAFByteHeaderRule",
+ "Name": "WAFByteHeaderRule"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Rule": {
+ "MetricName": "WAFByteHeaderRule",
+ "Name": "WAFByteHeaderRule",
+ "Predicates": [
+ {
+ "DataId": "MyByteMatchSetID",
+ "Negated": false,
+ "Type": "ByteMatch"
+ }
+ ],
+ "RuleId": "WAFRule-1-Example"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a rule named WAFByteHeaderRule.",
+ "id": "createrule-1474072675555",
+ "title": "To create a rule"
+ }
+ ],
+ "CreateSizeConstraintSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MySampleSizeConstraintSet"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SizeConstraintSet": {
+ "Name": "MySampleSizeConstraintSet",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SizeConstraints": [
+ {
+ "ComparisonOperator": "GT",
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "Size": 0,
+ "TextTransformation": "NONE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates size constraint set named MySampleSizeConstraintSet.",
+ "id": "createsizeconstraint-1474299140754",
+ "title": "To create a size constraint"
+ }
+ ],
+ "CreateSqlInjectionMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MySQLInjectionMatchSet"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SqlInjectionMatchSet": {
+ "Name": "MySQLInjectionMatchSet",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SqlInjectionMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a SQL injection match set named MySQLInjectionMatchSet.",
+ "id": "createsqlinjectionmatchset-1474492796105",
+ "title": "To create a SQL injection match set"
+ }
+ ],
+ "CreateWebACL": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "MetricName": "CreateExample",
+ "Name": "CreateExample"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "WebACL": {
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "MetricName": "CreateExample",
+ "Name": "CreateExample",
+ "Rules": [
+ {
+ "Action": {
+ "Type": "ALLOW"
+ },
+ "Priority": 1,
+ "RuleId": "WAFRule-1-Example"
+ }
+ ],
+ "WebACLId": "example-46da-4444-5555-example"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates a web ACL named CreateExample.",
+ "id": "createwebacl-1472061481310",
+ "title": "To create a web ACL"
+ }
+ ],
+ "CreateXssMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MySampleXssMatchSet"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "XssMatchSet": {
+ "Name": "MySampleXssMatchSet",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "XssMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example creates an XSS match set named MySampleXssMatchSet.",
+ "id": "createxssmatchset-1474560868500",
+ "title": "To create an XSS match set"
+ }
+ ],
+ "DeleteByteMatchSet": [
+ {
+ "input": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5",
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletebytematchset-1473367566229",
+ "title": "To delete a byte match set"
+ }
+ ],
+ "DeleteIPSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deleteipset-1472767434306",
+ "title": "To delete an IP set"
+ }
+ ],
+ "DeleteRule": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "RuleId": "WAFRule-1-Example"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a rule with the ID WAFRule-1-Example.",
+ "id": "deleterule-1474073108749",
+ "title": "To delete a rule"
+ }
+ ],
+ "DeleteSizeConstraintSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletesizeconstraintset-1474299857905",
+ "title": "To delete a size constraint set"
+ }
+ ],
+ "DeleteSqlInjectionMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletesqlinjectionmatchset-1474493373197",
+ "title": "To delete a SQL injection match set"
+ }
+ ],
+ "DeleteWebACL": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "WebACLId": "example-46da-4444-5555-example"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a web ACL with the ID example-46da-4444-5555-example.",
+ "id": "deletewebacl-1472767755931",
+ "title": "To delete a web ACL"
+ }
+ ],
+ "DeleteXssMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "deletexssmatchset-1474561302618",
+ "title": "To delete an XSS match set"
+ }
+ ],
+ "GetByteMatchSet": [
+ {
+ "input": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ByteMatchSet": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5",
+ "ByteMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Data": "referer",
+ "Type": "HEADER"
+ },
+ "PositionalConstraint": "CONTAINS",
+ "TargetString": "badrefer1",
+ "TextTransformation": "NONE"
+ }
+ ],
+ "Name": "ByteMatchNameExample"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getbytematchset-1473273311532",
+ "title": "To get a byte match set"
+ }
+ ],
+ "GetChangeToken": [
+ {
+ "input": {
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns a change token to use for a create, update or delete operation.",
+ "id": "get-change-token-example-1471635120794",
+ "title": "To get a change token"
+ }
+ ],
+ "GetChangeTokenStatus": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "output": {
+ "ChangeTokenStatus": "PENDING"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the status of a change token with the ID abcd12f2-46da-4fdb-b8d5-fbd4c466928f.",
+ "id": "getchangetokenstatus-1474658417107",
+ "title": "To get the change token status"
+ }
+ ],
+ "GetIPSet": [
+ {
+ "input": {
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "IPSet": {
+ "IPSetDescriptors": [
+ {
+ "Type": "IPV4",
+ "Value": "192.0.2.44/32"
+ }
+ ],
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Name": "MyIPSetFriendlyName"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getipset-1474658688675",
+ "title": "To get an IP set"
+ }
+ ],
+ "GetRule": [
+ {
+ "input": {
+ "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "Rule": {
+ "MetricName": "WAFByteHeaderRule",
+ "Name": "WAFByteHeaderRule",
+ "Predicates": [
+ {
+ "DataId": "MyByteMatchSetID",
+ "Negated": false,
+ "Type": "ByteMatch"
+ }
+ ],
+ "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getrule-1474659238790",
+ "title": "To get a rule"
+ }
+ ],
+ "GetSampledRequests": [
+ {
+ "input": {
+ "MaxItems": 100,
+ "RuleId": "WAFRule-1-Example",
+ "TimeWindow": {
+ "EndTime": "2016-09-27T15:50Z",
+ "StartTime": "2016-09-27T15:50Z"
+ },
+ "WebAclId": "createwebacl-1472061481310"
+ },
+ "output": {
+ "PopulationSize": 50,
+ "SampledRequests": [
+ {
+ "Action": "BLOCK",
+ "Request": {
+ "ClientIP": "192.0.2.44",
+ "Country": "US",
+ "HTTPVersion": "HTTP/1.1",
+ "Headers": [
+ {
+ "Name": "User-Agent",
+ "Value": "BadBot "
+ }
+ ],
+ "Method": "HEAD"
+ },
+ "Timestamp": "2016-09-27T14:55Z",
+ "Weight": 1
+ }
+ ],
+ "TimeWindow": {
+ "EndTime": "2016-09-27T15:50Z",
+ "StartTime": "2016-09-27T14:50Z"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns detailed information about 100 requests --a sample-- that AWS WAF randomly selects from among the first 5,000 requests that your AWS resource received between the time period 2016-09-27T15:50Z to 2016-09-27T15:50Z.",
+ "id": "getsampledrequests-1474927997195",
+ "title": "To get a sampled requests"
+ }
+ ],
+ "GetSizeConstraintSet": [
+ {
+ "input": {
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "SizeConstraintSet": {
+ "Name": "MySampleSizeConstraintSet",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SizeConstraints": [
+ {
+ "ComparisonOperator": "GT",
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "Size": 0,
+ "TextTransformation": "NONE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a size constraint match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getsizeconstraintset-1475005422493",
+ "title": "To get a size constraint set"
+ }
+ ],
+ "GetSqlInjectionMatchSet": [
+ {
+ "input": {
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "SqlInjectionMatchSet": {
+ "Name": "MySQLInjectionMatchSet",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "SqlInjectionMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getsqlinjectionmatchset-1475005940137",
+ "title": "To get a SQL injection match set"
+ }
+ ],
+ "GetWebACL": [
+ {
+ "input": {
+ "WebACLId": "createwebacl-1472061481310"
+ },
+ "output": {
+ "WebACL": {
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "MetricName": "CreateExample",
+ "Name": "CreateExample",
+ "Rules": [
+ {
+ "Action": {
+ "Type": "ALLOW"
+ },
+ "Priority": 1,
+ "RuleId": "WAFRule-1-Example"
+ }
+ ],
+ "WebACLId": "createwebacl-1472061481310"
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of a web ACL with the ID createwebacl-1472061481310.",
+ "id": "getwebacl-1475006348525",
+ "title": "To get a web ACL"
+ }
+ ],
+ "GetXssMatchSet": [
+ {
+ "input": {
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "XssMatchSet": {
+ "Name": "MySampleXssMatchSet",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "XssMatchTuples": [
+ {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ ]
+ }
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns the details of an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "getxssmatchset-1475187879017",
+ "title": "To get an XSS match set"
+ }
+ ],
+ "ListIPSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "IPSets": [
+ {
+ "IPSetId": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Name": "MyIPSetFriendlyName"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 IP match sets.",
+ "id": "listipsets-1472235676229",
+ "title": "To list IP sets"
+ }
+ ],
+ "ListRules": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "Rules": [
+ {
+ "Name": "WAFByteHeaderRule",
+ "RuleId": "WAFRule-1-Example"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 rules.",
+ "id": "listrules-1475258406433",
+ "title": "To list rules"
+ }
+ ],
+ "ListSizeConstraintSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "SizeConstraintSets": [
+ {
+ "Name": "MySampleSizeConstraintSet",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 size contraint match sets.",
+ "id": "listsizeconstraintsets-1474300067597",
+ "title": "To list a size constraint sets"
+ }
+ ],
+ "ListSqlInjectionMatchSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "SqlInjectionMatchSets": [
+ {
+ "Name": "MySQLInjectionMatchSet",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 SQL injection match sets.",
+ "id": "listsqlinjectionmatchset-1474493560103",
+ "title": "To list SQL injection match sets"
+ }
+ ],
+ "ListWebACLs": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "WebACLs": [
+ {
+ "Name": "WebACLexample",
+ "WebACLId": "webacl-1472061481310"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 web ACLs.",
+ "id": "listwebacls-1475258732691",
+ "title": "To list Web ACLs"
+ }
+ ],
+ "ListXssMatchSets": [
+ {
+ "input": {
+ "Limit": 100
+ },
+ "output": {
+ "XssMatchSets": [
+ {
+ "Name": "MySampleXssMatchSet",
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ }
+ ]
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example returns an array of up to 100 XSS match sets.",
+ "id": "listxssmatchsets-1474561481168",
+ "title": "To list XSS match sets"
+ }
+ ],
+ "UpdateByteMatchSet": [
+ {
+ "input": {
+ "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5",
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "ByteMatchTuple": {
+ "FieldToMatch": {
+ "Data": "referer",
+ "Type": "HEADER"
+ },
+ "PositionalConstraint": "CONTAINS",
+ "TargetString": "badrefer1",
+ "TextTransformation": "NONE"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a ByteMatchTuple object (filters) in an byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatebytematchset-1475259074558",
+ "title": "To update a byte match set"
+ }
+ ],
+ "UpdateIPSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "IPSetDescriptor": {
+ "Type": "IPV4",
+ "Value": "192.0.2.44/32"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an IPSetDescriptor object in an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updateipset-1475259733625",
+ "title": "To update an IP set"
+ }
+ ],
+ "UpdateRule": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "Predicate": {
+ "DataId": "MyByteMatchSetID",
+ "Negated": false,
+ "Type": "ByteMatch"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a Predicate object in a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updaterule-1475260064720",
+ "title": "To update a rule"
+ }
+ ],
+ "UpdateSizeConstraintSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "SizeConstraint": {
+ "ComparisonOperator": "GT",
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "Size": 0,
+ "TextTransformation": "NONE"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a SizeConstraint object (filters) in a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatesizeconstraintset-1475531697891",
+ "title": "To update a size constraint set"
+ }
+ ],
+ "UpdateSqlInjectionMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "SqlInjectionMatchTuple": {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ }
+ ]
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes a SqlInjectionMatchTuple object (filters) in a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatesqlinjectionmatchset-1475532094686",
+ "title": "To update a SQL injection match set"
+ }
+ ],
+ "UpdateWebACL": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "DefaultAction": {
+ "Type": "ALLOW"
+ },
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "ActivatedRule": {
+ "Action": {
+ "Type": "ALLOW"
+ },
+ "Priority": 1,
+ "RuleId": "WAFRule-1-Example"
+ }
+ }
+ ],
+ "WebACLId": "webacl-1472061481310"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an ActivatedRule object in a WebACL with the ID webacl-1472061481310.",
+ "id": "updatewebacl-1475533627385",
+ "title": "To update a Web ACL"
+ }
+ ],
+ "UpdateXssMatchSet": [
+ {
+ "input": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f",
+ "Updates": [
+ {
+ "Action": "DELETE",
+ "XssMatchTuple": {
+ "FieldToMatch": {
+ "Type": "QUERY_STRING"
+ },
+ "TextTransformation": "URL_DECODE"
+ }
+ }
+ ],
+ "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5"
+ },
+ "output": {
+ "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f"
+ },
+ "comments": {
+ "input": {
+ },
+ "output": {
+ }
+ },
+ "description": "The following example deletes an XssMatchTuple object (filters) in an XssMatchSet with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.",
+ "id": "updatexssmatchset-1475534098881",
+ "title": "To update an XSS match set"
+ }
+ ]
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/paginators-1.json
new file mode 100644
index 0000000000..9f2eba808e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/paginators-1.json
@@ -0,0 +1,99 @@
+{
+ "pagination": {
+ "ListByteMatchSets": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "ByteMatchSets"
+ },
+ "ListIPSets": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "IPSets"
+ },
+ "ListRules": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "Rules"
+ },
+ "ListSizeConstraintSets": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "SizeConstraintSets"
+ },
+ "ListSqlInjectionMatchSets": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "SqlInjectionMatchSets"
+ },
+ "ListWebACLs": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "WebACLs"
+ },
+ "ListXssMatchSets": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "limit_key": "Limit",
+ "result_key": "XssMatchSets"
+ },
+ "GetRateBasedRuleManagedKeys": {
+ "input_token": "NextMarker",
+ "output_token": "NextMarker",
+ "result_key": "ManagedKeys"
+ },
+ "ListActivatedRulesInRuleGroup": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "ActivatedRules"
+ },
+ "ListGeoMatchSets": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "GeoMatchSets"
+ },
+ "ListLoggingConfigurations": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "LoggingConfigurations"
+ },
+ "ListRateBasedRules": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "Rules"
+ },
+ "ListRegexMatchSets": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "RegexMatchSets"
+ },
+ "ListRegexPatternSets": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "RegexPatternSets"
+ },
+ "ListRuleGroups": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "RuleGroups"
+ },
+ "ListSubscribedRuleGroups": {
+ "input_token": "NextMarker",
+ "limit_key": "Limit",
+ "output_token": "NextMarker",
+ "result_key": "RuleGroups"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/service-2.json.gz
new file mode 100644
index 0000000000..4b543b32dd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/waf/2015-08-24/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4a2d2de66c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/service-2.json.gz
new file mode 100644
index 0000000000..59eaaa05f6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wafv2/2019-07-29/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..d283b22dc3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/service-2.json.gz
new file mode 100644
index 0000000000..677e8008ec
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wellarchitected/2020-03-31/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..5b44ac97dc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/paginators-1.json
new file mode 100644
index 0000000000..60b1dca5d5
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/paginators-1.json
@@ -0,0 +1,64 @@
+{
+ "pagination": {
+ "ListAssistantAssociations": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "assistantAssociationSummaries"
+ },
+ "ListAssistants": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "assistantSummaries"
+ },
+ "ListContents": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "contentSummaries"
+ },
+ "ListKnowledgeBases": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "knowledgeBaseSummaries"
+ },
+ "QueryAssistant": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "results"
+ },
+ "SearchContent": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "contentSummaries"
+ },
+ "SearchSessions": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "sessionSummaries"
+ },
+ "ListImportJobs": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "importJobSummaries"
+ },
+ "ListQuickResponses": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "quickResponseSummaries"
+ },
+ "SearchQuickResponses": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "results"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/service-2.json.gz
new file mode 100644
index 0000000000..edb17bb70a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/wisdom/2020-10-19/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4d67312647
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/paginators-1.json
new file mode 100644
index 0000000000..ff2f410a92
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/paginators-1.json
@@ -0,0 +1,67 @@
+{
+ "pagination": {
+ "DescribeDocumentVersions": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "DocumentVersions"
+ },
+ "DescribeFolderContents": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": [
+ "Folders",
+ "Documents"
+ ]
+ },
+ "DescribeUsers": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Users"
+ },
+ "DescribeActivities": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "UserActivities"
+ },
+ "DescribeComments": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Comments"
+ },
+ "DescribeGroups": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Groups"
+ },
+ "DescribeNotificationSubscriptions": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Subscriptions"
+ },
+ "DescribeResourcePermissions": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Principals"
+ },
+ "DescribeRootFolders": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Folders"
+ },
+ "SearchResources": {
+ "input_token": "Marker",
+ "limit_key": "Limit",
+ "output_token": "Marker",
+ "result_key": "Items"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/service-2.json.gz
new file mode 100644
index 0000000000..236739a876
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workdocs/2016-05-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e364454bc3
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/service-2.json.gz
new file mode 100644
index 0000000000..98379ee044
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/worklink/2018-09-25/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..2905fc0bec
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/paginators-1.json
new file mode 100644
index 0000000000..40a3cadf68
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/paginators-1.json
@@ -0,0 +1,58 @@
+{
+ "pagination": {
+ "ListUsers": {
+ "result_key": "Users",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListGroupMembers": {
+ "result_key": "Members",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListOrganizations": {
+ "result_key": "OrganizationSummaries",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListGroups": {
+ "result_key": "Groups",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListResources": {
+ "result_key": "Resources",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListAliases": {
+ "result_key": "Aliases",
+ "output_token": "NextToken",
+ "input_token": "NextToken",
+ "limit_key": "MaxResults"
+ },
+ "ListMailboxPermissions": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Permissions"
+ },
+ "ListResourceDelegates": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Delegates"
+ },
+ "ListAvailabilityConfigurations": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "limit_key": "MaxResults",
+ "result_key": "AvailabilityConfigurations"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/service-2.json.gz
new file mode 100644
index 0000000000..686adf826e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmail/2017-10-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..d2db86a0d2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/service-2.json.gz
new file mode 100644
index 0000000000..e3f5b14a63
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workmailmessageflow/2019-05-01/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..4d00cfe434
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/paginators-1.json
new file mode 100644
index 0000000000..9fe21a4857
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/paginators-1.json
@@ -0,0 +1,22 @@
+{
+ "pagination": {
+ "ListDevices": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "devices"
+ },
+ "ListEnvironments": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "environments"
+ },
+ "ListSoftwareSets": {
+ "input_token": "nextToken",
+ "output_token": "nextToken",
+ "limit_key": "maxResults",
+ "result_key": "softwareSets"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/service-2.json.gz
new file mode 100644
index 0000000000..d9c716f7fd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-thin-client/2023-08-22/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..b8289773a9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/paginators-1.json
new file mode 100644
index 0000000000..ea142457a6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/paginators-1.json
@@ -0,0 +1,3 @@
+{
+ "pagination": {}
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/service-2.json.gz
new file mode 100644
index 0000000000..cc445820cb
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces-web/2020-07-08/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..e8cf5b13b5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/paginators-1.json
new file mode 100644
index 0000000000..57e10e02b1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/paginators-1.json
@@ -0,0 +1,48 @@
+{
+ "pagination": {
+ "DescribeWorkspaceBundles": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Bundles"
+ },
+ "DescribeWorkspaceDirectories": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Directories"
+ },
+ "DescribeWorkspaces": {
+ "limit_key": "Limit",
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Workspaces"
+ },
+ "DescribeAccountModifications": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "AccountModifications"
+ },
+ "DescribeIpGroups": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Result"
+ },
+ "DescribeWorkspaceImages": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "Images"
+ },
+ "DescribeWorkspacesConnectionStatus": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "WorkspacesConnectionStatus"
+ },
+ "ListAvailableManagementCidrRanges": {
+ "input_token": "NextToken",
+ "limit_key": "MaxResults",
+ "output_token": "NextToken",
+ "result_key": "ManagementCidrRanges"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/service-2.json.gz
new file mode 100644
index 0000000000..f0ae889118
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/workspaces/2015-04-08/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/endpoint-rule-set-1.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/endpoint-rule-set-1.json.gz
new file mode 100644
index 0000000000..f306c726d6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/endpoint-rule-set-1.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/examples-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/examples-1.json
new file mode 100644
index 0000000000..0ea7e3b0bb
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/examples-1.json
@@ -0,0 +1,5 @@
+{
+ "version": "1.0",
+ "examples": {
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/paginators-1.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/paginators-1.json
new file mode 100644
index 0000000000..0f65898f26
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/paginators-1.json
@@ -0,0 +1,69 @@
+{
+ "pagination": {
+ "BatchGetTraces": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Traces",
+ "non_aggregate_keys": [
+ "UnprocessedTraceIds"
+ ]
+ },
+ "GetServiceGraph": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Services",
+ "non_aggregate_keys": [
+ "StartTime",
+ "EndTime",
+ "ContainsOldGroupVersions"
+ ]
+ },
+ "GetTraceGraph": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Services"
+ },
+ "GetTraceSummaries": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "TraceSummaries",
+ "non_aggregate_keys": [
+ "TracesProcessedCount",
+ "ApproximateTime"
+ ]
+ },
+ "GetGroups": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Groups"
+ },
+ "GetSamplingRules": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "SamplingRuleRecords"
+ },
+ "GetSamplingStatisticSummaries": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "SamplingStatisticSummaries"
+ },
+ "GetTimeSeriesServiceStatistics": {
+ "input_token": "NextToken",
+ "non_aggregate_keys": [
+ "ContainsOldGroupVersions"
+ ],
+ "output_token": "NextToken",
+ "result_key": "TimeSeriesServiceStatistics"
+ },
+ "ListResourcePolicies": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "ResourcePolicies"
+ },
+ "ListTagsForResource": {
+ "input_token": "NextToken",
+ "output_token": "NextToken",
+ "result_key": "Tags"
+ }
+ }
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/service-2.json.gz b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/service-2.json.gz
new file mode 100644
index 0000000000..0c29f8768a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/data/xray/2016-04-12/service-2.json.gz differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/discovery.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/discovery.py
new file mode 100644
index 0000000000..9c68001dea
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/discovery.py
@@ -0,0 +1,282 @@
+# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import logging
+import time
+import weakref
+
+from botocore import xform_name
+from botocore.exceptions import BotoCoreError, ConnectionError, HTTPClientError
+from botocore.model import OperationNotFoundError
+from botocore.utils import CachedProperty
+
+logger = logging.getLogger(__name__)
+
+
+class EndpointDiscoveryException(BotoCoreError):
+ pass
+
+
+class EndpointDiscoveryRequired(EndpointDiscoveryException):
+ """Endpoint Discovery is disabled but is required for this operation."""
+
+ fmt = 'Endpoint Discovery is not enabled but this operation requires it.'
+
+
+class EndpointDiscoveryRefreshFailed(EndpointDiscoveryException):
+ """Endpoint Discovery failed to the refresh the known endpoints."""
+
+ fmt = 'Endpoint Discovery failed to refresh the required endpoints.'
+
+
+def block_endpoint_discovery_required_operations(model, **kwargs):
+ endpoint_discovery = model.endpoint_discovery
+ if endpoint_discovery and endpoint_discovery.get('required'):
+ raise EndpointDiscoveryRequired()
+
+
+class EndpointDiscoveryModel:
+ def __init__(self, service_model):
+ self._service_model = service_model
+
+ @CachedProperty
+ def discovery_operation_name(self):
+ discovery_operation = self._service_model.endpoint_discovery_operation
+ return xform_name(discovery_operation.name)
+
+ @CachedProperty
+ def discovery_operation_keys(self):
+ discovery_operation = self._service_model.endpoint_discovery_operation
+ keys = []
+ if discovery_operation.input_shape:
+ keys = list(discovery_operation.input_shape.members.keys())
+ return keys
+
+ def discovery_required_for(self, operation_name):
+ try:
+ operation_model = self._service_model.operation_model(
+ operation_name
+ )
+ return operation_model.endpoint_discovery.get('required', False)
+ except OperationNotFoundError:
+ return False
+
+ def discovery_operation_kwargs(self, **kwargs):
+ input_keys = self.discovery_operation_keys
+ # Operation and Identifiers are only sent if there are Identifiers
+ if not kwargs.get('Identifiers'):
+ kwargs.pop('Operation', None)
+ kwargs.pop('Identifiers', None)
+ return {k: v for k, v in kwargs.items() if k in input_keys}
+
+ def gather_identifiers(self, operation, params):
+ return self._gather_ids(operation.input_shape, params)
+
+ def _gather_ids(self, shape, params, ids=None):
+ # Traverse the input shape and corresponding parameters, gathering
+ # any input fields labeled as an endpoint discovery id
+ if ids is None:
+ ids = {}
+ for member_name, member_shape in shape.members.items():
+ if member_shape.metadata.get('endpointdiscoveryid'):
+ ids[member_name] = params[member_name]
+ elif (
+ member_shape.type_name == 'structure' and member_name in params
+ ):
+ self._gather_ids(member_shape, params[member_name], ids)
+ return ids
+
+
+class EndpointDiscoveryManager:
+ def __init__(
+ self, client, cache=None, current_time=None, always_discover=True
+ ):
+ if cache is None:
+ cache = {}
+ self._cache = cache
+ self._failed_attempts = {}
+ if current_time is None:
+ current_time = time.time
+ self._time = current_time
+ self._always_discover = always_discover
+
+ # This needs to be a weak ref in order to prevent memory leaks on
+ # python 2.6
+ self._client = weakref.proxy(client)
+ self._model = EndpointDiscoveryModel(client.meta.service_model)
+
+ def _parse_endpoints(self, response):
+ endpoints = response['Endpoints']
+ current_time = self._time()
+ for endpoint in endpoints:
+ cache_time = endpoint.get('CachePeriodInMinutes')
+ endpoint['Expiration'] = current_time + cache_time * 60
+ return endpoints
+
+ def _cache_item(self, value):
+ if isinstance(value, dict):
+ return tuple(sorted(value.items()))
+ else:
+ return value
+
+ def _create_cache_key(self, **kwargs):
+ kwargs = self._model.discovery_operation_kwargs(**kwargs)
+ return tuple(self._cache_item(v) for k, v in sorted(kwargs.items()))
+
+ def gather_identifiers(self, operation, params):
+ return self._model.gather_identifiers(operation, params)
+
+ def delete_endpoints(self, **kwargs):
+ cache_key = self._create_cache_key(**kwargs)
+ if cache_key in self._cache:
+ del self._cache[cache_key]
+
+ def _describe_endpoints(self, **kwargs):
+ # This is effectively a proxy to whatever name/kwargs the service
+ # supports for endpoint discovery.
+ kwargs = self._model.discovery_operation_kwargs(**kwargs)
+ operation_name = self._model.discovery_operation_name
+ discovery_operation = getattr(self._client, operation_name)
+ logger.debug('Discovering endpoints with kwargs: %s', kwargs)
+ return discovery_operation(**kwargs)
+
+ def _get_current_endpoints(self, key):
+ if key not in self._cache:
+ return None
+ now = self._time()
+ return [e for e in self._cache[key] if now < e['Expiration']]
+
+ def _refresh_current_endpoints(self, **kwargs):
+ cache_key = self._create_cache_key(**kwargs)
+ try:
+ response = self._describe_endpoints(**kwargs)
+ endpoints = self._parse_endpoints(response)
+ self._cache[cache_key] = endpoints
+ self._failed_attempts.pop(cache_key, None)
+ return endpoints
+ except (ConnectionError, HTTPClientError):
+ self._failed_attempts[cache_key] = self._time() + 60
+ return None
+
+ def _recently_failed(self, cache_key):
+ if cache_key in self._failed_attempts:
+ now = self._time()
+ if now < self._failed_attempts[cache_key]:
+ return True
+ del self._failed_attempts[cache_key]
+ return False
+
+ def _select_endpoint(self, endpoints):
+ return endpoints[0]['Address']
+
+ def describe_endpoint(self, **kwargs):
+ operation = kwargs['Operation']
+ discovery_required = self._model.discovery_required_for(operation)
+
+ if not self._always_discover and not discovery_required:
+ # Discovery set to only run on required operations
+ logger.debug(
+ 'Optional discovery disabled. Skipping discovery for Operation: %s'
+ % operation
+ )
+ return None
+
+ # Get the endpoint for the provided operation and identifiers
+ cache_key = self._create_cache_key(**kwargs)
+ endpoints = self._get_current_endpoints(cache_key)
+ if endpoints:
+ return self._select_endpoint(endpoints)
+ # All known endpoints are stale
+ recently_failed = self._recently_failed(cache_key)
+ if not recently_failed:
+ # We haven't failed to discover recently, go ahead and refresh
+ endpoints = self._refresh_current_endpoints(**kwargs)
+ if endpoints:
+ return self._select_endpoint(endpoints)
+ # Discovery has failed recently, do our best to get an endpoint
+ logger.debug('Endpoint Discovery has failed for: %s', kwargs)
+ stale_entries = self._cache.get(cache_key, None)
+ if stale_entries:
+ # We have stale entries, use those while discovery is failing
+ return self._select_endpoint(stale_entries)
+ if discovery_required:
+ # It looks strange to be checking recently_failed again but,
+ # this informs us as to whether or not we tried to refresh earlier
+ if recently_failed:
+ # Discovery is required and we haven't already refreshed
+ endpoints = self._refresh_current_endpoints(**kwargs)
+ if endpoints:
+ return self._select_endpoint(endpoints)
+ # No endpoints even refresh, raise hard error
+ raise EndpointDiscoveryRefreshFailed()
+ # Discovery is optional, just use the default endpoint for now
+ return None
+
+
+class EndpointDiscoveryHandler:
+ def __init__(self, manager):
+ self._manager = manager
+
+ def register(self, events, service_id):
+ events.register(
+ 'before-parameter-build.%s' % service_id, self.gather_identifiers
+ )
+ events.register_first(
+ 'request-created.%s' % service_id, self.discover_endpoint
+ )
+ events.register('needs-retry.%s' % service_id, self.handle_retries)
+
+ def gather_identifiers(self, params, model, context, **kwargs):
+ endpoint_discovery = model.endpoint_discovery
+ # Only continue if the operation supports endpoint discovery
+ if endpoint_discovery is None:
+ return
+ ids = self._manager.gather_identifiers(model, params)
+ context['discovery'] = {'identifiers': ids}
+
+ def discover_endpoint(self, request, operation_name, **kwargs):
+ ids = request.context.get('discovery', {}).get('identifiers')
+ if ids is None:
+ return
+ endpoint = self._manager.describe_endpoint(
+ Operation=operation_name, Identifiers=ids
+ )
+ if endpoint is None:
+ logger.debug('Failed to discover and inject endpoint')
+ return
+ if not endpoint.startswith('http'):
+ endpoint = 'https://' + endpoint
+ logger.debug('Injecting discovered endpoint: %s', endpoint)
+ request.url = endpoint
+
+ def handle_retries(self, request_dict, response, operation, **kwargs):
+ if response is None:
+ return None
+
+ _, response = response
+ status = response.get('ResponseMetadata', {}).get('HTTPStatusCode')
+ error_code = response.get('Error', {}).get('Code')
+ if status != 421 and error_code != 'InvalidEndpointException':
+ return None
+
+ context = request_dict.get('context', {})
+ ids = context.get('discovery', {}).get('identifiers')
+ if ids is None:
+ return None
+
+ # Delete the cached endpoints, forcing a refresh on retry
+ # TODO: Improve eviction behavior to only evict the bad endpoint if
+ # there are multiple. This will almost certainly require a lock.
+ self._manager.delete_endpoints(
+ Operation=operation.name, Identifiers=ids
+ )
+ return 0
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__init__.py
new file mode 100644
index 0000000000..844f5de59b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__init__.py
@@ -0,0 +1,54 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore.docs.service import ServiceDocumenter
+
+DEPRECATED_SERVICE_NAMES = {'sms-voice'}
+
+
+def generate_docs(root_dir, session):
+ """Generates the reference documentation for botocore
+
+ This will go through every available AWS service and output ReSTructured
+ text files documenting each service.
+
+ :param root_dir: The directory to write the reference files to. Each
+ service's reference documentation is loacated at
+ root_dir/reference/services/service-name.rst
+ """
+ # Create the root directory where all service docs live.
+ services_dir_path = os.path.join(root_dir, 'reference', 'services')
+ if not os.path.exists(services_dir_path):
+ os.makedirs(services_dir_path)
+
+ # Prevents deprecated service names from being generated in docs.
+ available_services = [
+ service
+ for service in session.get_available_services()
+ if service not in DEPRECATED_SERVICE_NAMES
+ ]
+
+ # Generate reference docs and write them out.
+ for service_name in available_services:
+ docs = ServiceDocumenter(
+ service_name, session, services_dir_path
+ ).document_service()
+
+ # Write the main service documentation page.
+ # Path: /reference/services//index.rst
+ service_file_path = os.path.join(
+ services_dir_path, f'{service_name}.rst'
+ )
+ with open(service_file_path, 'wb') as f:
+ f.write(docs)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..7e6dac84d0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/client.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/client.cpython-311.pyc
new file mode 100644
index 0000000000..ab8b737edc
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/client.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/docstring.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/docstring.cpython-311.pyc
new file mode 100644
index 0000000000..6b9edf7733
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/docstring.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/example.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/example.cpython-311.pyc
new file mode 100644
index 0000000000..52fa80528b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/example.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/method.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/method.cpython-311.pyc
new file mode 100644
index 0000000000..e529787656
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/method.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/paginator.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/paginator.cpython-311.pyc
new file mode 100644
index 0000000000..f37a916752
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/paginator.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/params.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/params.cpython-311.pyc
new file mode 100644
index 0000000000..f723622a16
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/params.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/service.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/service.cpython-311.pyc
new file mode 100644
index 0000000000..4d69ef36c2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/service.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/shape.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/shape.cpython-311.pyc
new file mode 100644
index 0000000000..54090fc3ec
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/shape.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/sharedexample.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/sharedexample.cpython-311.pyc
new file mode 100644
index 0000000000..fcaec6f1f6
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/sharedexample.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/translator.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/translator.cpython-311.pyc
new file mode 100644
index 0000000000..558b23993c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/translator.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/utils.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/utils.cpython-311.pyc
new file mode 100644
index 0000000000..407d4dca4c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/utils.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/waiter.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/waiter.cpython-311.pyc
new file mode 100644
index 0000000000..741a1c9347
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/__pycache__/waiter.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__init__.py
new file mode 100644
index 0000000000..b687f69da2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+__version__ = '0.16.0'
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..deafac1bfa
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/docstringparser.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/docstringparser.cpython-311.pyc
new file mode 100644
index 0000000000..568a784536
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/docstringparser.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/restdoc.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/restdoc.cpython-311.pyc
new file mode 100644
index 0000000000..90dc00a0dd
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/restdoc.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/style.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/style.cpython-311.pyc
new file mode 100644
index 0000000000..7546d6a2b2
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/__pycache__/style.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/docstringparser.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/docstringparser.py
new file mode 100644
index 0000000000..16e74e7d20
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/docstringparser.py
@@ -0,0 +1,315 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from html.parser import HTMLParser
+from itertools import zip_longest
+
+PRIORITY_PARENT_TAGS = ('code', 'a')
+OMIT_NESTED_TAGS = ('span', 'i', 'code', 'a')
+OMIT_SELF_TAGS = ('i', 'b')
+HTML_BLOCK_DISPLAY_TAGS = ('p', 'note', 'ul', 'li')
+
+
+class DocStringParser(HTMLParser):
+ """
+ A simple HTML parser. Focused on converting the subset of HTML
+ that appears in the documentation strings of the JSON models into
+ simple ReST format.
+ """
+
+ def __init__(self, doc):
+ self.tree = None
+ self.doc = doc
+ super().__init__()
+
+ def reset(self):
+ HTMLParser.reset(self)
+ self.tree = HTMLTree(self.doc)
+
+ def feed(self, data):
+ super().feed(data)
+ self.tree.write()
+ self.tree = HTMLTree(self.doc)
+
+ def close(self):
+ super().close()
+ # Write if there is anything remaining.
+ self.tree.write()
+ self.tree = HTMLTree(self.doc)
+
+ def handle_starttag(self, tag, attrs):
+ self.tree.add_tag(tag, attrs=attrs)
+
+ def handle_endtag(self, tag):
+ self.tree.add_tag(tag, is_start=False)
+
+ def handle_data(self, data):
+ self.tree.add_data(data)
+
+
+class HTMLTree:
+ """
+ A tree which handles HTML nodes. Designed to work with a python HTML parser,
+ meaning that the current_node will be the most recently opened tag. When
+ a tag is closed, the current_node moves up to the parent node.
+ """
+
+ def __init__(self, doc):
+ self.doc = doc
+ self.head = StemNode()
+ self.current_node = self.head
+ self.unhandled_tags = []
+
+ def add_tag(self, tag, attrs=None, is_start=True):
+ if not self._doc_has_handler(tag, is_start):
+ self.unhandled_tags.append(tag)
+ return
+
+ if is_start:
+ node = TagNode(tag, attrs)
+ self.current_node.add_child(node)
+ self.current_node = node
+ else:
+ self.current_node = self.current_node.parent
+
+ def _doc_has_handler(self, tag, is_start):
+ if is_start:
+ handler_name = 'start_%s' % tag
+ else:
+ handler_name = 'end_%s' % tag
+
+ return hasattr(self.doc.style, handler_name)
+
+ def add_data(self, data):
+ self.current_node.add_child(DataNode(data))
+
+ def write(self):
+ self.head.write(self.doc)
+
+
+class Node:
+ def __init__(self, parent=None):
+ self.parent = parent
+
+ def write(self, doc):
+ raise NotImplementedError
+
+
+class StemNode(Node):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.children = []
+
+ def add_child(self, child):
+ child.parent = self
+ self.children.append(child)
+
+ def write(self, doc):
+ self.collapse_whitespace()
+ self._write_children(doc)
+
+ def _write_children(self, doc):
+ for child, next_child in zip_longest(self.children, self.children[1:]):
+ if isinstance(child, TagNode) and next_child is not None:
+ child.write(doc, next_child)
+ else:
+ child.write(doc)
+
+ def is_whitespace(self):
+ return all(child.is_whitespace() for child in self.children)
+
+ def startswith_whitespace(self):
+ return self.children and self.children[0].startswith_whitespace()
+
+ def endswith_whitespace(self):
+ return self.children and self.children[-1].endswith_whitespace()
+
+ def lstrip(self):
+ while self.children and self.children[0].is_whitespace():
+ self.children = self.children[1:]
+ if self.children:
+ self.children[0].lstrip()
+
+ def rstrip(self):
+ while self.children and self.children[-1].is_whitespace():
+ self.children = self.children[:-1]
+ if self.children:
+ self.children[-1].rstrip()
+
+ def collapse_whitespace(self):
+ """Remove collapsible white-space from HTML.
+
+ HTML in docstrings often contains extraneous white-space around tags,
+ for readability. Browsers would collapse this white-space before
+ rendering. If not removed before conversion to RST where white-space is
+ part of the syntax, for example for indentation, it can result in
+ incorrect output.
+ """
+ self.lstrip()
+ self.rstrip()
+ for child in self.children:
+ child.collapse_whitespace()
+
+
+class TagNode(StemNode):
+ """
+ A generic Tag node. It will verify that handlers exist before writing.
+ """
+
+ def __init__(self, tag, attrs=None, parent=None):
+ super().__init__(parent)
+ self.attrs = attrs
+ self.tag = tag
+
+ def _has_nested_tags(self):
+ # Returns True if any children are TagNodes and False otherwise.
+ return any(isinstance(child, TagNode) for child in self.children)
+
+ def write(self, doc, next_child=None):
+ prioritize_nested_tags = (
+ self.tag in OMIT_SELF_TAGS and self._has_nested_tags()
+ )
+ prioritize_parent_tag = (
+ isinstance(self.parent, TagNode)
+ and self.parent.tag in PRIORITY_PARENT_TAGS
+ and self.tag in OMIT_NESTED_TAGS
+ )
+ if prioritize_nested_tags or prioritize_parent_tag:
+ self._write_children(doc)
+ return
+
+ self._write_start(doc)
+ self._write_children(doc)
+ self._write_end(doc, next_child)
+
+ def collapse_whitespace(self):
+ """Remove collapsible white-space.
+
+ All tags collapse internal whitespace. Block-display HTML tags also
+ strip all leading and trailing whitespace.
+
+ Approximately follows the specification used in browsers:
+ https://www.w3.org/TR/css-text-3/#white-space-rules
+ https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace
+ """
+ if self.tag in HTML_BLOCK_DISPLAY_TAGS:
+ self.lstrip()
+ self.rstrip()
+ # Collapse whitespace in situations like `` foo`` into
+ # `` foo``.
+ for prev, cur in zip(self.children[:-1], self.children[1:]):
+ if (
+ isinstance(prev, DataNode)
+ and prev.endswith_whitespace()
+ and cur.startswith_whitespace()
+ ):
+ cur.lstrip()
+ # Same logic, but for situations like ``bar ``:
+ for cur, nxt in zip(self.children[:-1], self.children[1:]):
+ if (
+ isinstance(nxt, DataNode)
+ and cur.endswith_whitespace()
+ and nxt.startswith_whitespace()
+ ):
+ cur.rstrip()
+ # Recurse into children
+ for child in self.children:
+ child.collapse_whitespace()
+
+ def _write_start(self, doc):
+ handler_name = 'start_%s' % self.tag
+ if hasattr(doc.style, handler_name):
+ getattr(doc.style, handler_name)(self.attrs)
+
+ def _write_end(self, doc, next_child):
+ handler_name = 'end_%s' % self.tag
+ if hasattr(doc.style, handler_name):
+ if handler_name == 'end_a':
+ # We use lookahead to determine if a space is needed after a link node
+ getattr(doc.style, handler_name)(next_child)
+ else:
+ getattr(doc.style, handler_name)()
+
+
+class DataNode(Node):
+ """
+ A Node that contains only string data.
+ """
+
+ def __init__(self, data, parent=None):
+ super().__init__(parent)
+ if not isinstance(data, str):
+ raise ValueError("Expecting string type, %s given." % type(data))
+ self._leading_whitespace = ''
+ self._trailing_whitespace = ''
+ self._stripped_data = ''
+ if data == '':
+ return
+ if data.isspace():
+ self._trailing_whitespace = data
+ return
+ first_non_space = next(
+ idx for idx, ch in enumerate(data) if not ch.isspace()
+ )
+ last_non_space = len(data) - next(
+ idx for idx, ch in enumerate(reversed(data)) if not ch.isspace()
+ )
+ self._leading_whitespace = data[:first_non_space]
+ self._trailing_whitespace = data[last_non_space:]
+ self._stripped_data = data[first_non_space:last_non_space]
+
+ @property
+ def data(self):
+ return (
+ f'{self._leading_whitespace}{self._stripped_data}'
+ f'{self._trailing_whitespace}'
+ )
+
+ def is_whitespace(self):
+ return self._stripped_data == '' and (
+ self._leading_whitespace != '' or self._trailing_whitespace != ''
+ )
+
+ def startswith_whitespace(self):
+ return self._leading_whitespace != '' or (
+ self._stripped_data == '' and self._trailing_whitespace != ''
+ )
+
+ def endswith_whitespace(self):
+ return self._trailing_whitespace != '' or (
+ self._stripped_data == '' and self._leading_whitespace != ''
+ )
+
+ def lstrip(self):
+ if self._leading_whitespace != '':
+ self._leading_whitespace = ''
+ elif self._stripped_data == '':
+ self.rstrip()
+
+ def rstrip(self):
+ if self._trailing_whitespace != '':
+ self._trailing_whitespace = ''
+ elif self._stripped_data == '':
+ self.lstrip()
+
+ def collapse_whitespace(self):
+ """Noop, ``DataNode.write`` always collapses whitespace"""
+ return
+
+ def write(self, doc):
+ words = doc.translate_words(self._stripped_data.split())
+ str_data = (
+ f'{self._leading_whitespace}{" ".join(words)}'
+ f'{self._trailing_whitespace}'
+ )
+ if str_data != '':
+ doc.handle_data(str_data)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/restdoc.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/restdoc.py
new file mode 100644
index 0000000000..d23fcf2825
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/restdoc.py
@@ -0,0 +1,282 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import logging
+import os
+import re
+
+from botocore.compat import OrderedDict
+from botocore.docs.bcdoc.docstringparser import DocStringParser
+from botocore.docs.bcdoc.style import ReSTStyle
+
+DEFAULT_AWS_DOCS_LINK = 'https://docs.aws.amazon.com/index.html'
+DOCUMENTATION_LINK_REGEX = re.compile(
+ r'`AWS API Documentation '
+ r'`_'
+)
+LARGE_SECTION_MESSAGE = """
+
+ **{}**
+ ::
+
+ # This section is too large to render.
+ # Please see the AWS API Documentation linked below.
+
+ {}
+ """
+LOG = logging.getLogger('bcdocs')
+SECTION_LINE_LIMIT_CONFIG = {
+ 'response-example': {'name': 'Response Syntax', 'line_limit': 1500},
+ 'description': {'name': 'Response Structure', 'line_limit': 5000},
+ 'request-example': {'name': 'Request Syntax', 'line_limit': 1500},
+ 'request-params': {'name': 'Parameters', 'line_limit': 5000},
+}
+SECTION_METHOD_PATH_DEPTH = {
+ 'client-api': 4,
+ 'paginator-api': 3,
+ 'waiter-api': 3,
+}
+
+
+class ReSTDocument:
+ def __init__(self, target='man'):
+ self.style = ReSTStyle(self)
+ self.target = target
+ self.parser = DocStringParser(self)
+ self.keep_data = True
+ self.do_translation = False
+ self.translation_map = {}
+ self.hrefs = {}
+ self._writes = []
+ self._last_doc_string = None
+
+ def _write(self, s):
+ if self.keep_data and s is not None:
+ self._writes.append(s)
+
+ def write(self, content):
+ """
+ Write content into the document.
+ """
+ self._write(content)
+
+ def writeln(self, content):
+ """
+ Write content on a newline.
+ """
+ self._write(f'{self.style.spaces()}{content}\n')
+
+ def peek_write(self):
+ """
+ Returns the last content written to the document without
+ removing it from the stack.
+ """
+ return self._writes[-1]
+
+ def pop_write(self):
+ """
+ Removes and returns the last content written to the stack.
+ """
+ return self._writes.pop() if len(self._writes) > 0 else None
+
+ def push_write(self, s):
+ """
+ Places new content on the stack.
+ """
+ self._writes.append(s)
+
+ def getvalue(self):
+ """
+ Returns the current content of the document as a string.
+ """
+ if self.hrefs:
+ self.style.new_paragraph()
+ for refname, link in self.hrefs.items():
+ self.style.link_target_definition(refname, link)
+ return ''.join(self._writes).encode('utf-8')
+
+ def translate_words(self, words):
+ return [self.translation_map.get(w, w) for w in words]
+
+ def handle_data(self, data):
+ if data and self.keep_data:
+ self._write(data)
+
+ def include_doc_string(self, doc_string):
+ if doc_string:
+ try:
+ start = len(self._writes)
+ self.parser.feed(doc_string)
+ self.parser.close()
+ end = len(self._writes)
+ self._last_doc_string = (start, end)
+ except Exception:
+ LOG.debug('Error parsing doc string', exc_info=True)
+ LOG.debug(doc_string)
+
+ def remove_last_doc_string(self):
+ # Removes all writes inserted by last doc string
+ if self._last_doc_string is not None:
+ start, end = self._last_doc_string
+ del self._writes[start:end]
+
+
+class DocumentStructure(ReSTDocument):
+ def __init__(self, name, section_names=None, target='man', context=None):
+ """Provides a Hierarichial structure to a ReSTDocument
+
+ You can write to it similiar to as you can to a ReSTDocument but
+ has an innate structure for more orginaztion and abstraction.
+
+ :param name: The name of the document
+ :param section_names: A list of sections to be included
+ in the document.
+ :param target: The target documentation of the Document structure
+ :param context: A dictionary of data to store with the strucuture. These
+ are only stored per section not the entire structure.
+ """
+ super().__init__(target=target)
+ self._name = name
+ self._structure = OrderedDict()
+ self._path = [self._name]
+ self._context = {}
+ if context is not None:
+ self._context = context
+ if section_names is not None:
+ self._generate_structure(section_names)
+
+ @property
+ def name(self):
+ """The name of the document structure"""
+ return self._name
+
+ @property
+ def path(self):
+ """
+ A list of where to find a particular document structure in the
+ overlying document structure.
+ """
+ return self._path
+
+ @path.setter
+ def path(self, value):
+ self._path = value
+
+ @property
+ def available_sections(self):
+ return list(self._structure)
+
+ @property
+ def context(self):
+ return self._context
+
+ def _generate_structure(self, section_names):
+ for section_name in section_names:
+ self.add_new_section(section_name)
+
+ def add_new_section(self, name, context=None):
+ """Adds a new section to the current document structure
+
+ This document structure will be considered a section to the
+ current document structure but will in itself be an entirely
+ new document structure that can be written to and have sections
+ as well
+
+ :param name: The name of the section.
+ :param context: A dictionary of data to store with the strucuture. These
+ are only stored per section not the entire structure.
+ :rtype: DocumentStructure
+ :returns: A new document structure to add to but lives as a section
+ to the document structure it was instantiated from.
+ """
+ # Add a new section
+ section = self.__class__(
+ name=name, target=self.target, context=context
+ )
+ section.path = self.path + [name]
+ # Indent the section apporpriately as well
+ section.style.indentation = self.style.indentation
+ section.translation_map = self.translation_map
+ section.hrefs = self.hrefs
+ self._structure[name] = section
+ return section
+
+ def get_section(self, name):
+ """Retrieve a section"""
+ return self._structure[name]
+
+ def delete_section(self, name):
+ """Delete a section"""
+ del self._structure[name]
+
+ def flush_structure(self, docs_link=None):
+ """Flushes a doc structure to a ReSTructed string
+
+ The document is flushed out in a DFS style where sections and their
+ subsections' values are added to the string as they are visited.
+ """
+ # We are at the root flush the links at the beginning of the
+ # document
+ path_length = len(self.path)
+ if path_length == 1:
+ if self.hrefs:
+ self.style.new_paragraph()
+ for refname, link in self.hrefs.items():
+ self.style.link_target_definition(refname, link)
+ # Clear docs_link at the correct depth to prevent passing a non-related link.
+ elif path_length == SECTION_METHOD_PATH_DEPTH.get(self.path[1]):
+ docs_link = None
+ value = self.getvalue()
+ for name, section in self._structure.items():
+ # Checks is the AWS API Documentation link has been generated.
+ # If it has been generated, it gets passed as a the doc_link parameter.
+ match = DOCUMENTATION_LINK_REGEX.search(value.decode())
+ docs_link = (
+ f'{match.group(0)}\n\n'.encode() if match else docs_link
+ )
+ value += section.flush_structure(docs_link)
+
+ # Replace response/request sections if the line number exceeds our limit.
+ # The section is replaced with a message linking to AWS API Documentation.
+ line_count = len(value.splitlines())
+ section_config = SECTION_LINE_LIMIT_CONFIG.get(self.name)
+ aws_docs_link = (
+ docs_link.decode()
+ if docs_link is not None
+ else DEFAULT_AWS_DOCS_LINK
+ )
+ if section_config and line_count > section_config['line_limit']:
+ value = LARGE_SECTION_MESSAGE.format(
+ section_config['name'], aws_docs_link
+ ).encode()
+ return value
+
+ def getvalue(self):
+ return ''.join(self._writes).encode('utf-8')
+
+ def remove_all_sections(self):
+ self._structure = OrderedDict()
+
+ def clear_text(self):
+ self._writes = []
+
+ def add_title_section(self, title):
+ title_section = self.add_new_section('title')
+ title_section.style.h1(title)
+ return title_section
+
+ def write_to_file(self, full_path, file_name):
+ if not os.path.exists(full_path):
+ os.makedirs(full_path)
+ sub_resource_file_path = os.path.join(full_path, f'{file_name}.rst')
+ with open(sub_resource_file_path, 'wb') as f:
+ f.write(self.flush_structure())
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/style.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/style.py
new file mode 100644
index 0000000000..f2a165a932
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/bcdoc/style.py
@@ -0,0 +1,447 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+import logging
+
+logger = logging.getLogger('bcdocs')
+# Terminal punctuation where a space is not needed before.
+PUNCTUATION_CHARACTERS = ('.', ',', '?', '!', ':', ';')
+
+
+class BaseStyle:
+ def __init__(self, doc, indent_width=2):
+ self.doc = doc
+ self.indent_width = indent_width
+ self._indent = 0
+ self.keep_data = True
+
+ @property
+ def indentation(self):
+ return self._indent
+
+ @indentation.setter
+ def indentation(self, value):
+ self._indent = value
+
+ def new_paragraph(self):
+ return '\n%s' % self.spaces()
+
+ def indent(self):
+ self._indent += 1
+
+ def dedent(self):
+ if self._indent > 0:
+ self._indent -= 1
+
+ def spaces(self):
+ return ' ' * (self._indent * self.indent_width)
+
+ def bold(self, s):
+ return s
+
+ def ref(self, link, title=None):
+ return link
+
+ def h2(self, s):
+ return s
+
+ def h3(self, s):
+ return s
+
+ def underline(self, s):
+ return s
+
+ def italics(self, s):
+ return s
+
+ def add_trailing_space_to_previous_write(self):
+ # Adds a trailing space if none exists. This is mainly used for
+ # ensuring inline code and links are separated from surrounding text.
+ last_write = self.doc.pop_write()
+ if last_write is None:
+ last_write = ''
+ if last_write != '' and last_write[-1] != ' ':
+ last_write += ' '
+ self.doc.push_write(last_write)
+
+
+class ReSTStyle(BaseStyle):
+ def __init__(self, doc, indent_width=2):
+ BaseStyle.__init__(self, doc, indent_width)
+ self.do_p = True
+ self.a_href = None
+ self.list_depth = 0
+
+ def new_paragraph(self):
+ self.doc.write('\n\n%s' % self.spaces())
+
+ def new_line(self):
+ self.doc.write('\n%s' % self.spaces())
+
+ def _start_inline(self, markup):
+ # Insert space between any directly adjacent bold and italic inlines to
+ # avoid situations like ``**abc***def*``.
+ try:
+ last_write = self.doc.peek_write()
+ except IndexError:
+ pass
+ else:
+ if last_write in ('*', '**') and markup in ('*', '**'):
+ self.doc.write(' ')
+ self.doc.write(markup)
+
+ def _end_inline(self, markup):
+ # Remove empty and self-closing tags like ```` and ````.
+ # If we simply translate that directly then we end up with something
+ # like ****, which rst will assume is a heading instead of an empty
+ # bold.
+ last_write = self.doc.pop_write()
+ if last_write == markup:
+ return
+ self.doc.push_write(last_write)
+ self.doc.write(markup)
+
+ def start_bold(self, attrs=None):
+ self._start_inline('**')
+
+ def end_bold(self):
+ self._end_inline('**')
+
+ def start_b(self, attrs=None):
+ self.doc.do_translation = True
+ self.start_bold(attrs)
+
+ def end_b(self):
+ self.doc.do_translation = False
+ self.end_bold()
+
+ def bold(self, s):
+ if s:
+ self.start_bold()
+ self.doc.write(s)
+ self.end_bold()
+
+ def ref(self, title, link=None):
+ if link is None:
+ link = title
+ self.doc.write(f':doc:`{title} <{link}>`')
+
+ def _heading(self, s, border_char):
+ border = border_char * len(s)
+ self.new_paragraph()
+ self.doc.write(f'{border}\n{s}\n{border}')
+ self.new_paragraph()
+
+ def h1(self, s):
+ self._heading(s, '*')
+
+ def h2(self, s):
+ self._heading(s, '=')
+
+ def h3(self, s):
+ self._heading(s, '-')
+
+ def start_italics(self, attrs=None):
+ self._start_inline('*')
+
+ def end_italics(self):
+ self._end_inline('*')
+
+ def italics(self, s):
+ if s:
+ self.start_italics()
+ self.doc.write(s)
+ self.end_italics()
+
+ def start_p(self, attrs=None):
+ if self.do_p:
+ self.doc.write('\n\n%s' % self.spaces())
+
+ def end_p(self):
+ if self.do_p:
+ self.doc.write('\n\n%s' % self.spaces())
+
+ def start_code(self, attrs=None):
+ self.doc.do_translation = True
+ self.add_trailing_space_to_previous_write()
+ self._start_inline('``')
+
+ def end_code(self):
+ self.doc.do_translation = False
+ self._end_inline('``')
+
+ def code(self, s):
+ if s:
+ self.start_code()
+ self.doc.write(s)
+ self.end_code()
+
+ def start_note(self, attrs=None):
+ self.new_paragraph()
+ self.doc.write('.. note::')
+ self.indent()
+ self.new_paragraph()
+
+ def end_note(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def start_important(self, attrs=None):
+ self.new_paragraph()
+ self.doc.write('.. warning::')
+ self.indent()
+ self.new_paragraph()
+
+ def end_important(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def start_danger(self, attrs=None):
+ self.new_paragraph()
+ self.doc.write('.. danger::')
+ self.indent()
+ self.new_paragraph()
+
+ def end_danger(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def start_a(self, attrs=None):
+ # Write an empty space to guard against zero whitespace
+ # before an "a" tag. Example: hiExample
+ self.add_trailing_space_to_previous_write()
+ if attrs:
+ for attr_key, attr_value in attrs:
+ if attr_key == 'href':
+ # Removes unnecessary whitespace around the href link.
+ # Example: Example
+ self.a_href = attr_value.strip()
+ self.doc.write('`')
+ else:
+ # There are some model documentation that
+ # looks like this: DescribeInstances.
+ # In this case we just write out an empty
+ # string.
+ self.doc.write(' ')
+ self.doc.do_translation = True
+
+ def link_target_definition(self, refname, link):
+ self.doc.writeln(f'.. _{refname}: {link}')
+
+ def sphinx_reference_label(self, label, text=None):
+ if text is None:
+ text = label
+ if self.doc.target == 'html':
+ self.doc.write(f':ref:`{text} <{label}>`')
+ else:
+ self.doc.write(text)
+
+ def _clean_link_text(self):
+ doc = self.doc
+ # Pop till we reach the link start character to retrieve link text.
+ last_write = doc.pop_write()
+ while not last_write.startswith('`'):
+ last_write = doc.pop_write() + last_write
+ if last_write != '':
+ # Remove whitespace from the start of link text.
+ if last_write.startswith('` '):
+ last_write = f'`{last_write[1:].lstrip(" ")}'
+ doc.push_write(last_write)
+
+ def end_a(self, next_child=None):
+ self.doc.do_translation = False
+ if self.a_href:
+ self._clean_link_text()
+ last_write = self.doc.pop_write()
+ last_write = last_write.rstrip(' ')
+ if last_write and last_write != '`':
+ if ':' in last_write:
+ last_write = last_write.replace(':', r'\:')
+ self.doc.push_write(last_write)
+ self.doc.push_write(' <%s>`__' % self.a_href)
+ elif last_write == '`':
+ # Look at start_a(). It will do a self.doc.write('`')
+ # which is the start of the link title. If that is the
+ # case then there was no link text. We should just
+ # use an inline link. The syntax of this is
+ # ``_
+ self.doc.push_write('`<%s>`__' % self.a_href)
+ else:
+ self.doc.push_write(self.a_href)
+ self.doc.hrefs[self.a_href] = self.a_href
+ self.doc.write('`__')
+ self.a_href = None
+
+ def start_i(self, attrs=None):
+ self.doc.do_translation = True
+ self.start_italics()
+
+ def end_i(self):
+ self.doc.do_translation = False
+ self.end_italics()
+
+ def start_li(self, attrs=None):
+ self.new_line()
+ self.do_p = False
+ self.doc.write('* ')
+
+ def end_li(self):
+ self.do_p = True
+ self.new_line()
+
+ def li(self, s):
+ if s:
+ self.start_li()
+ self.doc.writeln(s)
+ self.end_li()
+
+ def start_ul(self, attrs=None):
+ if self.list_depth != 0:
+ self.indent()
+ self.list_depth += 1
+ self.new_paragraph()
+
+ def end_ul(self):
+ self.list_depth -= 1
+ if self.list_depth != 0:
+ self.dedent()
+ self.new_paragraph()
+
+ def start_ol(self, attrs=None):
+ # TODO: Need to control the bullets used for LI items
+ if self.list_depth != 0:
+ self.indent()
+ self.list_depth += 1
+ self.new_paragraph()
+
+ def end_ol(self):
+ self.list_depth -= 1
+ if self.list_depth != 0:
+ self.dedent()
+ self.new_paragraph()
+
+ def start_examples(self, attrs=None):
+ self.doc.keep_data = False
+
+ def end_examples(self):
+ self.doc.keep_data = True
+
+ def start_fullname(self, attrs=None):
+ self.doc.keep_data = False
+
+ def end_fullname(self):
+ self.doc.keep_data = True
+
+ def start_codeblock(self, attrs=None):
+ self.doc.write('::')
+ self.indent()
+ self.new_paragraph()
+
+ def end_codeblock(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def codeblock(self, code):
+ """
+ Literal code blocks are introduced by ending a paragraph with
+ the special marker ::. The literal block must be indented
+ (and, like all paragraphs, separated from the surrounding
+ ones by blank lines).
+ """
+ self.start_codeblock()
+ self.doc.writeln(code)
+ self.end_codeblock()
+
+ def toctree(self):
+ if self.doc.target == 'html':
+ self.doc.write('\n.. toctree::\n')
+ self.doc.write(' :maxdepth: 1\n')
+ self.doc.write(' :titlesonly:\n\n')
+ else:
+ self.start_ul()
+
+ def tocitem(self, item, file_name=None):
+ if self.doc.target == 'man':
+ self.li(item)
+ else:
+ if file_name:
+ self.doc.writeln(' %s' % file_name)
+ else:
+ self.doc.writeln(' %s' % item)
+
+ def hidden_toctree(self):
+ if self.doc.target == 'html':
+ self.doc.write('\n.. toctree::\n')
+ self.doc.write(' :maxdepth: 1\n')
+ self.doc.write(' :hidden:\n\n')
+
+ def hidden_tocitem(self, item):
+ if self.doc.target == 'html':
+ self.tocitem(item)
+
+ def table_of_contents(self, title=None, depth=None):
+ self.doc.write('.. contents:: ')
+ if title is not None:
+ self.doc.writeln(title)
+ if depth is not None:
+ self.doc.writeln(' :depth: %s' % depth)
+
+ def start_sphinx_py_class(self, class_name):
+ self.new_paragraph()
+ self.doc.write('.. py:class:: %s' % class_name)
+ self.indent()
+ self.new_paragraph()
+
+ def end_sphinx_py_class(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def start_sphinx_py_method(self, method_name, parameters=None):
+ self.new_paragraph()
+ content = '.. py:method:: %s' % method_name
+ if parameters is not None:
+ content += '(%s)' % parameters
+ self.doc.write(content)
+ self.indent()
+ self.new_paragraph()
+
+ def end_sphinx_py_method(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def start_sphinx_py_attr(self, attr_name):
+ self.new_paragraph()
+ self.doc.write('.. py:attribute:: %s' % attr_name)
+ self.indent()
+ self.new_paragraph()
+
+ def end_sphinx_py_attr(self):
+ self.dedent()
+ self.new_paragraph()
+
+ def write_py_doc_string(self, docstring):
+ docstring_lines = docstring.splitlines()
+ for docstring_line in docstring_lines:
+ self.doc.writeln(docstring_line)
+
+ def external_link(self, title, link):
+ if self.doc.target == 'html':
+ self.doc.write(f'`{title} <{link}>`_')
+ else:
+ self.doc.write(title)
+
+ def internal_link(self, title, page):
+ if self.doc.target == 'html':
+ self.doc.write(f':doc:`{title} <{page}>`')
+ else:
+ self.doc.write(title)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/client.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/client.py
new file mode 100644
index 0000000000..bc9b2658c9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/client.py
@@ -0,0 +1,455 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.compat import OrderedDict
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.example import ResponseExampleDocumenter
+from botocore.docs.method import (
+ document_custom_method,
+ document_model_driven_method,
+ get_instance_public_methods,
+)
+from botocore.docs.params import ResponseParamsDocumenter
+from botocore.docs.sharedexample import document_shared_examples
+from botocore.docs.utils import DocumentedShape, get_official_service_name
+
+
+def _allowlist_generate_presigned_url(method_name, service_name, **kwargs):
+ if method_name != 'generate_presigned_url':
+ return None
+ return service_name in ['s3']
+
+
+class ClientDocumenter:
+ _CLIENT_METHODS_FILTERS = [
+ _allowlist_generate_presigned_url,
+ ]
+
+ def __init__(self, client, root_docs_path, shared_examples=None):
+ self._client = client
+ self._client_class_name = self._client.__class__.__name__
+ self._root_docs_path = root_docs_path
+ self._shared_examples = shared_examples
+ if self._shared_examples is None:
+ self._shared_examples = {}
+ self._service_name = self._client.meta.service_model.service_name
+
+ def document_client(self, section):
+ """Documents a client and its methods
+
+ :param section: The section to write to.
+ """
+ self._add_title(section)
+ self._add_class_signature(section)
+ client_methods = self._get_client_methods()
+ self._add_client_intro(section, client_methods)
+ self._add_client_methods(client_methods)
+
+ def _get_client_methods(self):
+ client_methods = get_instance_public_methods(self._client)
+ return self._filter_client_methods(client_methods)
+
+ def _filter_client_methods(self, client_methods):
+ filtered_methods = {}
+ for method_name, method in client_methods.items():
+ include = self._filter_client_method(
+ method=method,
+ method_name=method_name,
+ service_name=self._service_name,
+ )
+ if include:
+ filtered_methods[method_name] = method
+ return filtered_methods
+
+ def _filter_client_method(self, **kwargs):
+ # Apply each filter to the method
+ for filter in self._CLIENT_METHODS_FILTERS:
+ filter_include = filter(**kwargs)
+ # Use the first non-None value returned by any of the filters
+ if filter_include is not None:
+ return filter_include
+ # Otherwise default to including it
+ return True
+
+ def _add_title(self, section):
+ section.style.h2('Client')
+
+ def _add_client_intro(self, section, client_methods):
+ section = section.add_new_section('intro')
+ # Write out the top level description for the client.
+ official_service_name = get_official_service_name(
+ self._client.meta.service_model
+ )
+ section.write(
+ f"A low-level client representing {official_service_name}"
+ )
+ section.style.new_line()
+ section.include_doc_string(
+ self._client.meta.service_model.documentation
+ )
+
+ # Write out the client example instantiation.
+ self._add_client_creation_example(section)
+
+ # List out all of the possible client methods.
+ section.style.dedent()
+ section.style.new_paragraph()
+ section.writeln('These are the available methods:')
+ section.style.toctree()
+ for method_name in sorted(client_methods):
+ section.style.tocitem(f'{self._service_name}/client/{method_name}')
+
+ def _add_class_signature(self, section):
+ section.style.start_sphinx_py_class(
+ class_name=f'{self._client_class_name}.Client'
+ )
+
+ def _add_client_creation_example(self, section):
+ section.style.start_codeblock()
+ section.style.new_line()
+ section.write(
+ 'client = session.create_client(\'{service}\')'.format(
+ service=self._service_name
+ )
+ )
+ section.style.end_codeblock()
+
+ def _add_client_methods(self, client_methods):
+ for method_name in sorted(client_methods):
+ # Create a new DocumentStructure for each client method and add contents.
+ method_doc_structure = DocumentStructure(
+ method_name, target='html'
+ )
+ self._add_client_method(
+ method_doc_structure, method_name, client_methods[method_name]
+ )
+ # Write client methods in individual/nested files.
+ # Path: /reference/services//client/.rst
+ client_dir_path = os.path.join(
+ self._root_docs_path, self._service_name, 'client'
+ )
+ method_doc_structure.write_to_file(client_dir_path, method_name)
+
+ def _add_client_method(self, section, method_name, method):
+ breadcrumb_section = section.add_new_section('breadcrumb')
+ breadcrumb_section.style.ref(
+ self._client_class_name, f'../../{self._service_name}'
+ )
+ breadcrumb_section.write(f' / Client / {method_name}')
+ section.add_title_section(method_name)
+ method_section = section.add_new_section(
+ method_name,
+ context={'qualifier': f'{self._client_class_name}.Client.'},
+ )
+ if self._is_custom_method(method_name):
+ self._add_custom_method(
+ method_section,
+ method_name,
+ method,
+ )
+ else:
+ self._add_model_driven_method(method_section, method_name)
+
+ def _is_custom_method(self, method_name):
+ return method_name not in self._client.meta.method_to_api_mapping
+
+ def _add_custom_method(self, section, method_name, method):
+ document_custom_method(section, method_name, method)
+
+ def _add_method_exceptions_list(self, section, operation_model):
+ error_section = section.add_new_section('exceptions')
+ error_section.style.new_line()
+ error_section.style.bold('Exceptions')
+ error_section.style.new_line()
+ for error in operation_model.error_shapes:
+ class_name = (
+ f'{self._client_class_name}.Client.exceptions.{error.name}'
+ )
+ error_section.style.li(':py:class:`%s`' % class_name)
+
+ def _add_model_driven_method(self, section, method_name):
+ service_model = self._client.meta.service_model
+ operation_name = self._client.meta.method_to_api_mapping[method_name]
+ operation_model = service_model.operation_model(operation_name)
+
+ example_prefix = 'response = client.%s' % method_name
+ full_method_name = (
+ f"{section.context.get('qualifier', '')}{method_name}"
+ )
+ document_model_driven_method(
+ section,
+ full_method_name,
+ operation_model,
+ event_emitter=self._client.meta.events,
+ method_description=operation_model.documentation,
+ example_prefix=example_prefix,
+ )
+
+ # Add any modeled exceptions
+ if operation_model.error_shapes:
+ self._add_method_exceptions_list(section, operation_model)
+
+ # Add the shared examples
+ shared_examples = self._shared_examples.get(operation_name)
+ if shared_examples:
+ document_shared_examples(
+ section, operation_model, example_prefix, shared_examples
+ )
+
+
+class ClientExceptionsDocumenter:
+ _USER_GUIDE_LINK = (
+ 'https://boto3.amazonaws.com/'
+ 'v1/documentation/api/latest/guide/error-handling.html'
+ )
+ _GENERIC_ERROR_SHAPE = DocumentedShape(
+ name='Error',
+ type_name='structure',
+ documentation=('Normalized access to common exception attributes.'),
+ members=OrderedDict(
+ [
+ (
+ 'Code',
+ DocumentedShape(
+ name='Code',
+ type_name='string',
+ documentation=(
+ 'An identifier specifying the exception type.'
+ ),
+ ),
+ ),
+ (
+ 'Message',
+ DocumentedShape(
+ name='Message',
+ type_name='string',
+ documentation=(
+ 'A descriptive message explaining why the exception '
+ 'occured.'
+ ),
+ ),
+ ),
+ ]
+ ),
+ )
+
+ def __init__(self, client, root_docs_path):
+ self._client = client
+ self._client_class_name = self._client.__class__.__name__
+ self._service_name = self._client.meta.service_model.service_name
+ self._root_docs_path = root_docs_path
+
+ def document_exceptions(self, section):
+ self._add_title(section)
+ self._add_overview(section)
+ self._add_exceptions_list(section)
+ self._add_exception_classes()
+
+ def _add_title(self, section):
+ section.style.h2('Client Exceptions')
+
+ def _add_overview(self, section):
+ section.style.new_line()
+ section.write(
+ 'Client exceptions are available on a client instance '
+ 'via the ``exceptions`` property. For more detailed instructions '
+ 'and examples on the exact usage of client exceptions, see the '
+ 'error handling '
+ )
+ section.style.external_link(
+ title='user guide',
+ link=self._USER_GUIDE_LINK,
+ )
+ section.write('.')
+ section.style.new_line()
+
+ def _exception_class_name(self, shape):
+ return f'{self._client_class_name}.Client.exceptions.{shape.name}'
+
+ def _add_exceptions_list(self, section):
+ error_shapes = self._client.meta.service_model.error_shapes
+ if not error_shapes:
+ section.style.new_line()
+ section.write('This client has no modeled exception classes.')
+ section.style.new_line()
+ return
+ section.style.new_line()
+ section.writeln('The available client exceptions are:')
+ section.style.toctree()
+ for shape in error_shapes:
+ section.style.tocitem(
+ f'{self._service_name}/client/exceptions/{shape.name}'
+ )
+
+ def _add_exception_classes(self):
+ for shape in self._client.meta.service_model.error_shapes:
+ # Create a new DocumentStructure for each exception method and add contents.
+ exception_doc_structure = DocumentStructure(
+ shape.name, target='html'
+ )
+ self._add_exception_class(exception_doc_structure, shape)
+ # Write exceptions in individual/nested files.
+ # Path: /reference/services//client/exceptions/.rst
+ exception_dir_path = os.path.join(
+ self._root_docs_path,
+ self._service_name,
+ 'client',
+ 'exceptions',
+ )
+ exception_doc_structure.write_to_file(
+ exception_dir_path, shape.name
+ )
+
+ def _add_exception_class(self, section, shape):
+ breadcrumb_section = section.add_new_section('breadcrumb')
+ breadcrumb_section.style.ref(
+ self._client_class_name, f'../../../{self._service_name}'
+ )
+ breadcrumb_section.write(f' / Client / exceptions / {shape.name}')
+ section.add_title_section(shape.name)
+ class_section = section.add_new_section(shape.name)
+ class_name = self._exception_class_name(shape)
+ class_section.style.start_sphinx_py_class(class_name=class_name)
+ self._add_top_level_documentation(class_section, shape)
+ self._add_exception_catch_example(class_section, shape)
+ self._add_response_attr(class_section, shape)
+ class_section.style.end_sphinx_py_class()
+
+ def _add_top_level_documentation(self, section, shape):
+ if shape.documentation:
+ section.style.new_line()
+ section.include_doc_string(shape.documentation)
+ section.style.new_line()
+
+ def _add_exception_catch_example(self, section, shape):
+ section.style.new_line()
+ section.style.bold('Example')
+ section.style.new_paragraph()
+ section.style.start_codeblock()
+ section.write('try:')
+ section.style.indent()
+ section.style.new_line()
+ section.write('...')
+ section.style.dedent()
+ section.style.new_line()
+ section.write('except client.exceptions.%s as e:' % shape.name)
+ section.style.indent()
+ section.style.new_line()
+ section.write('print(e.response)')
+ section.style.dedent()
+ section.style.end_codeblock()
+
+ def _add_response_attr(self, section, shape):
+ response_section = section.add_new_section('response')
+ response_section.style.start_sphinx_py_attr('response')
+ self._add_response_attr_description(response_section)
+ self._add_response_example(response_section, shape)
+ self._add_response_params(response_section, shape)
+ response_section.style.end_sphinx_py_attr()
+
+ def _add_response_attr_description(self, section):
+ section.style.new_line()
+ section.include_doc_string(
+ 'The parsed error response. All exceptions have a top level '
+ '``Error`` key that provides normalized access to common '
+ 'exception atrributes. All other keys are specific to this '
+ 'service or exception class.'
+ )
+ section.style.new_line()
+
+ def _add_response_example(self, section, shape):
+ example_section = section.add_new_section('syntax')
+ example_section.style.new_line()
+ example_section.style.bold('Syntax')
+ example_section.style.new_paragraph()
+ documenter = ResponseExampleDocumenter(
+ service_name=self._service_name,
+ operation_name=None,
+ event_emitter=self._client.meta.events,
+ )
+ documenter.document_example(
+ example_section,
+ shape,
+ include=[self._GENERIC_ERROR_SHAPE],
+ )
+
+ def _add_response_params(self, section, shape):
+ params_section = section.add_new_section('Structure')
+ params_section.style.new_line()
+ params_section.style.bold('Structure')
+ params_section.style.new_paragraph()
+ documenter = ResponseParamsDocumenter(
+ service_name=self._service_name,
+ operation_name=None,
+ event_emitter=self._client.meta.events,
+ )
+ documenter.document_params(
+ params_section,
+ shape,
+ include=[self._GENERIC_ERROR_SHAPE],
+ )
+
+
+class ClientContextParamsDocumenter:
+ _CONFIG_GUIDE_LINK = (
+ 'https://boto3.amazonaws.com/'
+ 'v1/documentation/api/latest/guide/configuration.html'
+ )
+
+ OMITTED_CONTEXT_PARAMS = {
+ 's3': (
+ 'Accelerate',
+ 'DisableMultiRegionAccessPoints',
+ 'ForcePathStyle',
+ 'UseArnRegion',
+ ),
+ 's3control': ('UseArnRegion',),
+ }
+
+ def __init__(self, service_name, context_params):
+ self._service_name = service_name
+ self._context_params = context_params
+
+ def document_context_params(self, section):
+ self._add_title(section)
+ self._add_overview(section)
+ self._add_context_params_list(section)
+
+ def _add_title(self, section):
+ section.style.h2('Client Context Parameters')
+
+ def _add_overview(self, section):
+ section.style.new_line()
+ section.write(
+ 'Client context parameters are configurable on a client '
+ 'instance via the ``client_context_params`` parameter in the '
+ '``Config`` object. For more detailed instructions and examples '
+ 'on the exact usage of context params see the '
+ )
+ section.style.external_link(
+ title='configuration guide',
+ link=self._CONFIG_GUIDE_LINK,
+ )
+ section.write('.')
+ section.style.new_line()
+
+ def _add_context_params_list(self, section):
+ section.style.new_line()
+ sn = f'``{self._service_name}``'
+ section.writeln(f'The available {sn} client context params are:')
+ for param in self._context_params:
+ section.style.new_line()
+ name = f'``{xform_name(param.name)}``'
+ section.write(f'* {name} ({param.type}) - {param.documentation}')
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/docstring.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/docstring.py
new file mode 100644
index 0000000000..93b2e6b23c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/docstring.py
@@ -0,0 +1,97 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.method import document_model_driven_method
+from botocore.docs.paginator import document_paginate_method
+from botocore.docs.waiter import document_wait_method
+
+
+class LazyLoadedDocstring(str):
+ """Used for lazily loading docstrings
+
+ You can instantiate this class and assign it to a __doc__ value.
+ The docstring will not be generated till accessed via __doc__ or
+ help(). Note that all docstring classes **must** subclass from
+ this class. It cannot be used directly as a docstring.
+ """
+
+ def __init__(self, *args, **kwargs):
+ """
+ The args and kwargs are the same as the underlying document
+ generation function. These just get proxied to the underlying
+ function.
+ """
+ super().__init__()
+ self._gen_args = args
+ self._gen_kwargs = kwargs
+ self._docstring = None
+
+ def __new__(cls, *args, **kwargs):
+ # Needed in order to sub class from str with args and kwargs
+ return super().__new__(cls)
+
+ def _write_docstring(self, *args, **kwargs):
+ raise NotImplementedError(
+ '_write_docstring is not implemented. Please subclass from '
+ 'this class and provide your own _write_docstring method'
+ )
+
+ def expandtabs(self, tabsize=8):
+ """Expands tabs to spaces
+
+ So this is a big hack in order to get lazy loaded docstring work
+ for the ``help()``. In the ``help()`` function, ``pydoc`` and
+ ``inspect`` are used. At some point the ``inspect.cleandoc``
+ method is called. To clean the docs ``expandtabs`` is called
+ and that is where we override the method to generate and return the
+ docstrings.
+ """
+ if self._docstring is None:
+ self._generate()
+ return self._docstring.expandtabs(tabsize)
+
+ def __str__(self):
+ return self._generate()
+
+ # __doc__ of target will use either __repr__ or __str__ of this class.
+ __repr__ = __str__
+
+ def _generate(self):
+ # Generate the docstring if it is not already cached.
+ if self._docstring is None:
+ self._docstring = self._create_docstring()
+ return self._docstring
+
+ def _create_docstring(self):
+ docstring_structure = DocumentStructure('docstring', target='html')
+ # Call the document method function with the args and kwargs
+ # passed to the class.
+ self._write_docstring(
+ docstring_structure, *self._gen_args, **self._gen_kwargs
+ )
+ return docstring_structure.flush_structure().decode('utf-8')
+
+
+class ClientMethodDocstring(LazyLoadedDocstring):
+ def _write_docstring(self, *args, **kwargs):
+ document_model_driven_method(*args, **kwargs)
+
+
+class WaiterDocstring(LazyLoadedDocstring):
+ def _write_docstring(self, *args, **kwargs):
+ document_wait_method(*args, **kwargs)
+
+
+class PaginatorDocstring(LazyLoadedDocstring):
+ def _write_docstring(self, *args, **kwargs):
+ document_paginate_method(*args, **kwargs)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/example.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/example.py
new file mode 100644
index 0000000000..9f831bcde1
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/example.py
@@ -0,0 +1,236 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.shape import ShapeDocumenter
+from botocore.docs.utils import py_default
+
+
+class BaseExampleDocumenter(ShapeDocumenter):
+ def document_example(
+ self, section, shape, prefix=None, include=None, exclude=None
+ ):
+ """Generates an example based on a shape
+
+ :param section: The section to write the documentation to.
+
+ :param shape: The shape of the operation.
+
+ :param prefix: Anything to be included before the example
+
+ :type include: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include: The parameter shapes to include in the documentation.
+
+ :type exclude: List of the names of the parameters to exclude.
+ :param exclude: The names of the parameters to exclude from
+ documentation.
+ """
+ history = []
+ section.style.new_line()
+ section.style.start_codeblock()
+ if prefix is not None:
+ section.write(prefix)
+ self.traverse_and_document_shape(
+ section=section,
+ shape=shape,
+ history=history,
+ include=include,
+ exclude=exclude,
+ )
+ final_blank_line_section = section.add_new_section('final-blank-line')
+ final_blank_line_section.style.new_line()
+
+ def document_recursive_shape(self, section, shape, **kwargs):
+ section.write('{\'... recursive ...\'}')
+
+ def document_shape_default(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ py_type = self._get_special_py_default(shape)
+ if py_type is None:
+ py_type = py_default(shape.type_name)
+
+ if self._context.get('streaming_shape') == shape:
+ py_type = 'StreamingBody()'
+ section.write(py_type)
+
+ def document_shape_type_string(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ if 'enum' in shape.metadata:
+ for i, enum in enumerate(shape.metadata['enum']):
+ section.write('\'%s\'' % enum)
+ if i < len(shape.metadata['enum']) - 1:
+ section.write('|')
+ else:
+ self.document_shape_default(section, shape, history)
+
+ def document_shape_type_list(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ param_shape = shape.member
+ list_section = section.add_new_section('list-value')
+ self._start_nested_param(list_section, '[')
+ param_section = list_section.add_new_section(
+ 'member', context={'shape': param_shape.name}
+ )
+ self.traverse_and_document_shape(
+ section=param_section, shape=param_shape, history=history
+ )
+ ending_comma_section = list_section.add_new_section('ending-comma')
+ ending_comma_section.write(',')
+ ending_bracket_section = list_section.add_new_section('ending-bracket')
+ self._end_nested_param(ending_bracket_section, ']')
+
+ def document_shape_type_structure(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ if not shape.members:
+ section.write('{}')
+ return
+
+ section = section.add_new_section('structure-value')
+ self._start_nested_param(section, '{')
+
+ input_members = self._add_members_to_shape(shape.members, include)
+
+ for i, param in enumerate(input_members):
+ if exclude and param in exclude:
+ continue
+ param_section = section.add_new_section(param)
+ param_section.write('\'%s\': ' % param)
+ param_shape = input_members[param]
+ param_value_section = param_section.add_new_section(
+ 'member-value', context={'shape': param_shape.name}
+ )
+ self.traverse_and_document_shape(
+ section=param_value_section,
+ shape=param_shape,
+ history=history,
+ name=param,
+ )
+ if i < len(input_members) - 1:
+ ending_comma_section = param_section.add_new_section(
+ 'ending-comma'
+ )
+ ending_comma_section.write(',')
+ ending_comma_section.style.new_line()
+ self._end_structure(section, '{', '}')
+
+ def document_shape_type_map(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ map_section = section.add_new_section('map-value')
+ self._start_nested_param(map_section, '{')
+ value_shape = shape.value
+ key_section = map_section.add_new_section(
+ 'key', context={'shape': shape.key.name}
+ )
+ key_section.write('\'string\': ')
+ value_section = map_section.add_new_section(
+ 'value', context={'shape': value_shape.name}
+ )
+ self.traverse_and_document_shape(
+ section=value_section, shape=value_shape, history=history
+ )
+ end_bracket_section = map_section.add_new_section('ending-bracket')
+ self._end_nested_param(end_bracket_section, '}')
+
+ def _add_members_to_shape(self, members, include):
+ if include:
+ members = members.copy()
+ for param in include:
+ members[param.name] = param
+ return members
+
+ def _start_nested_param(self, section, start=None):
+ if start is not None:
+ section.write(start)
+ section.style.indent()
+ section.style.indent()
+ section.style.new_line()
+
+ def _end_nested_param(self, section, end=None):
+ section.style.dedent()
+ section.style.dedent()
+ section.style.new_line()
+ if end is not None:
+ section.write(end)
+
+ def _end_structure(self, section, start, end):
+ # If there are no members in the strucuture, then make sure the
+ # start and the end bracket are on the same line, by removing all
+ # previous text and writing the start and end.
+ if not section.available_sections:
+ section.clear_text()
+ section.write(start + end)
+ self._end_nested_param(section)
+ else:
+ end_bracket_section = section.add_new_section('ending-bracket')
+ self._end_nested_param(end_bracket_section, end)
+
+
+class ResponseExampleDocumenter(BaseExampleDocumenter):
+ EVENT_NAME = 'response-example'
+
+ def document_shape_type_event_stream(
+ self, section, shape, history, **kwargs
+ ):
+ section.write('EventStream(')
+ self.document_shape_type_structure(section, shape, history, **kwargs)
+ end_section = section.add_new_section('event-stream-end')
+ end_section.write(')')
+
+
+class RequestExampleDocumenter(BaseExampleDocumenter):
+ EVENT_NAME = 'request-example'
+
+ def document_shape_type_structure(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ param_format = '\'%s\''
+ operator = ': '
+ start = '{'
+ end = '}'
+
+ if len(history) <= 1:
+ operator = '='
+ start = '('
+ end = ')'
+ param_format = '%s'
+ section = section.add_new_section('structure-value')
+ self._start_nested_param(section, start)
+ input_members = self._add_members_to_shape(shape.members, include)
+
+ for i, param in enumerate(input_members):
+ if exclude and param in exclude:
+ continue
+ param_section = section.add_new_section(param)
+ param_section.write(param_format % param)
+ param_section.write(operator)
+ param_shape = input_members[param]
+ param_value_section = param_section.add_new_section(
+ 'member-value', context={'shape': param_shape.name}
+ )
+ self.traverse_and_document_shape(
+ section=param_value_section,
+ shape=param_shape,
+ history=history,
+ name=param,
+ )
+ if i < len(input_members) - 1:
+ ending_comma_section = param_section.add_new_section(
+ 'ending-comma'
+ )
+ ending_comma_section.write(',')
+ ending_comma_section.style.new_line()
+ self._end_structure(section, start, end)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/method.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/method.py
new file mode 100644
index 0000000000..5db906c8dd
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/method.py
@@ -0,0 +1,328 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import inspect
+import types
+
+from botocore.docs.example import (
+ RequestExampleDocumenter,
+ ResponseExampleDocumenter,
+)
+from botocore.docs.params import (
+ RequestParamsDocumenter,
+ ResponseParamsDocumenter,
+)
+
+AWS_DOC_BASE = 'https://docs.aws.amazon.com/goto/WebAPI'
+
+
+def get_instance_public_methods(instance):
+ """Retrieves an objects public methods
+
+ :param instance: The instance of the class to inspect
+ :rtype: dict
+ :returns: A dictionary that represents an instance's methods where
+ the keys are the name of the methods and the
+ values are the handler to the method.
+ """
+ instance_members = inspect.getmembers(instance)
+ instance_methods = {}
+ for name, member in instance_members:
+ if not name.startswith('_'):
+ if inspect.ismethod(member):
+ instance_methods[name] = member
+ return instance_methods
+
+
+def document_model_driven_signature(
+ section, name, operation_model, include=None, exclude=None
+):
+ """Documents the signature of a model-driven method
+
+ :param section: The section to write the documentation to.
+
+ :param name: The name of the method
+
+ :param operation_model: The operation model for the method
+
+ :type include: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include: The parameter shapes to include in the documentation.
+
+ :type exclude: List of the names of the parameters to exclude.
+ :param exclude: The names of the parameters to exclude from
+ documentation.
+ """
+ params = {}
+ if operation_model.input_shape:
+ params = operation_model.input_shape.members
+
+ parameter_names = list(params.keys())
+
+ if include is not None:
+ for member in include:
+ parameter_names.append(member.name)
+
+ if exclude is not None:
+ for member in exclude:
+ if member in parameter_names:
+ parameter_names.remove(member)
+
+ signature_params = ''
+ if parameter_names:
+ signature_params = '**kwargs'
+ section.style.start_sphinx_py_method(name, signature_params)
+
+
+def document_custom_signature(
+ section, name, method, include=None, exclude=None
+):
+ """Documents the signature of a custom method
+
+ :param section: The section to write the documentation to.
+
+ :param name: The name of the method
+
+ :param method: The handle to the method being documented
+
+ :type include: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include: The parameter shapes to include in the documentation.
+
+ :type exclude: List of the names of the parameters to exclude.
+ :param exclude: The names of the parameters to exclude from
+ documentation.
+ """
+ signature = inspect.signature(method)
+ # "raw" class methods are FunctionType and they include "self" param
+ # object methods are MethodType and they skip the "self" param
+ if isinstance(method, types.FunctionType):
+ self_param = next(iter(signature.parameters))
+ self_kind = signature.parameters[self_param].kind
+ # safety check that we got the right parameter
+ assert self_kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
+ new_params = signature.parameters.copy()
+ del new_params[self_param]
+ signature = signature.replace(parameters=new_params.values())
+ signature_params = str(signature).lstrip('(')
+ signature_params = signature_params.rstrip(')')
+ section.style.start_sphinx_py_method(name, signature_params)
+
+
+def document_custom_method(section, method_name, method):
+ """Documents a non-data driven method
+
+ :param section: The section to write the documentation to.
+
+ :param method_name: The name of the method
+
+ :param method: The handle to the method being documented
+ """
+ full_method_name = f"{section.context.get('qualifier', '')}{method_name}"
+ document_custom_signature(section, full_method_name, method)
+ method_intro_section = section.add_new_section('method-intro')
+ method_intro_section.writeln('')
+ doc_string = inspect.getdoc(method)
+ if doc_string is not None:
+ method_intro_section.style.write_py_doc_string(doc_string)
+
+
+def document_model_driven_method(
+ section,
+ method_name,
+ operation_model,
+ event_emitter,
+ method_description=None,
+ example_prefix=None,
+ include_input=None,
+ include_output=None,
+ exclude_input=None,
+ exclude_output=None,
+ document_output=True,
+ include_signature=True,
+):
+ """Documents an individual method
+
+ :param section: The section to write to
+
+ :param method_name: The name of the method
+
+ :param operation_model: The model of the operation
+
+ :param event_emitter: The event emitter to use to emit events
+
+ :param example_prefix: The prefix to use in the method example.
+
+ :type include_input: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include_input: The parameter shapes to include in the
+ input documentation.
+
+ :type include_output: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include_input: The parameter shapes to include in the
+ output documentation.
+
+ :type exclude_input: List of the names of the parameters to exclude.
+ :param exclude_input: The names of the parameters to exclude from
+ input documentation.
+
+ :type exclude_output: List of the names of the parameters to exclude.
+ :param exclude_input: The names of the parameters to exclude from
+ output documentation.
+
+ :param document_output: A boolean flag to indicate whether to
+ document the output.
+
+ :param include_signature: Whether or not to include the signature.
+ It is useful for generating docstrings.
+ """
+ # Add the signature if specified.
+ if include_signature:
+ document_model_driven_signature(
+ section,
+ method_name,
+ operation_model,
+ include=include_input,
+ exclude=exclude_input,
+ )
+
+ # Add the description for the method.
+ method_intro_section = section.add_new_section('method-intro')
+ method_intro_section.include_doc_string(method_description)
+ if operation_model.deprecated:
+ method_intro_section.style.start_danger()
+ method_intro_section.writeln(
+ 'This operation is deprecated and may not function as '
+ 'expected. This operation should not be used going forward '
+ 'and is only kept for the purpose of backwards compatiblity.'
+ )
+ method_intro_section.style.end_danger()
+ service_uid = operation_model.service_model.metadata.get('uid')
+ if service_uid is not None:
+ method_intro_section.style.new_paragraph()
+ method_intro_section.write("See also: ")
+ link = f"{AWS_DOC_BASE}/{service_uid}/{operation_model.name}"
+ method_intro_section.style.external_link(
+ title="AWS API Documentation", link=link
+ )
+ method_intro_section.writeln('')
+
+ # Add the example section.
+ example_section = section.add_new_section('request-example')
+ example_section.style.new_paragraph()
+ example_section.style.bold('Request Syntax')
+
+ context = {
+ 'special_shape_types': {
+ 'streaming_input_shape': operation_model.get_streaming_input(),
+ 'streaming_output_shape': operation_model.get_streaming_output(),
+ 'eventstream_output_shape': operation_model.get_event_stream_output(),
+ },
+ }
+
+ if operation_model.input_shape:
+ RequestExampleDocumenter(
+ service_name=operation_model.service_model.service_name,
+ operation_name=operation_model.name,
+ event_emitter=event_emitter,
+ context=context,
+ ).document_example(
+ example_section,
+ operation_model.input_shape,
+ prefix=example_prefix,
+ include=include_input,
+ exclude=exclude_input,
+ )
+ else:
+ example_section.style.new_paragraph()
+ example_section.style.start_codeblock()
+ example_section.write(example_prefix + '()')
+
+ # Add the request parameter documentation.
+ request_params_section = section.add_new_section('request-params')
+ if operation_model.input_shape:
+ RequestParamsDocumenter(
+ service_name=operation_model.service_model.service_name,
+ operation_name=operation_model.name,
+ event_emitter=event_emitter,
+ context=context,
+ ).document_params(
+ request_params_section,
+ operation_model.input_shape,
+ include=include_input,
+ exclude=exclude_input,
+ )
+
+ # Add the return value documentation
+ return_section = section.add_new_section('return')
+ return_section.style.new_line()
+ if operation_model.output_shape is not None and document_output:
+ return_section.write(':rtype: dict')
+ return_section.style.new_line()
+ return_section.write(':returns: ')
+ return_section.style.indent()
+ return_section.style.new_line()
+
+ # If the operation is an event stream, describe the tagged union
+ event_stream_output = operation_model.get_event_stream_output()
+ if event_stream_output:
+ event_section = return_section.add_new_section('event-stream')
+ event_section.style.new_paragraph()
+ event_section.write(
+ 'The response of this operation contains an '
+ ':class:`.EventStream` member. When iterated the '
+ ':class:`.EventStream` will yield events based on the '
+ 'structure below, where only one of the top level keys '
+ 'will be present for any given event.'
+ )
+ event_section.style.new_line()
+
+ # Add an example return value
+ return_example_section = return_section.add_new_section(
+ 'response-example'
+ )
+ return_example_section.style.new_line()
+ return_example_section.style.bold('Response Syntax')
+ return_example_section.style.new_paragraph()
+ ResponseExampleDocumenter(
+ service_name=operation_model.service_model.service_name,
+ operation_name=operation_model.name,
+ event_emitter=event_emitter,
+ context=context,
+ ).document_example(
+ return_example_section,
+ operation_model.output_shape,
+ include=include_output,
+ exclude=exclude_output,
+ )
+
+ # Add a description for the return value
+ return_description_section = return_section.add_new_section(
+ 'description'
+ )
+ return_description_section.style.new_line()
+ return_description_section.style.bold('Response Structure')
+ return_description_section.style.new_paragraph()
+ ResponseParamsDocumenter(
+ service_name=operation_model.service_model.service_name,
+ operation_name=operation_model.name,
+ event_emitter=event_emitter,
+ context=context,
+ ).document_params(
+ return_description_section,
+ operation_model.output_shape,
+ include=include_output,
+ exclude=exclude_output,
+ )
+ else:
+ return_section.write(':returns: None')
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/paginator.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/paginator.py
new file mode 100644
index 0000000000..1ac4dd4848
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/paginator.py
@@ -0,0 +1,243 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.compat import OrderedDict
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.method import document_model_driven_method
+from botocore.docs.utils import DocumentedShape
+from botocore.utils import get_service_module_name
+
+
+class PaginatorDocumenter:
+ def __init__(self, client, service_paginator_model, root_docs_path):
+ self._client = client
+ self._client_class_name = self._client.__class__.__name__
+ self._service_name = self._client.meta.service_model.service_name
+ self._service_paginator_model = service_paginator_model
+ self._root_docs_path = root_docs_path
+ self._USER_GUIDE_LINK = (
+ 'https://boto3.amazonaws.com/'
+ 'v1/documentation/api/latest/guide/paginators.html'
+ )
+
+ def document_paginators(self, section):
+ """Documents the various paginators for a service
+
+ param section: The section to write to.
+ """
+ section.style.h2('Paginators')
+ self._add_overview(section)
+ section.style.new_line()
+ section.writeln('The available paginators are:')
+ section.style.toctree()
+
+ paginator_names = sorted(
+ self._service_paginator_model._paginator_config
+ )
+
+ # List the available paginators and then document each paginator.
+ for paginator_name in paginator_names:
+ section.style.tocitem(
+ f'{self._service_name}/paginator/{paginator_name}'
+ )
+ # Create a new DocumentStructure for each paginator and add contents.
+ paginator_doc_structure = DocumentStructure(
+ paginator_name, target='html'
+ )
+ self._add_paginator(paginator_doc_structure, paginator_name)
+ # Write paginators in individual/nested files.
+ # Path: /reference/services//paginator/.rst
+ paginator_dir_path = os.path.join(
+ self._root_docs_path, self._service_name, 'paginator'
+ )
+ paginator_doc_structure.write_to_file(
+ paginator_dir_path, paginator_name
+ )
+
+ def _add_paginator(self, section, paginator_name):
+ breadcrumb_section = section.add_new_section('breadcrumb')
+ breadcrumb_section.style.ref(
+ self._client_class_name, f'../../{self._service_name}'
+ )
+ breadcrumb_section.write(f' / Paginator / {paginator_name}')
+ section.add_title_section(paginator_name)
+
+ # Docment the paginator class
+ paginator_section = section.add_new_section(paginator_name)
+ paginator_section.style.start_sphinx_py_class(
+ class_name=(
+ f'{self._client_class_name}.Paginator.{paginator_name}'
+ )
+ )
+ paginator_section.style.start_codeblock()
+ paginator_section.style.new_line()
+
+ # Document how to instantiate the paginator.
+ paginator_section.write(
+ f"paginator = client.get_paginator('{xform_name(paginator_name)}')"
+ )
+ paginator_section.style.end_codeblock()
+ paginator_section.style.new_line()
+ # Get the pagination model for the particular paginator.
+ paginator_config = self._service_paginator_model.get_paginator(
+ paginator_name
+ )
+ document_paginate_method(
+ section=paginator_section,
+ paginator_name=paginator_name,
+ event_emitter=self._client.meta.events,
+ service_model=self._client.meta.service_model,
+ paginator_config=paginator_config,
+ )
+
+ def _add_overview(self, section):
+ section.style.new_line()
+ section.write(
+ 'Paginators are available on a client instance '
+ 'via the ``get_paginator`` method. For more detailed instructions '
+ 'and examples on the usage of paginators, see the '
+ 'paginators '
+ )
+ section.style.external_link(
+ title='user guide',
+ link=self._USER_GUIDE_LINK,
+ )
+ section.write('.')
+ section.style.new_line()
+
+
+def document_paginate_method(
+ section,
+ paginator_name,
+ event_emitter,
+ service_model,
+ paginator_config,
+ include_signature=True,
+):
+ """Documents the paginate method of a paginator
+
+ :param section: The section to write to
+
+ :param paginator_name: The name of the paginator. It is snake cased.
+
+ :param event_emitter: The event emitter to use to emit events
+
+ :param service_model: The service model
+
+ :param paginator_config: The paginator config associated to a particular
+ paginator.
+
+ :param include_signature: Whether or not to include the signature.
+ It is useful for generating docstrings.
+ """
+ # Retrieve the operation model of the underlying operation.
+ operation_model = service_model.operation_model(paginator_name)
+
+ # Add representations of the request and response parameters
+ # we want to include in the description of the paginate method.
+ # These are parameters we expose via the botocore interface.
+ pagination_config_members = OrderedDict()
+
+ pagination_config_members['MaxItems'] = DocumentedShape(
+ name='MaxItems',
+ type_name='integer',
+ documentation=(
+ 'The total number of items to return. If the total '
+ 'number of items available is more than the value '
+ 'specified in max-items then a NextToken '
+ 'will be provided in the output that you can use to '
+ 'resume pagination.
'
+ ),
+ )
+
+ if paginator_config.get('limit_key', None):
+ pagination_config_members['PageSize'] = DocumentedShape(
+ name='PageSize',
+ type_name='integer',
+ documentation='The size of each page.
',
+ )
+
+ pagination_config_members['StartingToken'] = DocumentedShape(
+ name='StartingToken',
+ type_name='string',
+ documentation=(
+ '
A token to specify where to start paginating. '
+ 'This is the NextToken from a previous '
+ 'response.
'
+ ),
+ )
+
+ botocore_pagination_params = [
+ DocumentedShape(
+ name='PaginationConfig',
+ type_name='structure',
+ documentation=(
+ 'A dictionary that provides parameters to control '
+ 'pagination.
'
+ ),
+ members=pagination_config_members,
+ )
+ ]
+
+ botocore_pagination_response_params = [
+ DocumentedShape(
+ name='NextToken',
+ type_name='string',
+ documentation=('A token to resume pagination.
'),
+ )
+ ]
+
+ service_pagination_params = []
+
+ # Add the normal input token of the method to a list
+ # of input paramters that we wish to hide since we expose our own.
+ if isinstance(paginator_config['input_token'], list):
+ service_pagination_params += paginator_config['input_token']
+ else:
+ service_pagination_params.append(paginator_config['input_token'])
+
+ # Hide the limit key in the documentation.
+ if paginator_config.get('limit_key', None):
+ service_pagination_params.append(paginator_config['limit_key'])
+
+ # Hide the output tokens in the documentation.
+ service_pagination_response_params = []
+ if isinstance(paginator_config['output_token'], list):
+ service_pagination_response_params += paginator_config['output_token']
+ else:
+ service_pagination_response_params.append(
+ paginator_config['output_token']
+ )
+
+ paginate_description = (
+ 'Creates an iterator that will paginate through responses '
+ 'from :py:meth:`{}.Client.{}`.'.format(
+ get_service_module_name(service_model), xform_name(paginator_name)
+ )
+ )
+
+ document_model_driven_method(
+ section,
+ 'paginate',
+ operation_model,
+ event_emitter=event_emitter,
+ method_description=paginate_description,
+ example_prefix='response_iterator = paginator.paginate',
+ include_input=botocore_pagination_params,
+ include_output=botocore_pagination_response_params,
+ exclude_input=service_pagination_params,
+ exclude_output=service_pagination_response_params,
+ include_signature=include_signature,
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/params.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/params.py
new file mode 100644
index 0000000000..cddaf12fc3
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/params.py
@@ -0,0 +1,303 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.shape import ShapeDocumenter
+from botocore.docs.utils import py_type_name
+
+
+class BaseParamsDocumenter(ShapeDocumenter):
+ def document_params(self, section, shape, include=None, exclude=None):
+ """Fills out the documentation for a section given a model shape.
+
+ :param section: The section to write the documentation to.
+
+ :param shape: The shape of the operation.
+
+ :type include: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include: The parameter shapes to include in the documentation.
+
+ :type exclude: List of the names of the parameters to exclude.
+ :param exclude: The names of the parameters to exclude from
+ documentation.
+ """
+ history = []
+ self.traverse_and_document_shape(
+ section=section,
+ shape=shape,
+ history=history,
+ name=None,
+ include=include,
+ exclude=exclude,
+ )
+
+ def document_recursive_shape(self, section, shape, **kwargs):
+ self._add_member_documentation(section, shape, **kwargs)
+
+ def document_shape_default(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ self._add_member_documentation(section, shape, **kwargs)
+
+ def document_shape_type_list(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ self._add_member_documentation(section, shape, **kwargs)
+ param_shape = shape.member
+ param_section = section.add_new_section(
+ param_shape.name, context={'shape': shape.member.name}
+ )
+ self._start_nested_param(param_section)
+ self.traverse_and_document_shape(
+ section=param_section,
+ shape=param_shape,
+ history=history,
+ name=None,
+ )
+ section = section.add_new_section('end-list')
+ self._end_nested_param(section)
+
+ def document_shape_type_map(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ self._add_member_documentation(section, shape, **kwargs)
+
+ key_section = section.add_new_section(
+ 'key', context={'shape': shape.key.name}
+ )
+ self._start_nested_param(key_section)
+ self._add_member_documentation(key_section, shape.key)
+
+ param_section = section.add_new_section(
+ shape.value.name, context={'shape': shape.value.name}
+ )
+ param_section.style.indent()
+ self._start_nested_param(param_section)
+ self.traverse_and_document_shape(
+ section=param_section,
+ shape=shape.value,
+ history=history,
+ name=None,
+ )
+
+ end_section = section.add_new_section('end-map')
+ self._end_nested_param(end_section)
+ self._end_nested_param(end_section)
+
+ def document_shape_type_structure(
+ self,
+ section,
+ shape,
+ history,
+ include=None,
+ exclude=None,
+ name=None,
+ **kwargs,
+ ):
+ members = self._add_members_to_shape(shape.members, include)
+ self._add_member_documentation(section, shape, name=name)
+ for param in members:
+ if exclude and param in exclude:
+ continue
+ param_shape = members[param]
+ param_section = section.add_new_section(
+ param, context={'shape': param_shape.name}
+ )
+ self._start_nested_param(param_section)
+ self.traverse_and_document_shape(
+ section=param_section,
+ shape=param_shape,
+ history=history,
+ name=param,
+ )
+ section = section.add_new_section('end-structure')
+ self._end_nested_param(section)
+
+ def _add_member_documentation(self, section, shape, **kwargs):
+ pass
+
+ def _add_members_to_shape(self, members, include):
+ if include:
+ members = members.copy()
+ for param in include:
+ members[param.name] = param
+ return members
+
+ def _document_non_top_level_param_type(self, type_section, shape):
+ special_py_type = self._get_special_py_type_name(shape)
+ py_type = py_type_name(shape.type_name)
+
+ type_format = '(%s) --'
+ if special_py_type is not None:
+ # Special type can reference a linked class.
+ # Italicizing it blows away the link.
+ type_section.write(type_format % special_py_type)
+ else:
+ type_section.style.italics(type_format % py_type)
+ type_section.write(' ')
+
+ def _start_nested_param(self, section):
+ section.style.indent()
+ section.style.new_line()
+
+ def _end_nested_param(self, section):
+ section.style.dedent()
+ section.style.new_line()
+
+
+class ResponseParamsDocumenter(BaseParamsDocumenter):
+ """Generates the description for the response parameters"""
+
+ EVENT_NAME = 'response-params'
+
+ def _add_member_documentation(self, section, shape, name=None, **kwargs):
+ name_section = section.add_new_section('param-name')
+ name_section.write('- ')
+ if name is not None:
+ name_section.style.bold('%s' % name)
+ name_section.write(' ')
+ type_section = section.add_new_section('param-type')
+ self._document_non_top_level_param_type(type_section, shape)
+
+ documentation_section = section.add_new_section('param-documentation')
+ if shape.documentation:
+ documentation_section.style.indent()
+ if getattr(shape, 'is_tagged_union', False):
+ tagged_union_docs = section.add_new_section(
+ 'param-tagged-union-docs'
+ )
+ note = (
+ '.. note::'
+ ' This is a Tagged Union structure. Only one of the '
+ ' following top level keys will be set: %s. '
+ ' If a client receives an unknown member it will '
+ ' set ``SDK_UNKNOWN_MEMBER`` as the top level key, '
+ ' which maps to the name or tag of the unknown '
+ ' member. The structure of ``SDK_UNKNOWN_MEMBER`` is '
+ ' as follows'
+ )
+ tagged_union_members_str = ', '.join(
+ ['``%s``' % key for key in shape.members.keys()]
+ )
+ unknown_code_example = (
+ '\'SDK_UNKNOWN_MEMBER\': '
+ '{\'name\': \'UnknownMemberName\'}'
+ )
+ tagged_union_docs.write(note % (tagged_union_members_str))
+ example = section.add_new_section('param-unknown-example')
+ example.style.codeblock(unknown_code_example)
+ documentation_section.include_doc_string(shape.documentation)
+ section.style.new_paragraph()
+
+ def document_shape_type_event_stream(
+ self, section, shape, history, **kwargs
+ ):
+ self.document_shape_type_structure(section, shape, history, **kwargs)
+
+
+class RequestParamsDocumenter(BaseParamsDocumenter):
+ """Generates the description for the request parameters"""
+
+ EVENT_NAME = 'request-params'
+
+ def document_shape_type_structure(
+ self, section, shape, history, include=None, exclude=None, **kwargs
+ ):
+ if len(history) > 1:
+ self._add_member_documentation(section, shape, **kwargs)
+ section.style.indent()
+ members = self._add_members_to_shape(shape.members, include)
+ for i, param in enumerate(members):
+ if exclude and param in exclude:
+ continue
+ param_shape = members[param]
+ param_section = section.add_new_section(
+ param, context={'shape': param_shape.name}
+ )
+ param_section.style.new_line()
+ is_required = param in shape.required_members
+ self.traverse_and_document_shape(
+ section=param_section,
+ shape=param_shape,
+ history=history,
+ name=param,
+ is_required=is_required,
+ )
+ section = section.add_new_section('end-structure')
+ if len(history) > 1:
+ section.style.dedent()
+ section.style.new_line()
+
+ def _add_member_documentation(
+ self,
+ section,
+ shape,
+ name=None,
+ is_top_level_param=False,
+ is_required=False,
+ **kwargs,
+ ):
+ py_type = self._get_special_py_type_name(shape)
+ if py_type is None:
+ py_type = py_type_name(shape.type_name)
+ if is_top_level_param:
+ type_section = section.add_new_section('param-type')
+ type_section.write(f':type {name}: {py_type}')
+ end_type_section = type_section.add_new_section('end-param-type')
+ end_type_section.style.new_line()
+ name_section = section.add_new_section('param-name')
+ name_section.write(':param %s: ' % name)
+
+ else:
+ name_section = section.add_new_section('param-name')
+ name_section.write('- ')
+ if name is not None:
+ name_section.style.bold('%s' % name)
+ name_section.write(' ')
+ type_section = section.add_new_section('param-type')
+ self._document_non_top_level_param_type(type_section, shape)
+
+ if is_required:
+ is_required_section = section.add_new_section('is-required')
+ is_required_section.style.indent()
+ is_required_section.style.bold('[REQUIRED]')
+ is_required_section.write(' ')
+ if shape.documentation:
+ documentation_section = section.add_new_section(
+ 'param-documentation'
+ )
+ documentation_section.style.indent()
+ if getattr(shape, 'is_tagged_union', False):
+ tagged_union_docs = section.add_new_section(
+ 'param-tagged-union-docs'
+ )
+ note = (
+ '.. note::'
+ ' This is a Tagged Union structure. Only one of the '
+ ' following top level keys can be set: %s. '
+ )
+ tagged_union_members_str = ', '.join(
+ ['``%s``' % key for key in shape.members.keys()]
+ )
+ tagged_union_docs.write(note % (tagged_union_members_str))
+ documentation_section.include_doc_string(shape.documentation)
+ self._add_special_trait_documentation(documentation_section, shape)
+ end_param_section = section.add_new_section('end-param')
+ end_param_section.style.new_paragraph()
+
+ def _add_special_trait_documentation(self, section, shape):
+ if 'idempotencyToken' in shape.metadata:
+ self._append_idempotency_documentation(section)
+
+ def _append_idempotency_documentation(self, section):
+ docstring = 'This field is autopopulated if not provided.'
+ section.write(docstring)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/service.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/service.py
new file mode 100644
index 0000000000..d20a889dc9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/service.py
@@ -0,0 +1,133 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.client import (
+ ClientContextParamsDocumenter,
+ ClientDocumenter,
+ ClientExceptionsDocumenter,
+)
+from botocore.docs.paginator import PaginatorDocumenter
+from botocore.docs.waiter import WaiterDocumenter
+from botocore.exceptions import DataNotFoundError
+
+
+class ServiceDocumenter:
+ def __init__(self, service_name, session, root_docs_path):
+ self._session = session
+ self._service_name = service_name
+ self._root_docs_path = root_docs_path
+
+ self._client = self._session.create_client(
+ service_name,
+ region_name='us-east-1',
+ aws_access_key_id='foo',
+ aws_secret_access_key='bar',
+ )
+ self._event_emitter = self._client.meta.events
+
+ self.sections = [
+ 'title',
+ 'client-api',
+ 'client-exceptions',
+ 'paginator-api',
+ 'waiter-api',
+ 'client-context-params',
+ ]
+
+ def document_service(self):
+ """Documents an entire service.
+
+ :returns: The reStructured text of the documented service.
+ """
+ doc_structure = DocumentStructure(
+ self._service_name, section_names=self.sections, target='html'
+ )
+ self.title(doc_structure.get_section('title'))
+ self.client_api(doc_structure.get_section('client-api'))
+ self.client_exceptions(doc_structure.get_section('client-exceptions'))
+ self.paginator_api(doc_structure.get_section('paginator-api'))
+ self.waiter_api(doc_structure.get_section('waiter-api'))
+ context_params_section = doc_structure.get_section(
+ 'client-context-params'
+ )
+ self.client_context_params(context_params_section)
+ return doc_structure.flush_structure()
+
+ def title(self, section):
+ section.style.h1(self._client.__class__.__name__)
+ self._event_emitter.emit(
+ f"docs.title.{self._service_name}", section=section
+ )
+
+ def table_of_contents(self, section):
+ section.style.table_of_contents(title='Table of Contents', depth=2)
+
+ def client_api(self, section):
+ examples = None
+ try:
+ examples = self.get_examples(self._service_name)
+ except DataNotFoundError:
+ pass
+
+ ClientDocumenter(
+ self._client, self._root_docs_path, examples
+ ).document_client(section)
+
+ def client_exceptions(self, section):
+ ClientExceptionsDocumenter(
+ self._client, self._root_docs_path
+ ).document_exceptions(section)
+
+ def paginator_api(self, section):
+ try:
+ service_paginator_model = self._session.get_paginator_model(
+ self._service_name
+ )
+ except DataNotFoundError:
+ return
+ if service_paginator_model._paginator_config:
+ paginator_documenter = PaginatorDocumenter(
+ self._client, service_paginator_model, self._root_docs_path
+ )
+ paginator_documenter.document_paginators(section)
+
+ def waiter_api(self, section):
+ if self._client.waiter_names:
+ service_waiter_model = self._session.get_waiter_model(
+ self._service_name
+ )
+ waiter_documenter = WaiterDocumenter(
+ self._client, service_waiter_model, self._root_docs_path
+ )
+ waiter_documenter.document_waiters(section)
+
+ def get_examples(self, service_name, api_version=None):
+ loader = self._session.get_component('data_loader')
+ examples = loader.load_service_model(
+ service_name, 'examples-1', api_version
+ )
+ return examples['examples']
+
+ def client_context_params(self, section):
+ omitted_params = ClientContextParamsDocumenter.OMITTED_CONTEXT_PARAMS
+ params_to_omit = omitted_params.get(self._service_name, [])
+ service_model = self._client.meta.service_model
+ raw_context_params = service_model.client_context_parameters
+ context_params = [
+ p for p in raw_context_params if p.name not in params_to_omit
+ ]
+ if context_params:
+ context_param_documenter = ClientContextParamsDocumenter(
+ self._service_name, context_params
+ )
+ context_param_documenter.document_context_params(section)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/shape.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/shape.py
new file mode 100644
index 0000000000..640a5d18ef
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/shape.py
@@ -0,0 +1,135 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+
+# NOTE: This class should not be instantiated and its
+# ``traverse_and_document_shape`` method called directly. It should be
+# inherited from a Documenter class with the appropriate methods
+# and attributes.
+from botocore.utils import is_json_value_header
+
+
+class ShapeDocumenter:
+ EVENT_NAME = ''
+
+ def __init__(
+ self, service_name, operation_name, event_emitter, context=None
+ ):
+ self._service_name = service_name
+ self._operation_name = operation_name
+ self._event_emitter = event_emitter
+ self._context = context
+ if context is None:
+ self._context = {'special_shape_types': {}}
+
+ def traverse_and_document_shape(
+ self,
+ section,
+ shape,
+ history,
+ include=None,
+ exclude=None,
+ name=None,
+ is_required=False,
+ ):
+ """Traverses and documents a shape
+
+ Will take a self class and call its appropriate methods as a shape
+ is traversed.
+
+ :param section: The section to document.
+
+ :param history: A list of the names of the shapes that have been
+ traversed.
+
+ :type include: Dictionary where keys are parameter names and
+ values are the shapes of the parameter names.
+ :param include: The parameter shapes to include in the documentation.
+
+ :type exclude: List of the names of the parameters to exclude.
+ :param exclude: The names of the parameters to exclude from
+ documentation.
+
+ :param name: The name of the shape.
+
+ :param is_required: If the shape is a required member.
+ """
+ param_type = shape.type_name
+ if getattr(shape, 'serialization', {}).get('eventstream'):
+ param_type = 'event_stream'
+ if shape.name in history:
+ self.document_recursive_shape(section, shape, name=name)
+ else:
+ history.append(shape.name)
+ is_top_level_param = len(history) == 2
+ if hasattr(shape, 'is_document_type') and shape.is_document_type:
+ param_type = 'document'
+ getattr(
+ self,
+ f"document_shape_type_{param_type}",
+ self.document_shape_default,
+ )(
+ section,
+ shape,
+ history=history,
+ name=name,
+ include=include,
+ exclude=exclude,
+ is_top_level_param=is_top_level_param,
+ is_required=is_required,
+ )
+ if is_top_level_param:
+ self._event_emitter.emit(
+ f"docs.{self.EVENT_NAME}.{self._service_name}.{self._operation_name}.{name}",
+ section=section,
+ )
+ at_overlying_method_section = len(history) == 1
+ if at_overlying_method_section:
+ self._event_emitter.emit(
+ f"docs.{self.EVENT_NAME}.{self._service_name}.{self._operation_name}.complete-section",
+ section=section,
+ )
+ history.pop()
+
+ def _get_special_py_default(self, shape):
+ special_defaults = {
+ 'document_type': '{...}|[...]|123|123.4|\'string\'|True|None',
+ 'jsonvalue_header': '{...}|[...]|123|123.4|\'string\'|True|None',
+ 'streaming_input_shape': 'b\'bytes\'|file',
+ 'streaming_output_shape': 'StreamingBody()',
+ 'eventstream_output_shape': 'EventStream()',
+ }
+ return self._get_value_for_special_type(shape, special_defaults)
+
+ def _get_special_py_type_name(self, shape):
+ special_type_names = {
+ 'document_type': ':ref:`document`',
+ 'jsonvalue_header': 'JSON serializable',
+ 'streaming_input_shape': 'bytes or seekable file-like object',
+ 'streaming_output_shape': ':class:`.StreamingBody`',
+ 'eventstream_output_shape': ':class:`.EventStream`',
+ }
+ return self._get_value_for_special_type(shape, special_type_names)
+
+ def _get_value_for_special_type(self, shape, special_type_map):
+ if is_json_value_header(shape):
+ return special_type_map['jsonvalue_header']
+ if hasattr(shape, 'is_document_type') and shape.is_document_type:
+ return special_type_map['document_type']
+ for special_type, marked_shape in self._context[
+ 'special_shape_types'
+ ].items():
+ if special_type in special_type_map:
+ if shape == marked_shape:
+ return special_type_map[special_type]
+ return None
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/sharedexample.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/sharedexample.py
new file mode 100644
index 0000000000..58cdfa594c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/sharedexample.py
@@ -0,0 +1,227 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import numbers
+import re
+
+from botocore.docs.utils import escape_controls
+from botocore.utils import parse_timestamp
+
+
+class SharedExampleDocumenter:
+ def document_shared_example(
+ self, example, prefix, section, operation_model
+ ):
+ """Documents a single shared example based on its definition.
+
+ :param example: The model of the example
+
+ :param prefix: The prefix to use in the method example.
+
+ :param section: The section to write to.
+
+ :param operation_model: The model of the operation used in the example
+ """
+ section.style.new_paragraph()
+ section.write(example.get('description'))
+ section.style.new_line()
+ self.document_input(
+ section, example, prefix, operation_model.input_shape
+ )
+ self.document_output(section, example, operation_model.output_shape)
+
+ def document_input(self, section, example, prefix, shape):
+ input_section = section.add_new_section('input')
+ input_section.style.start_codeblock()
+ if prefix is not None:
+ input_section.write(prefix)
+ params = example.get('input', {})
+ comments = example.get('comments')
+ if comments:
+ comments = comments.get('input')
+ param_section = input_section.add_new_section('parameters')
+ self._document_params(param_section, params, comments, [], shape)
+ closing_section = input_section.add_new_section('input-close')
+ closing_section.style.new_line()
+ closing_section.style.new_line()
+ closing_section.write('print(response)')
+ closing_section.style.end_codeblock()
+
+ def document_output(self, section, example, shape):
+ output_section = section.add_new_section('output')
+ output_section.style.new_line()
+ output_section.write('Expected Output:')
+ output_section.style.new_line()
+ output_section.style.start_codeblock()
+ params = example.get('output', {})
+
+ # There might not be an output, but we will return metadata anyway
+ params['ResponseMetadata'] = {"...": "..."}
+ comments = example.get('comments')
+ if comments:
+ comments = comments.get('output')
+ self._document_dict(output_section, params, comments, [], shape, True)
+ closing_section = output_section.add_new_section('output-close')
+ closing_section.style.end_codeblock()
+
+ def _document(self, section, value, comments, path, shape):
+ """
+ :param section: The section to add the docs to.
+
+ :param value: The input / output values representing the parameters that
+ are included in the example.
+
+ :param comments: The dictionary containing all the comments to be
+ applied to the example.
+
+ :param path: A list describing where the documenter is in traversing the
+ parameters. This is used to find the equivalent location
+ in the comments dictionary.
+ """
+ if isinstance(value, dict):
+ self._document_dict(section, value, comments, path, shape)
+ elif isinstance(value, list):
+ self._document_list(section, value, comments, path, shape)
+ elif isinstance(value, numbers.Number):
+ self._document_number(section, value, path)
+ elif shape and shape.type_name == 'timestamp':
+ self._document_datetime(section, value, path)
+ else:
+ self._document_str(section, value, path)
+
+ def _document_dict(
+ self, section, value, comments, path, shape, top_level=False
+ ):
+ dict_section = section.add_new_section('dict-value')
+ self._start_nested_value(dict_section, '{')
+ for key, val in value.items():
+ path.append('.%s' % key)
+ item_section = dict_section.add_new_section(key)
+ item_section.style.new_line()
+ item_comment = self._get_comment(path, comments)
+ if item_comment:
+ item_section.write(item_comment)
+ item_section.style.new_line()
+ item_section.write("'%s': " % key)
+
+ # Shape could be none if there is no output besides ResponseMetadata
+ item_shape = None
+ if shape:
+ if shape.type_name == 'structure':
+ item_shape = shape.members.get(key)
+ elif shape.type_name == 'map':
+ item_shape = shape.value
+ self._document(item_section, val, comments, path, item_shape)
+ path.pop()
+ dict_section_end = dict_section.add_new_section('ending-brace')
+ self._end_nested_value(dict_section_end, '}')
+ if not top_level:
+ dict_section_end.write(',')
+
+ def _document_params(self, section, value, comments, path, shape):
+ param_section = section.add_new_section('param-values')
+ self._start_nested_value(param_section, '(')
+ for key, val in value.items():
+ path.append('.%s' % key)
+ item_section = param_section.add_new_section(key)
+ item_section.style.new_line()
+ item_comment = self._get_comment(path, comments)
+ if item_comment:
+ item_section.write(item_comment)
+ item_section.style.new_line()
+ item_section.write(key + '=')
+
+ # Shape could be none if there are no input parameters
+ item_shape = None
+ if shape:
+ item_shape = shape.members.get(key)
+ self._document(item_section, val, comments, path, item_shape)
+ path.pop()
+ param_section_end = param_section.add_new_section('ending-parenthesis')
+ self._end_nested_value(param_section_end, ')')
+
+ def _document_list(self, section, value, comments, path, shape):
+ list_section = section.add_new_section('list-section')
+ self._start_nested_value(list_section, '[')
+ item_shape = shape.member
+ for index, val in enumerate(value):
+ item_section = list_section.add_new_section(index)
+ item_section.style.new_line()
+ path.append('[%s]' % index)
+ item_comment = self._get_comment(path, comments)
+ if item_comment:
+ item_section.write(item_comment)
+ item_section.style.new_line()
+ self._document(item_section, val, comments, path, item_shape)
+ path.pop()
+ list_section_end = list_section.add_new_section('ending-bracket')
+ self._end_nested_value(list_section_end, '],')
+
+ def _document_str(self, section, value, path):
+ # We do the string conversion because this might accept a type that
+ # we don't specifically address.
+ safe_value = escape_controls(value)
+ section.write(f"'{safe_value}',")
+
+ def _document_number(self, section, value, path):
+ section.write("%s," % str(value))
+
+ def _document_datetime(self, section, value, path):
+ datetime_tuple = parse_timestamp(value).timetuple()
+ datetime_str = str(datetime_tuple[0])
+ for i in range(1, len(datetime_tuple)):
+ datetime_str += ", " + str(datetime_tuple[i])
+ section.write("datetime(%s)," % datetime_str)
+
+ def _get_comment(self, path, comments):
+ key = re.sub(r'^\.', '', ''.join(path))
+ if comments and key in comments:
+ return '# ' + comments[key]
+ else:
+ return ''
+
+ def _start_nested_value(self, section, start):
+ section.write(start)
+ section.style.indent()
+ section.style.indent()
+
+ def _end_nested_value(self, section, end):
+ section.style.dedent()
+ section.style.dedent()
+ section.style.new_line()
+ section.write(end)
+
+
+def document_shared_examples(
+ section, operation_model, example_prefix, shared_examples
+):
+ """Documents the shared examples
+
+ :param section: The section to write to.
+
+ :param operation_model: The model of the operation.
+
+ :param example_prefix: The prefix to use in the method example.
+
+ :param shared_examples: The shared JSON examples from the model.
+ """
+ container_section = section.add_new_section('shared-examples')
+ container_section.style.new_paragraph()
+ container_section.style.bold('Examples')
+ documenter = SharedExampleDocumenter()
+ for example in shared_examples:
+ documenter.document_shared_example(
+ example=example,
+ section=container_section.add_new_section(example['id']),
+ prefix=example_prefix,
+ operation_model=operation_model,
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/translator.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/translator.py
new file mode 100644
index 0000000000..0b0a308930
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/translator.py
@@ -0,0 +1,62 @@
+# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from docutils import nodes
+from sphinx.locale import admonitionlabels
+from sphinx.writers.html5 import HTML5Translator as SphinxHTML5Translator
+
+
+class BotoHTML5Translator(SphinxHTML5Translator):
+ """Extension of Sphinx's ``HTML5Translator`` for Botocore documentation."""
+
+ IGNORE_IMPLICIT_HEADINGS = [
+ '[REQUIRED]',
+ ]
+
+ def visit_admonition(self, node, name=""):
+ """Uses the h3 tag for admonition titles instead of the p tag."""
+ self.body.append(
+ self.starttag(node, "div", CLASS=("admonition " + name))
+ )
+ if name:
+ title = (
+ f" {admonitionlabels[name]}
"
+ )
+ self.body.append(title)
+
+ def is_implicit_heading(self, node):
+ """Determines if a node is an implicit heading.
+
+ An implicit heading is represented by a paragraph node whose only
+ child is a strong node with text that isnt in `IGNORE_IMPLICIT_HEADINGS`.
+ """
+ return (
+ len(node) == 1
+ and isinstance(node[0], nodes.strong)
+ and len(node[0]) == 1
+ and isinstance(node[0][0], nodes.Text)
+ and node[0][0].astext() not in self.IGNORE_IMPLICIT_HEADINGS
+ )
+
+ def visit_paragraph(self, node):
+ """Visit a paragraph HTML element.
+
+ Replaces implicit headings with an h3 tag and defers to default
+ behavior for normal paragraph elements.
+ """
+ if self.is_implicit_heading(node):
+ text = node[0][0]
+ self.body.append(f'{text}
\n')
+ # Do not visit the current nodes children or call its depart method.
+ raise nodes.SkipNode
+ else:
+ super().visit_paragraph(node)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/utils.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/utils.py
new file mode 100644
index 0000000000..eb6cae145c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/utils.py
@@ -0,0 +1,222 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import re
+from collections import namedtuple
+
+
+def py_type_name(type_name):
+ """Get the Python type name for a given model type.
+
+ >>> py_type_name('list')
+ 'list'
+ >>> py_type_name('structure')
+ 'dict'
+
+ :rtype: string
+ """
+ return {
+ 'blob': 'bytes',
+ 'character': 'string',
+ 'double': 'float',
+ 'long': 'integer',
+ 'map': 'dict',
+ 'structure': 'dict',
+ 'timestamp': 'datetime',
+ }.get(type_name, type_name)
+
+
+def py_default(type_name):
+ """Get the Python default value for a given model type.
+
+ >>> py_default('string')
+ '\'string\''
+ >>> py_default('list')
+ '[...]'
+ >>> py_default('unknown')
+ '...'
+
+ :rtype: string
+ """
+ return {
+ 'double': '123.0',
+ 'long': '123',
+ 'integer': '123',
+ 'string': "'string'",
+ 'blob': "b'bytes'",
+ 'boolean': 'True|False',
+ 'list': '[...]',
+ 'map': '{...}',
+ 'structure': '{...}',
+ 'timestamp': 'datetime(2015, 1, 1)',
+ }.get(type_name, '...')
+
+
+def get_official_service_name(service_model):
+ """Generate the official name of an AWS Service
+
+ :param service_model: The service model representing the service
+ """
+ official_name = service_model.metadata.get('serviceFullName')
+ short_name = service_model.metadata.get('serviceAbbreviation', '')
+ if short_name.startswith('Amazon'):
+ short_name = short_name[7:]
+ if short_name.startswith('AWS'):
+ short_name = short_name[4:]
+ if short_name and short_name.lower() not in official_name.lower():
+ official_name += f' ({short_name})'
+ return official_name
+
+
+_DocumentedShape = namedtuple(
+ 'DocumentedShape',
+ [
+ 'name',
+ 'type_name',
+ 'documentation',
+ 'metadata',
+ 'members',
+ 'required_members',
+ ],
+)
+
+
+class DocumentedShape(_DocumentedShape):
+ """Use this class to inject new shapes into a model for documentation"""
+
+ def __new__(
+ cls,
+ name,
+ type_name,
+ documentation,
+ metadata=None,
+ members=None,
+ required_members=None,
+ ):
+ if metadata is None:
+ metadata = []
+ if members is None:
+ members = []
+ if required_members is None:
+ required_members = []
+ return super().__new__(
+ cls,
+ name,
+ type_name,
+ documentation,
+ metadata,
+ members,
+ required_members,
+ )
+
+
+class AutoPopulatedParam:
+ def __init__(self, name, param_description=None):
+ self.name = name
+ self.param_description = param_description
+ if param_description is None:
+ self.param_description = (
+ 'Please note that this parameter is automatically populated '
+ 'if it is not provided. Including this parameter is not '
+ 'required\n'
+ )
+
+ def document_auto_populated_param(self, event_name, section, **kwargs):
+ """Documents auto populated parameters
+
+ It will remove any required marks for the parameter, remove the
+ parameter from the example, and add a snippet about the parameter
+ being autopopulated in the description.
+ """
+ if event_name.startswith('docs.request-params'):
+ if self.name in section.available_sections:
+ section = section.get_section(self.name)
+ if 'is-required' in section.available_sections:
+ section.delete_section('is-required')
+ description_section = section.get_section(
+ 'param-documentation'
+ )
+ description_section.writeln(self.param_description)
+ elif event_name.startswith('docs.request-example'):
+ section = section.get_section('structure-value')
+ if self.name in section.available_sections:
+ section.delete_section(self.name)
+
+
+class HideParamFromOperations:
+ """Hides a single parameter from multiple operations.
+
+ This method will remove a parameter from documentation and from
+ examples. This method is typically used for things that are
+ automatically populated because a user would be unable to provide
+ a value (e.g., a checksum of a serialized XML request body)."""
+
+ def __init__(self, service_name, parameter_name, operation_names):
+ """
+ :type service_name: str
+ :param service_name: Name of the service to modify.
+
+ :type parameter_name: str
+ :param parameter_name: Name of the parameter to modify.
+
+ :type operation_names: list
+ :param operation_names: Operation names to modify.
+ """
+ self._parameter_name = parameter_name
+ self._params_events = set()
+ self._example_events = set()
+ # Build up the sets of relevant event names.
+ param_template = 'docs.request-params.%s.%s.complete-section'
+ example_template = 'docs.request-example.%s.%s.complete-section'
+ for name in operation_names:
+ self._params_events.add(param_template % (service_name, name))
+ self._example_events.add(example_template % (service_name, name))
+
+ def hide_param(self, event_name, section, **kwargs):
+ if event_name in self._example_events:
+ # Modify the structure value for example events.
+ section = section.get_section('structure-value')
+ elif event_name not in self._params_events:
+ return
+ if self._parameter_name in section.available_sections:
+ section.delete_section(self._parameter_name)
+
+
+class AppendParamDocumentation:
+ """Appends documentation to a specific parameter"""
+
+ def __init__(self, parameter_name, doc_string):
+ self._parameter_name = parameter_name
+ self._doc_string = doc_string
+
+ def append_documentation(self, event_name, section, **kwargs):
+ if self._parameter_name in section.available_sections:
+ section = section.get_section(self._parameter_name)
+ description_section = section.get_section('param-documentation')
+ description_section.writeln(self._doc_string)
+
+
+_CONTROLS = {
+ '\n': '\\n',
+ '\r': '\\r',
+ '\t': '\\t',
+ '\b': '\\b',
+ '\f': '\\f',
+}
+# Combines all CONTROLS keys into a big or regular expression
+_ESCAPE_CONTROLS_RE = re.compile('|'.join(map(re.escape, _CONTROLS)))
+# Based on the match get the appropriate replacement from CONTROLS
+_CONTROLS_MATCH_HANDLER = lambda match: _CONTROLS[match.group(0)]
+
+
+def escape_controls(value):
+ return _ESCAPE_CONTROLS_RE.sub(_CONTROLS_MATCH_HANDLER, value)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/waiter.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/waiter.py
new file mode 100644
index 0000000000..c5226d460e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/docs/waiter.py
@@ -0,0 +1,184 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.compat import OrderedDict
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.method import document_model_driven_method
+from botocore.docs.utils import DocumentedShape
+from botocore.utils import get_service_module_name
+
+
+class WaiterDocumenter:
+ def __init__(self, client, service_waiter_model, root_docs_path):
+ self._client = client
+ self._client_class_name = self._client.__class__.__name__
+ self._service_name = self._client.meta.service_model.service_name
+ self._service_waiter_model = service_waiter_model
+ self._root_docs_path = root_docs_path
+ self._USER_GUIDE_LINK = (
+ 'https://boto3.amazonaws.com/'
+ 'v1/documentation/api/latest/guide/clients.html#waiters'
+ )
+
+ def document_waiters(self, section):
+ """Documents the various waiters for a service.
+
+ :param section: The section to write to.
+ """
+ section.style.h2('Waiters')
+ self._add_overview(section)
+ section.style.new_line()
+ section.writeln('The available waiters are:')
+ section.style.toctree()
+ for waiter_name in self._service_waiter_model.waiter_names:
+ section.style.tocitem(f'{self._service_name}/waiter/{waiter_name}')
+ # Create a new DocumentStructure for each waiter and add contents.
+ waiter_doc_structure = DocumentStructure(
+ waiter_name, target='html'
+ )
+ self._add_single_waiter(waiter_doc_structure, waiter_name)
+ # Write waiters in individual/nested files.
+ # Path: /reference/services//waiter/.rst
+ waiter_dir_path = os.path.join(
+ self._root_docs_path, self._service_name, 'waiter'
+ )
+ waiter_doc_structure.write_to_file(waiter_dir_path, waiter_name)
+
+ def _add_single_waiter(self, section, waiter_name):
+ breadcrumb_section = section.add_new_section('breadcrumb')
+ breadcrumb_section.style.ref(
+ self._client_class_name, f'../../{self._service_name}'
+ )
+ breadcrumb_section.write(f' / Waiter / {waiter_name}')
+ section.add_title_section(waiter_name)
+ waiter_section = section.add_new_section(waiter_name)
+ waiter_section.style.start_sphinx_py_class(
+ class_name=f"{self._client_class_name}.Waiter.{waiter_name}"
+ )
+
+ # Add example on how to instantiate waiter.
+ waiter_section.style.start_codeblock()
+ waiter_section.style.new_line()
+ waiter_section.write(
+ 'waiter = client.get_waiter(\'%s\')' % xform_name(waiter_name)
+ )
+ waiter_section.style.end_codeblock()
+
+ # Add information on the wait() method
+ waiter_section.style.new_line()
+ document_wait_method(
+ section=waiter_section,
+ waiter_name=waiter_name,
+ event_emitter=self._client.meta.events,
+ service_model=self._client.meta.service_model,
+ service_waiter_model=self._service_waiter_model,
+ )
+
+ def _add_overview(self, section):
+ section.style.new_line()
+ section.write(
+ 'Waiters are available on a client instance '
+ 'via the ``get_waiter`` method. For more detailed instructions '
+ 'and examples on the usage or waiters, see the '
+ 'waiters '
+ )
+ section.style.external_link(
+ title='user guide',
+ link=self._USER_GUIDE_LINK,
+ )
+ section.write('.')
+ section.style.new_line()
+
+
+def document_wait_method(
+ section,
+ waiter_name,
+ event_emitter,
+ service_model,
+ service_waiter_model,
+ include_signature=True,
+):
+ """Documents a the wait method of a waiter
+
+ :param section: The section to write to
+
+ :param waiter_name: The name of the waiter
+
+ :param event_emitter: The event emitter to use to emit events
+
+ :param service_model: The service model
+
+ :param service_waiter_model: The waiter model associated to the service
+
+ :param include_signature: Whether or not to include the signature.
+ It is useful for generating docstrings.
+ """
+ waiter_model = service_waiter_model.get_waiter(waiter_name)
+ operation_model = service_model.operation_model(waiter_model.operation)
+
+ waiter_config_members = OrderedDict()
+
+ waiter_config_members['Delay'] = DocumentedShape(
+ name='Delay',
+ type_name='integer',
+ documentation=(
+ 'The amount of time in seconds to wait between '
+ 'attempts. Default: {}
'.format(waiter_model.delay)
+ ),
+ )
+
+ waiter_config_members['MaxAttempts'] = DocumentedShape(
+ name='MaxAttempts',
+ type_name='integer',
+ documentation=(
+ 'The maximum number of attempts to be made. '
+ 'Default: {}
'.format(waiter_model.max_attempts)
+ ),
+ )
+
+ botocore_waiter_params = [
+ DocumentedShape(
+ name='WaiterConfig',
+ type_name='structure',
+ documentation=(
+ 'A dictionary that provides parameters to control '
+ 'waiting behavior.
'
+ ),
+ members=waiter_config_members,
+ )
+ ]
+
+ wait_description = (
+ 'Polls :py:meth:`{}.Client.{}` every {} '
+ 'seconds until a successful state is reached. An error is '
+ 'returned after {} failed checks.'.format(
+ get_service_module_name(service_model),
+ xform_name(waiter_model.operation),
+ waiter_model.delay,
+ waiter_model.max_attempts,
+ )
+ )
+
+ document_model_driven_method(
+ section,
+ 'wait',
+ operation_model,
+ event_emitter=event_emitter,
+ method_description=wait_description,
+ example_prefix='waiter.wait',
+ include_input=botocore_waiter_params,
+ document_output=False,
+ include_signature=include_signature,
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/endpoint.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/endpoint.py
new file mode 100644
index 0000000000..adc622c25a
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/endpoint.py
@@ -0,0 +1,443 @@
+# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+import datetime
+import logging
+import os
+import threading
+import time
+import uuid
+
+from botocore import parsers
+from botocore.awsrequest import create_request_object
+from botocore.exceptions import HTTPClientError
+from botocore.history import get_global_history_recorder
+from botocore.hooks import first_non_none_response
+from botocore.httpchecksum import handle_checksum_body
+from botocore.httpsession import URLLib3Session
+from botocore.response import StreamingBody
+from botocore.utils import (
+ get_environ_proxies,
+ is_valid_endpoint_url,
+ is_valid_ipv6_endpoint_url,
+)
+
+logger = logging.getLogger(__name__)
+history_recorder = get_global_history_recorder()
+DEFAULT_TIMEOUT = 60
+MAX_POOL_CONNECTIONS = 10
+
+
+def convert_to_response_dict(http_response, operation_model):
+ """Convert an HTTP response object to a request dict.
+
+ This converts the requests library's HTTP response object to
+ a dictionary.
+
+ :type http_response: botocore.vendored.requests.model.Response
+ :param http_response: The HTTP response from an AWS service request.
+
+ :rtype: dict
+ :return: A response dictionary which will contain the following keys:
+ * headers (dict)
+ * status_code (int)
+ * body (string or file-like object)
+
+ """
+ response_dict = {
+ 'headers': http_response.headers,
+ 'status_code': http_response.status_code,
+ 'context': {
+ 'operation_name': operation_model.name,
+ },
+ }
+ if response_dict['status_code'] >= 300:
+ response_dict['body'] = http_response.content
+ elif operation_model.has_event_stream_output:
+ response_dict['body'] = http_response.raw
+ elif operation_model.has_streaming_output:
+ length = response_dict['headers'].get('content-length')
+ response_dict['body'] = StreamingBody(http_response.raw, length)
+ else:
+ response_dict['body'] = http_response.content
+ return response_dict
+
+
+class Endpoint:
+ """
+ Represents an endpoint for a particular service in a specific
+ region. Only an endpoint can make requests.
+
+ :ivar service: The Service object that describes this endpoints
+ service.
+ :ivar host: The fully qualified endpoint hostname.
+ :ivar session: The session object.
+ """
+
+ def __init__(
+ self,
+ host,
+ endpoint_prefix,
+ event_emitter,
+ response_parser_factory=None,
+ http_session=None,
+ ):
+ self._endpoint_prefix = endpoint_prefix
+ self._event_emitter = event_emitter
+ self.host = host
+ self._lock = threading.Lock()
+ if response_parser_factory is None:
+ response_parser_factory = parsers.ResponseParserFactory()
+ self._response_parser_factory = response_parser_factory
+ self.http_session = http_session
+ if self.http_session is None:
+ self.http_session = URLLib3Session()
+
+ def __repr__(self):
+ return f'{self._endpoint_prefix}({self.host})'
+
+ def close(self):
+ self.http_session.close()
+
+ def make_request(self, operation_model, request_dict):
+ logger.debug(
+ "Making request for %s with params: %s",
+ operation_model,
+ request_dict,
+ )
+ return self._send_request(request_dict, operation_model)
+
+ def create_request(self, params, operation_model=None):
+ request = create_request_object(params)
+ if operation_model:
+ request.stream_output = any(
+ [
+ operation_model.has_streaming_output,
+ operation_model.has_event_stream_output,
+ ]
+ )
+ service_id = operation_model.service_model.service_id.hyphenize()
+ event_name = 'request-created.{service_id}.{op_name}'.format(
+ service_id=service_id, op_name=operation_model.name
+ )
+ self._event_emitter.emit(
+ event_name,
+ request=request,
+ operation_name=operation_model.name,
+ )
+ prepared_request = self.prepare_request(request)
+ return prepared_request
+
+ def _encode_headers(self, headers):
+ # In place encoding of headers to utf-8 if they are unicode.
+ for key, value in headers.items():
+ if isinstance(value, str):
+ headers[key] = value.encode('utf-8')
+
+ def prepare_request(self, request):
+ self._encode_headers(request.headers)
+ return request.prepare()
+
+ def _calculate_ttl(
+ self, response_received_timestamp, date_header, read_timeout
+ ):
+ local_timestamp = datetime.datetime.utcnow()
+ date_conversion = datetime.datetime.strptime(
+ date_header, "%a, %d %b %Y %H:%M:%S %Z"
+ )
+ estimated_skew = date_conversion - response_received_timestamp
+ ttl = (
+ local_timestamp
+ + datetime.timedelta(seconds=read_timeout)
+ + estimated_skew
+ )
+ return ttl.strftime('%Y%m%dT%H%M%SZ')
+
+ def _set_ttl(self, retries_context, read_timeout, success_response):
+ response_date_header = success_response[0].headers.get('Date')
+ has_streaming_input = retries_context.get('has_streaming_input')
+ if response_date_header and not has_streaming_input:
+ try:
+ response_received_timestamp = datetime.datetime.utcnow()
+ retries_context['ttl'] = self._calculate_ttl(
+ response_received_timestamp,
+ response_date_header,
+ read_timeout,
+ )
+ except Exception:
+ logger.debug(
+ "Exception received when updating retries context with TTL",
+ exc_info=True,
+ )
+
+ def _update_retries_context(self, context, attempt, success_response=None):
+ retries_context = context.setdefault('retries', {})
+ retries_context['attempt'] = attempt
+ if 'invocation-id' not in retries_context:
+ retries_context['invocation-id'] = str(uuid.uuid4())
+
+ if success_response:
+ read_timeout = context['client_config'].read_timeout
+ self._set_ttl(retries_context, read_timeout, success_response)
+
+ def _send_request(self, request_dict, operation_model):
+ attempts = 1
+ context = request_dict['context']
+ self._update_retries_context(context, attempts)
+ request = self.create_request(request_dict, operation_model)
+ success_response, exception = self._get_response(
+ request, operation_model, context
+ )
+ while self._needs_retry(
+ attempts,
+ operation_model,
+ request_dict,
+ success_response,
+ exception,
+ ):
+ attempts += 1
+ self._update_retries_context(context, attempts, success_response)
+ # If there is a stream associated with the request, we need
+ # to reset it before attempting to send the request again.
+ # This will ensure that we resend the entire contents of the
+ # body.
+ request.reset_stream()
+ # Create a new request when retried (including a new signature).
+ request = self.create_request(request_dict, operation_model)
+ success_response, exception = self._get_response(
+ request, operation_model, context
+ )
+ if (
+ success_response is not None
+ and 'ResponseMetadata' in success_response[1]
+ ):
+ # We want to share num retries, not num attempts.
+ total_retries = attempts - 1
+ success_response[1]['ResponseMetadata'][
+ 'RetryAttempts'
+ ] = total_retries
+ if exception is not None:
+ raise exception
+ else:
+ return success_response
+
+ def _get_response(self, request, operation_model, context):
+ # This will return a tuple of (success_response, exception)
+ # and success_response is itself a tuple of
+ # (http_response, parsed_dict).
+ # If an exception occurs then the success_response is None.
+ # If no exception occurs then exception is None.
+ success_response, exception = self._do_get_response(
+ request, operation_model, context
+ )
+ kwargs_to_emit = {
+ 'response_dict': None,
+ 'parsed_response': None,
+ 'context': context,
+ 'exception': exception,
+ }
+ if success_response is not None:
+ http_response, parsed_response = success_response
+ kwargs_to_emit['parsed_response'] = parsed_response
+ kwargs_to_emit['response_dict'] = convert_to_response_dict(
+ http_response, operation_model
+ )
+ service_id = operation_model.service_model.service_id.hyphenize()
+ self._event_emitter.emit(
+ f"response-received.{service_id}.{operation_model.name}",
+ **kwargs_to_emit,
+ )
+ return success_response, exception
+
+ def _do_get_response(self, request, operation_model, context):
+ try:
+ logger.debug("Sending http request: %s", request)
+ history_recorder.record(
+ 'HTTP_REQUEST',
+ {
+ 'method': request.method,
+ 'headers': request.headers,
+ 'streaming': operation_model.has_streaming_input,
+ 'url': request.url,
+ 'body': request.body,
+ },
+ )
+ service_id = operation_model.service_model.service_id.hyphenize()
+ event_name = f"before-send.{service_id}.{operation_model.name}"
+ responses = self._event_emitter.emit(event_name, request=request)
+ http_response = first_non_none_response(responses)
+ if http_response is None:
+ http_response = self._send(request)
+ except HTTPClientError as e:
+ return (None, e)
+ except Exception as e:
+ logger.debug(
+ "Exception received when sending HTTP request.", exc_info=True
+ )
+ return (None, e)
+ # This returns the http_response and the parsed_data.
+ response_dict = convert_to_response_dict(
+ http_response, operation_model
+ )
+ handle_checksum_body(
+ http_response,
+ response_dict,
+ context,
+ operation_model,
+ )
+
+ http_response_record_dict = response_dict.copy()
+ http_response_record_dict[
+ 'streaming'
+ ] = operation_model.has_streaming_output
+ history_recorder.record('HTTP_RESPONSE', http_response_record_dict)
+
+ protocol = operation_model.metadata['protocol']
+ parser = self._response_parser_factory.create_parser(protocol)
+ parsed_response = parser.parse(
+ response_dict, operation_model.output_shape
+ )
+ # Do a second parsing pass to pick up on any modeled error fields
+ # NOTE: Ideally, we would push this down into the parser classes but
+ # they currently have no reference to the operation or service model
+ # The parsers should probably take the operation model instead of
+ # output shape but we can't change that now
+ if http_response.status_code >= 300:
+ self._add_modeled_error_fields(
+ response_dict,
+ parsed_response,
+ operation_model,
+ parser,
+ )
+ history_recorder.record('PARSED_RESPONSE', parsed_response)
+ return (http_response, parsed_response), None
+
+ def _add_modeled_error_fields(
+ self,
+ response_dict,
+ parsed_response,
+ operation_model,
+ parser,
+ ):
+ error_code = parsed_response.get("Error", {}).get("Code")
+ if error_code is None:
+ return
+ service_model = operation_model.service_model
+ error_shape = service_model.shape_for_error_code(error_code)
+ if error_shape is None:
+ return
+ modeled_parse = parser.parse(response_dict, error_shape)
+ # TODO: avoid naming conflicts with ResponseMetadata and Error
+ parsed_response.update(modeled_parse)
+
+ def _needs_retry(
+ self,
+ attempts,
+ operation_model,
+ request_dict,
+ response=None,
+ caught_exception=None,
+ ):
+ service_id = operation_model.service_model.service_id.hyphenize()
+ event_name = f"needs-retry.{service_id}.{operation_model.name}"
+ responses = self._event_emitter.emit(
+ event_name,
+ response=response,
+ endpoint=self,
+ operation=operation_model,
+ attempts=attempts,
+ caught_exception=caught_exception,
+ request_dict=request_dict,
+ )
+ handler_response = first_non_none_response(responses)
+ if handler_response is None:
+ return False
+ else:
+ # Request needs to be retried, and we need to sleep
+ # for the specified number of times.
+ logger.debug(
+ "Response received to retry, sleeping for %s seconds",
+ handler_response,
+ )
+ time.sleep(handler_response)
+ return True
+
+ def _send(self, request):
+ return self.http_session.send(request)
+
+
+class EndpointCreator:
+ def __init__(self, event_emitter):
+ self._event_emitter = event_emitter
+
+ def create_endpoint(
+ self,
+ service_model,
+ region_name,
+ endpoint_url,
+ verify=None,
+ response_parser_factory=None,
+ timeout=DEFAULT_TIMEOUT,
+ max_pool_connections=MAX_POOL_CONNECTIONS,
+ http_session_cls=URLLib3Session,
+ proxies=None,
+ socket_options=None,
+ client_cert=None,
+ proxies_config=None,
+ ):
+ if not is_valid_endpoint_url(
+ endpoint_url
+ ) and not is_valid_ipv6_endpoint_url(endpoint_url):
+ raise ValueError("Invalid endpoint: %s" % endpoint_url)
+
+ if proxies is None:
+ proxies = self._get_proxies(endpoint_url)
+ endpoint_prefix = service_model.endpoint_prefix
+
+ logger.debug('Setting %s timeout as %s', endpoint_prefix, timeout)
+ http_session = http_session_cls(
+ timeout=timeout,
+ proxies=proxies,
+ verify=self._get_verify_value(verify),
+ max_pool_connections=max_pool_connections,
+ socket_options=socket_options,
+ client_cert=client_cert,
+ proxies_config=proxies_config,
+ )
+
+ return Endpoint(
+ endpoint_url,
+ endpoint_prefix=endpoint_prefix,
+ event_emitter=self._event_emitter,
+ response_parser_factory=response_parser_factory,
+ http_session=http_session,
+ )
+
+ def _get_proxies(self, url):
+ # We could also support getting proxies from a config file,
+ # but for now proxy support is taken from the environment.
+ return get_environ_proxies(url)
+
+ def _get_verify_value(self, verify):
+ # This is to account for:
+ # https://github.com/kennethreitz/requests/issues/1436
+ # where we need to honor REQUESTS_CA_BUNDLE because we're creating our
+ # own request objects.
+ # First, if verify is not None, then the user explicitly specified
+ # a value so this automatically wins.
+ if verify is not None:
+ return verify
+ # Otherwise use the value from REQUESTS_CA_BUNDLE, or default to
+ # True if the env var does not exist.
+ return os.environ.get('REQUESTS_CA_BUNDLE', True)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/endpoint_provider.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/endpoint_provider.py
new file mode 100644
index 0000000000..1be5a25c8d
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/endpoint_provider.py
@@ -0,0 +1,722 @@
+# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+"""
+NOTE: All classes and functions in this module are considered private and are
+subject to abrupt breaking changes. Please do not use them directly.
+
+To view the raw JSON that the objects in this module represent, please
+go to any `endpoint-rule-set.json` file in /botocore/data///
+or you can look at the test files in /tests/unit/data/endpoints/valid-rules/
+"""
+
+
+import logging
+import re
+from enum import Enum
+from string import Formatter
+from typing import NamedTuple
+
+from botocore import xform_name
+from botocore.compat import IPV4_RE, quote, urlparse
+from botocore.exceptions import EndpointResolutionError
+from botocore.utils import (
+ ArnParser,
+ InvalidArnException,
+ is_valid_ipv4_endpoint_url,
+ is_valid_ipv6_endpoint_url,
+ lru_cache_weakref,
+ normalize_url_path,
+ percent_encode,
+)
+
+logger = logging.getLogger(__name__)
+
+TEMPLATE_STRING_RE = re.compile(r"\{[a-zA-Z#]+\}")
+GET_ATTR_RE = re.compile(r"(\w+)\[(\d+)\]")
+VALID_HOST_LABEL_RE = re.compile(
+ r"^(?!-)[a-zA-Z\d-]{1,63}(?= len(value):
+ return None
+ return value[index]
+ else:
+ value = value[part]
+ return value
+
+ def format_partition_output(self, partition):
+ output = partition["outputs"]
+ output["name"] = partition["id"]
+ return output
+
+ def is_partition_match(self, region, partition):
+ matches_regex = re.match(partition["regionRegex"], region) is not None
+ return region in partition["regions"] or matches_regex
+
+ def aws_partition(self, value):
+ """Match a region string to an AWS partition.
+
+ :type value: str
+ :rtype: dict
+ """
+ partitions = self.partitions_data['partitions']
+
+ if value is not None:
+ for partition in partitions:
+ if self.is_partition_match(value, partition):
+ return self.format_partition_output(partition)
+
+ # return the default partition if no matches were found
+ aws_partition = partitions[0]
+ return self.format_partition_output(aws_partition)
+
+ def aws_parse_arn(self, value):
+ """Parse and validate string for ARN components.
+
+ :type value: str
+ :rtype: dict
+ """
+ if value is None or not value.startswith("arn:"):
+ return None
+
+ try:
+ arn_dict = ARN_PARSER.parse_arn(value)
+ except InvalidArnException:
+ return None
+
+ # partition, resource, and service are required
+ if not all(
+ (arn_dict["partition"], arn_dict["service"], arn_dict["resource"])
+ ):
+ return None
+
+ arn_dict["accountId"] = arn_dict.pop("account")
+
+ resource = arn_dict.pop("resource")
+ arn_dict["resourceId"] = resource.replace(":", "/").split("/")
+
+ return arn_dict
+
+ def is_valid_host_label(self, value, allow_subdomains):
+ """Evaluates whether a value is a valid host label per
+ RFC 1123. If allow_subdomains is True, split on `.` and validate
+ each component separately.
+
+ :type value: str
+ :type allow_subdomains: bool
+ :rtype: bool
+ """
+ if value is None or allow_subdomains is False and value.count(".") > 0:
+ return False
+
+ if allow_subdomains is True:
+ return all(
+ self.is_valid_host_label(label, False)
+ for label in value.split(".")
+ )
+
+ return VALID_HOST_LABEL_RE.match(value) is not None
+
+ def string_equals(self, value1, value2):
+ """Evaluates two string values for equality.
+
+ :type value1: str
+ :type value2: str
+ :rtype: bool
+ """
+ if not all(isinstance(val, str) for val in (value1, value2)):
+ msg = f"Both values must be strings, not {type(value1)} and {type(value2)}."
+ raise EndpointResolutionError(msg=msg)
+ return value1 == value2
+
+ def uri_encode(self, value):
+ """Perform percent-encoding on an input string.
+
+ :type value: str
+ :rytpe: str
+ """
+ if value is None:
+ return None
+
+ return percent_encode(value)
+
+ def parse_url(self, value):
+ """Parse a URL string into components.
+
+ :type value: str
+ :rtype: dict
+ """
+ if value is None:
+ return None
+
+ url_components = urlparse(value)
+ try:
+ # url_parse may assign non-integer values to
+ # `port` and will fail when accessed.
+ url_components.port
+ except ValueError:
+ return None
+
+ scheme = url_components.scheme
+ query = url_components.query
+ # URLs with queries are not supported
+ if scheme not in ("https", "http") or len(query) > 0:
+ return None
+
+ path = url_components.path
+ normalized_path = quote(normalize_url_path(path))
+ if not normalized_path.endswith("/"):
+ normalized_path = f"{normalized_path}/"
+
+ return {
+ "scheme": scheme,
+ "authority": url_components.netloc,
+ "path": path,
+ "normalizedPath": normalized_path,
+ "isIp": is_valid_ipv4_endpoint_url(value)
+ or is_valid_ipv6_endpoint_url(value),
+ }
+
+ def boolean_equals(self, value1, value2):
+ """Evaluates two boolean values for equality.
+
+ :type value1: bool
+ :type value2: bool
+ :rtype: bool
+ """
+ if not all(isinstance(val, bool) for val in (value1, value2)):
+ msg = f"Both arguments must be bools, not {type(value1)} and {type(value2)}."
+ raise EndpointResolutionError(msg=msg)
+ return value1 is value2
+
+ def is_ascii(self, value):
+ """Evaluates if a string only contains ASCII characters.
+
+ :type value: str
+ :rtype: bool
+ """
+ try:
+ value.encode("ascii")
+ return True
+ except UnicodeEncodeError:
+ return False
+
+ def substring(self, value, start, stop, reverse):
+ """Computes a substring given the start index and end index. If `reverse` is
+ True, slice the string from the end instead.
+
+ :type value: str
+ :type start: int
+ :type end: int
+ :type reverse: bool
+ :rtype: str
+ """
+ if not isinstance(value, str):
+ msg = f"Input must be a string, not {type(value)}."
+ raise EndpointResolutionError(msg=msg)
+ if start >= stop or len(value) < stop or not self.is_ascii(value):
+ return None
+
+ if reverse is True:
+ r_start = len(value) - stop
+ r_stop = len(value) - start
+ return value[r_start:r_stop]
+
+ return value[start:stop]
+
+ def _not(self, value):
+ """A function implementation of the logical operator `not`.
+
+ :type value: Any
+ :rtype: bool
+ """
+ return not value
+
+ def aws_is_virtual_hostable_s3_bucket(self, value, allow_subdomains):
+ """Evaluates whether a value is a valid bucket name for virtual host
+ style bucket URLs. To pass, the value must meet the following criteria:
+ 1. is_valid_host_label(value) is True
+ 2. length between 3 and 63 characters (inclusive)
+ 3. does not contain uppercase characters
+ 4. is not formatted as an IP address
+
+ If allow_subdomains is True, split on `.` and validate
+ each component separately.
+
+ :type value: str
+ :type allow_subdomains: bool
+ :rtype: bool
+ """
+ if (
+ value is None
+ or len(value) < 3
+ or value.lower() != value
+ or IPV4_RE.match(value) is not None
+ ):
+ return False
+
+ return self.is_valid_host_label(
+ value, allow_subdomains=allow_subdomains
+ )
+
+
+# maintains backwards compatibility as `Library` was misspelled
+# in earlier versions
+RuleSetStandardLibary = RuleSetStandardLibrary
+
+
+class BaseRule:
+ """Base interface for individual endpoint rules."""
+
+ def __init__(self, conditions, documentation=None):
+ self.conditions = conditions
+ self.documentation = documentation
+
+ def evaluate(self, scope_vars, rule_lib):
+ raise NotImplementedError()
+
+ def evaluate_conditions(self, scope_vars, rule_lib):
+ """Determine if all conditions in a rule are met.
+
+ :type scope_vars: dict
+ :type rule_lib: RuleSetStandardLibrary
+ :rtype: bool
+ """
+ for func_signature in self.conditions:
+ result = rule_lib.call_function(func_signature, scope_vars)
+ if result is False or result is None:
+ return False
+ return True
+
+
+class RuleSetEndpoint(NamedTuple):
+ """A resolved endpoint object returned by a rule."""
+
+ url: str
+ properties: dict
+ headers: dict
+
+
+class EndpointRule(BaseRule):
+ def __init__(self, endpoint, **kwargs):
+ super().__init__(**kwargs)
+ self.endpoint = endpoint
+
+ def evaluate(self, scope_vars, rule_lib):
+ """Determine if conditions are met to provide a valid endpoint.
+
+ :type scope_vars: dict
+ :rtype: RuleSetEndpoint
+ """
+ if self.evaluate_conditions(scope_vars, rule_lib):
+ url = rule_lib.resolve_value(self.endpoint["url"], scope_vars)
+ properties = self.resolve_properties(
+ self.endpoint.get("properties", {}),
+ scope_vars,
+ rule_lib,
+ )
+ headers = self.resolve_headers(scope_vars, rule_lib)
+ return RuleSetEndpoint(
+ url=url, properties=properties, headers=headers
+ )
+
+ return None
+
+ def resolve_properties(self, properties, scope_vars, rule_lib):
+ """Traverse `properties` attribute, resolving any template strings.
+
+ :type properties: dict/list/str
+ :type scope_vars: dict
+ :type rule_lib: RuleSetStandardLibrary
+ :rtype: dict
+ """
+ if isinstance(properties, list):
+ return [
+ self.resolve_properties(prop, scope_vars, rule_lib)
+ for prop in properties
+ ]
+ elif isinstance(properties, dict):
+ return {
+ key: self.resolve_properties(value, scope_vars, rule_lib)
+ for key, value in properties.items()
+ }
+ elif rule_lib.is_template(properties):
+ return rule_lib.resolve_template_string(properties, scope_vars)
+
+ return properties
+
+ def resolve_headers(self, scope_vars, rule_lib):
+ """Iterate through headers attribute resolving all values.
+
+ :type scope_vars: dict
+ :type rule_lib: RuleSetStandardLibrary
+ :rtype: dict
+ """
+ resolved_headers = {}
+ headers = self.endpoint.get("headers", {})
+
+ for header, values in headers.items():
+ resolved_headers[header] = [
+ rule_lib.resolve_value(item, scope_vars) for item in values
+ ]
+ return resolved_headers
+
+
+class ErrorRule(BaseRule):
+ def __init__(self, error, **kwargs):
+ super().__init__(**kwargs)
+ self.error = error
+
+ def evaluate(self, scope_vars, rule_lib):
+ """If an error rule's conditions are met, raise an error rule.
+
+ :type scope_vars: dict
+ :type rule_lib: RuleSetStandardLibrary
+ :rtype: EndpointResolutionError
+ """
+ if self.evaluate_conditions(scope_vars, rule_lib):
+ error = rule_lib.resolve_value(self.error, scope_vars)
+ raise EndpointResolutionError(msg=error)
+ return None
+
+
+class TreeRule(BaseRule):
+ """A tree rule is non-terminal meaning it will never be returned to a provider.
+ Additionally this means it has no attributes that need to be resolved.
+ """
+
+ def __init__(self, rules, **kwargs):
+ super().__init__(**kwargs)
+ self.rules = [RuleCreator.create(**rule) for rule in rules]
+
+ def evaluate(self, scope_vars, rule_lib):
+ """If a tree rule's conditions are met, iterate its sub-rules
+ and return first result found.
+
+ :type scope_vars: dict
+ :type rule_lib: RuleSetStandardLibrary
+ :rtype: RuleSetEndpoint/EndpointResolutionError
+ """
+ if self.evaluate_conditions(scope_vars, rule_lib):
+ for rule in self.rules:
+ # don't share scope_vars between rules
+ rule_result = rule.evaluate(scope_vars.copy(), rule_lib)
+ if rule_result:
+ return rule_result
+ return None
+
+
+class RuleCreator:
+ endpoint = EndpointRule
+ error = ErrorRule
+ tree = TreeRule
+
+ @classmethod
+ def create(cls, **kwargs):
+ """Create a rule instance from metadata.
+
+ :rtype: TreeRule/EndpointRule/ErrorRule
+ """
+ rule_type = kwargs.pop("type")
+ try:
+ rule_class = getattr(cls, rule_type)
+ except AttributeError:
+ raise EndpointResolutionError(
+ msg=f"Unknown rule type: {rule_type}. A rule must "
+ "be of type tree, endpoint or error."
+ )
+ else:
+ return rule_class(**kwargs)
+
+
+class ParameterType(Enum):
+ """Translation from `type` attribute to native Python type."""
+
+ string = str
+ boolean = bool
+
+
+class ParameterDefinition:
+ """The spec of an individual parameter defined in a RuleSet."""
+
+ def __init__(
+ self,
+ name,
+ parameter_type,
+ documentation=None,
+ builtIn=None,
+ default=None,
+ required=None,
+ deprecated=None,
+ ):
+ self.name = name
+ try:
+ self.parameter_type = getattr(
+ ParameterType, parameter_type.lower()
+ ).value
+ except AttributeError:
+ raise EndpointResolutionError(
+ msg=f"Unknown parameter type: {parameter_type}. "
+ "A parameter must be of type string or boolean."
+ )
+ self.documentation = documentation
+ self.builtin = builtIn
+ self.default = default
+ self.required = required
+ self.deprecated = deprecated
+
+ def validate_input(self, value):
+ """Perform base validation on parameter input.
+
+ :type value: Any
+ :raises: EndpointParametersError
+ """
+
+ if not isinstance(value, self.parameter_type):
+ raise EndpointResolutionError(
+ msg=f"Value ({self.name}) is the wrong "
+ f"type. Must be {self.parameter_type}."
+ )
+ if self.deprecated is not None:
+ depr_str = f"{self.name} has been deprecated."
+ msg = self.deprecated.get("message")
+ since = self.deprecated.get("since")
+ if msg:
+ depr_str += f"\n{msg}"
+ if since:
+ depr_str += f"\nDeprecated since {since}."
+ logger.info(depr_str)
+
+ return None
+
+ def process_input(self, value):
+ """Process input against spec, applying default if value is None."""
+ if value is None:
+ if self.default is not None:
+ return self.default
+ if self.required:
+ raise EndpointResolutionError(
+ f"Cannot find value for required parameter {self.name}"
+ )
+ # in all other cases, the parameter will keep the value None
+ else:
+ self.validate_input(value)
+ return value
+
+
+class RuleSet:
+ """Collection of rules to derive a routable service endpoint."""
+
+ def __init__(
+ self, version, parameters, rules, partitions, documentation=None
+ ):
+ self.version = version
+ self.parameters = self._ingest_parameter_spec(parameters)
+ self.rules = [RuleCreator.create(**rule) for rule in rules]
+ self.rule_lib = RuleSetStandardLibrary(partitions)
+ self.documentation = documentation
+
+ def _ingest_parameter_spec(self, parameters):
+ return {
+ name: ParameterDefinition(
+ name,
+ spec["type"],
+ spec.get("documentation"),
+ spec.get("builtIn"),
+ spec.get("default"),
+ spec.get("required"),
+ spec.get("deprecated"),
+ )
+ for name, spec in parameters.items()
+ }
+
+ def process_input_parameters(self, input_params):
+ """Process each input parameter against its spec.
+
+ :type input_params: dict
+ """
+ for name, spec in self.parameters.items():
+ value = spec.process_input(input_params.get(name))
+ if value is not None:
+ input_params[name] = value
+ return None
+
+ def evaluate(self, input_parameters):
+ """Evaluate input parameters against rules returning first match.
+
+ :type input_parameters: dict
+ """
+ self.process_input_parameters(input_parameters)
+ for rule in self.rules:
+ evaluation = rule.evaluate(input_parameters.copy(), self.rule_lib)
+ if evaluation is not None:
+ return evaluation
+ return None
+
+
+class EndpointProvider:
+ """Derives endpoints from a RuleSet for given input parameters."""
+
+ def __init__(self, ruleset_data, partition_data):
+ self.ruleset = RuleSet(**ruleset_data, partitions=partition_data)
+
+ @lru_cache_weakref(maxsize=CACHE_SIZE)
+ def resolve_endpoint(self, **input_parameters):
+ """Match input parameters to a rule.
+
+ :type input_parameters: dict
+ :rtype: RuleSetEndpoint
+ """
+ params_for_error = input_parameters.copy()
+ endpoint = self.ruleset.evaluate(input_parameters)
+ if endpoint is None:
+ param_string = "\n".join(
+ [f"{key}: {value}" for key, value in params_for_error.items()]
+ )
+ raise EndpointResolutionError(
+ msg=f"No endpoint found for parameters:\n{param_string}"
+ )
+ return endpoint
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/errorfactory.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/errorfactory.py
new file mode 100644
index 0000000000..d9a1e9cd9c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/errorfactory.py
@@ -0,0 +1,90 @@
+# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.exceptions import ClientError
+from botocore.utils import get_service_module_name
+
+
+class BaseClientExceptions:
+ ClientError = ClientError
+
+ def __init__(self, code_to_exception):
+ """Base class for exceptions object on a client
+
+ :type code_to_exception: dict
+ :param code_to_exception: Mapping of error codes (strings) to exception
+ class that should be raised when encountering a particular
+ error code.
+ """
+ self._code_to_exception = code_to_exception
+
+ def from_code(self, error_code):
+ """Retrieves the error class based on the error code
+
+ This is helpful for identifying the exception class needing to be
+ caught based on the ClientError.parsed_reponse['Error']['Code'] value
+
+ :type error_code: string
+ :param error_code: The error code associated to a ClientError exception
+
+ :rtype: ClientError or a subclass of ClientError
+ :returns: The appropriate modeled exception class for that error
+ code. If the error code does not match any of the known
+ modeled exceptions then return a generic ClientError.
+ """
+ return self._code_to_exception.get(error_code, self.ClientError)
+
+ def __getattr__(self, name):
+ exception_cls_names = [
+ exception_cls.__name__
+ for exception_cls in self._code_to_exception.values()
+ ]
+ raise AttributeError(
+ fr"{self} object has no attribute {name}. "
+ fr"Valid exceptions are: {', '.join(exception_cls_names)}"
+ )
+
+
+class ClientExceptionsFactory:
+ def __init__(self):
+ self._client_exceptions_cache = {}
+
+ def create_client_exceptions(self, service_model):
+ """Creates a ClientExceptions object for the particular service client
+
+ :type service_model: botocore.model.ServiceModel
+ :param service_model: The service model for the client
+
+ :rtype: object that subclasses from BaseClientExceptions
+ :returns: The exceptions object of a client that can be used
+ to grab the various different modeled exceptions.
+ """
+ service_name = service_model.service_name
+ if service_name not in self._client_exceptions_cache:
+ client_exceptions = self._create_client_exceptions(service_model)
+ self._client_exceptions_cache[service_name] = client_exceptions
+ return self._client_exceptions_cache[service_name]
+
+ def _create_client_exceptions(self, service_model):
+ cls_props = {}
+ code_to_exception = {}
+ for error_shape in service_model.error_shapes:
+ exception_name = str(error_shape.name)
+ exception_cls = type(exception_name, (ClientError,), {})
+ cls_props[exception_name] = exception_cls
+ code = str(error_shape.error_code)
+ code_to_exception[code] = exception_cls
+ cls_name = str(get_service_module_name(service_model) + 'Exceptions')
+ client_exceptions_cls = type(
+ cls_name, (BaseClientExceptions,), cls_props
+ )
+ return client_exceptions_cls(code_to_exception)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/eventstream.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/eventstream.py
new file mode 100644
index 0000000000..11baf81a32
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/eventstream.py
@@ -0,0 +1,633 @@
+# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""Binary Event Stream Decoding """
+
+from binascii import crc32
+from struct import unpack
+
+from botocore.exceptions import EventStreamError
+
+# byte length of the prelude (total_length + header_length + prelude_crc)
+_PRELUDE_LENGTH = 12
+_MAX_HEADERS_LENGTH = 128 * 1024 # 128 Kb
+_MAX_PAYLOAD_LENGTH = 16 * 1024**2 # 16 Mb
+
+
+class ParserError(Exception):
+ """Base binary flow encoding parsing exception."""
+
+ pass
+
+
+class DuplicateHeader(ParserError):
+ """Duplicate header found in the event."""
+
+ def __init__(self, header):
+ message = 'Duplicate header present: "%s"' % header
+ super().__init__(message)
+
+
+class InvalidHeadersLength(ParserError):
+ """Headers length is longer than the maximum."""
+
+ def __init__(self, length):
+ message = 'Header length of {} exceeded the maximum of {}'.format(
+ length,
+ _MAX_HEADERS_LENGTH,
+ )
+ super().__init__(message)
+
+
+class InvalidPayloadLength(ParserError):
+ """Payload length is longer than the maximum."""
+
+ def __init__(self, length):
+ message = 'Payload length of {} exceeded the maximum of {}'.format(
+ length,
+ _MAX_PAYLOAD_LENGTH,
+ )
+ super().__init__(message)
+
+
+class ChecksumMismatch(ParserError):
+ """Calculated checksum did not match the expected checksum."""
+
+ def __init__(self, expected, calculated):
+ message = (
+ 'Checksum mismatch: expected 0x{:08x}, calculated 0x{:08x}'.format(
+ expected,
+ calculated,
+ )
+ )
+ super().__init__(message)
+
+
+class NoInitialResponseError(ParserError):
+ """An event of type initial-response was not received.
+
+ This exception is raised when the event stream produced no events or
+ the first event in the stream was not of the initial-response type.
+ """
+
+ def __init__(self):
+ message = 'First event was not of the initial-response type'
+ super().__init__(message)
+
+
+class DecodeUtils:
+ """Unpacking utility functions used in the decoder.
+
+ All methods on this class take raw bytes and return a tuple containing
+ the value parsed from the bytes and the number of bytes consumed to parse
+ that value.
+ """
+
+ UINT8_BYTE_FORMAT = '!B'
+ UINT16_BYTE_FORMAT = '!H'
+ UINT32_BYTE_FORMAT = '!I'
+ INT8_BYTE_FORMAT = '!b'
+ INT16_BYTE_FORMAT = '!h'
+ INT32_BYTE_FORMAT = '!i'
+ INT64_BYTE_FORMAT = '!q'
+ PRELUDE_BYTE_FORMAT = '!III'
+
+ # uint byte size to unpack format
+ UINT_BYTE_FORMAT = {
+ 1: UINT8_BYTE_FORMAT,
+ 2: UINT16_BYTE_FORMAT,
+ 4: UINT32_BYTE_FORMAT,
+ }
+
+ @staticmethod
+ def unpack_true(data):
+ """This method consumes none of the provided bytes and returns True.
+
+ :type data: bytes
+ :param data: The bytes to parse from. This is ignored in this method.
+
+ :rtype: tuple
+ :rtype: (bool, int)
+ :returns: The tuple (True, 0)
+ """
+ return True, 0
+
+ @staticmethod
+ def unpack_false(data):
+ """This method consumes none of the provided bytes and returns False.
+
+ :type data: bytes
+ :param data: The bytes to parse from. This is ignored in this method.
+
+ :rtype: tuple
+ :rtype: (bool, int)
+ :returns: The tuple (False, 0)
+ """
+ return False, 0
+
+ @staticmethod
+ def unpack_uint8(data):
+ """Parse an unsigned 8-bit integer from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: (int, int)
+ :returns: A tuple containing the (parsed integer value, bytes consumed)
+ """
+ value = unpack(DecodeUtils.UINT8_BYTE_FORMAT, data[:1])[0]
+ return value, 1
+
+ @staticmethod
+ def unpack_uint32(data):
+ """Parse an unsigned 32-bit integer from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: (int, int)
+ :returns: A tuple containing the (parsed integer value, bytes consumed)
+ """
+ value = unpack(DecodeUtils.UINT32_BYTE_FORMAT, data[:4])[0]
+ return value, 4
+
+ @staticmethod
+ def unpack_int8(data):
+ """Parse a signed 8-bit integer from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: (int, int)
+ :returns: A tuple containing the (parsed integer value, bytes consumed)
+ """
+ value = unpack(DecodeUtils.INT8_BYTE_FORMAT, data[:1])[0]
+ return value, 1
+
+ @staticmethod
+ def unpack_int16(data):
+ """Parse a signed 16-bit integer from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: tuple
+ :rtype: (int, int)
+ :returns: A tuple containing the (parsed integer value, bytes consumed)
+ """
+ value = unpack(DecodeUtils.INT16_BYTE_FORMAT, data[:2])[0]
+ return value, 2
+
+ @staticmethod
+ def unpack_int32(data):
+ """Parse a signed 32-bit integer from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: tuple
+ :rtype: (int, int)
+ :returns: A tuple containing the (parsed integer value, bytes consumed)
+ """
+ value = unpack(DecodeUtils.INT32_BYTE_FORMAT, data[:4])[0]
+ return value, 4
+
+ @staticmethod
+ def unpack_int64(data):
+ """Parse a signed 64-bit integer from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: tuple
+ :rtype: (int, int)
+ :returns: A tuple containing the (parsed integer value, bytes consumed)
+ """
+ value = unpack(DecodeUtils.INT64_BYTE_FORMAT, data[:8])[0]
+ return value, 8
+
+ @staticmethod
+ def unpack_byte_array(data, length_byte_size=2):
+ """Parse a variable length byte array from the bytes.
+
+ The bytes are expected to be in the following format:
+ [ length ][0 ... length bytes]
+ where length is an unsigned integer represented in the smallest number
+ of bytes to hold the maximum length of the array.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :type length_byte_size: int
+ :param length_byte_size: The byte size of the preceding integer that
+ represents the length of the array. Supported values are 1, 2, and 4.
+
+ :rtype: (bytes, int)
+ :returns: A tuple containing the (parsed byte array, bytes consumed).
+ """
+ uint_byte_format = DecodeUtils.UINT_BYTE_FORMAT[length_byte_size]
+ length = unpack(uint_byte_format, data[:length_byte_size])[0]
+ bytes_end = length + length_byte_size
+ array_bytes = data[length_byte_size:bytes_end]
+ return array_bytes, bytes_end
+
+ @staticmethod
+ def unpack_utf8_string(data, length_byte_size=2):
+ """Parse a variable length utf-8 string from the bytes.
+
+ The bytes are expected to be in the following format:
+ [ length ][0 ... length bytes]
+ where length is an unsigned integer represented in the smallest number
+ of bytes to hold the maximum length of the array and the following
+ bytes are a valid utf-8 string.
+
+ :type data: bytes
+ :param bytes: The bytes to parse from.
+
+ :type length_byte_size: int
+ :param length_byte_size: The byte size of the preceding integer that
+ represents the length of the array. Supported values are 1, 2, and 4.
+
+ :rtype: (str, int)
+ :returns: A tuple containing the (utf-8 string, bytes consumed).
+ """
+ array_bytes, consumed = DecodeUtils.unpack_byte_array(
+ data, length_byte_size
+ )
+ return array_bytes.decode('utf-8'), consumed
+
+ @staticmethod
+ def unpack_uuid(data):
+ """Parse a 16-byte uuid from the bytes.
+
+ :type data: bytes
+ :param data: The bytes to parse from.
+
+ :rtype: (bytes, int)
+ :returns: A tuple containing the (uuid bytes, bytes consumed).
+ """
+ return data[:16], 16
+
+ @staticmethod
+ def unpack_prelude(data):
+ """Parse the prelude for an event stream message from the bytes.
+
+ The prelude for an event stream message has the following format:
+ [total_length][header_length][prelude_crc]
+ where each field is an unsigned 32-bit integer.
+
+ :rtype: ((int, int, int), int)
+ :returns: A tuple of ((total_length, headers_length, prelude_crc),
+ consumed)
+ """
+ return (unpack(DecodeUtils.PRELUDE_BYTE_FORMAT, data), _PRELUDE_LENGTH)
+
+
+def _validate_checksum(data, checksum, crc=0):
+ # To generate the same numeric value across all Python versions and
+ # platforms use crc32(data) & 0xffffffff.
+ computed_checksum = crc32(data, crc) & 0xFFFFFFFF
+ if checksum != computed_checksum:
+ raise ChecksumMismatch(checksum, computed_checksum)
+
+
+class MessagePrelude:
+ """Represents the prelude of an event stream message."""
+
+ def __init__(self, total_length, headers_length, crc):
+ self.total_length = total_length
+ self.headers_length = headers_length
+ self.crc = crc
+
+ @property
+ def payload_length(self):
+ """Calculates the total payload length.
+
+ The extra minus 4 bytes is for the message CRC.
+
+ :rtype: int
+ :returns: The total payload length.
+ """
+ return self.total_length - self.headers_length - _PRELUDE_LENGTH - 4
+
+ @property
+ def payload_end(self):
+ """Calculates the byte offset for the end of the message payload.
+
+ The extra minus 4 bytes is for the message CRC.
+
+ :rtype: int
+ :returns: The byte offset from the beginning of the event stream
+ message to the end of the payload.
+ """
+ return self.total_length - 4
+
+ @property
+ def headers_end(self):
+ """Calculates the byte offset for the end of the message headers.
+
+ :rtype: int
+ :returns: The byte offset from the beginning of the event stream
+ message to the end of the headers.
+ """
+ return _PRELUDE_LENGTH + self.headers_length
+
+
+class EventStreamMessage:
+ """Represents an event stream message."""
+
+ def __init__(self, prelude, headers, payload, crc):
+ self.prelude = prelude
+ self.headers = headers
+ self.payload = payload
+ self.crc = crc
+
+ def to_response_dict(self, status_code=200):
+ message_type = self.headers.get(':message-type')
+ if message_type == 'error' or message_type == 'exception':
+ status_code = 400
+ return {
+ 'status_code': status_code,
+ 'headers': self.headers,
+ 'body': self.payload,
+ }
+
+
+class EventStreamHeaderParser:
+ """Parses the event headers from an event stream message.
+
+ Expects all of the header data upfront and creates a dictionary of headers
+ to return. This object can be reused multiple times to parse the headers
+ from multiple event stream messages.
+ """
+
+ # Maps header type to appropriate unpacking function
+ # These unpacking functions return the value and the amount unpacked
+ _HEADER_TYPE_MAP = {
+ # boolean_true
+ 0: DecodeUtils.unpack_true,
+ # boolean_false
+ 1: DecodeUtils.unpack_false,
+ # byte
+ 2: DecodeUtils.unpack_int8,
+ # short
+ 3: DecodeUtils.unpack_int16,
+ # integer
+ 4: DecodeUtils.unpack_int32,
+ # long
+ 5: DecodeUtils.unpack_int64,
+ # byte_array
+ 6: DecodeUtils.unpack_byte_array,
+ # string
+ 7: DecodeUtils.unpack_utf8_string,
+ # timestamp
+ 8: DecodeUtils.unpack_int64,
+ # uuid
+ 9: DecodeUtils.unpack_uuid,
+ }
+
+ def __init__(self):
+ self._data = None
+
+ def parse(self, data):
+ """Parses the event stream headers from an event stream message.
+
+ :type data: bytes
+ :param data: The bytes that correspond to the headers section of an
+ event stream message.
+
+ :rtype: dict
+ :returns: A dictionary of header key, value pairs.
+ """
+ self._data = data
+ return self._parse_headers()
+
+ def _parse_headers(self):
+ headers = {}
+ while self._data:
+ name, value = self._parse_header()
+ if name in headers:
+ raise DuplicateHeader(name)
+ headers[name] = value
+ return headers
+
+ def _parse_header(self):
+ name = self._parse_name()
+ value = self._parse_value()
+ return name, value
+
+ def _parse_name(self):
+ name, consumed = DecodeUtils.unpack_utf8_string(self._data, 1)
+ self._advance_data(consumed)
+ return name
+
+ def _parse_type(self):
+ type, consumed = DecodeUtils.unpack_uint8(self._data)
+ self._advance_data(consumed)
+ return type
+
+ def _parse_value(self):
+ header_type = self._parse_type()
+ value_unpacker = self._HEADER_TYPE_MAP[header_type]
+ value, consumed = value_unpacker(self._data)
+ self._advance_data(consumed)
+ return value
+
+ def _advance_data(self, consumed):
+ self._data = self._data[consumed:]
+
+
+class EventStreamBuffer:
+ """Streaming based event stream buffer
+
+ A buffer class that wraps bytes from an event stream providing parsed
+ messages as they become available via an iterable interface.
+ """
+
+ def __init__(self):
+ self._data = b''
+ self._prelude = None
+ self._header_parser = EventStreamHeaderParser()
+
+ def add_data(self, data):
+ """Add data to the buffer.
+
+ :type data: bytes
+ :param data: The bytes to add to the buffer to be used when parsing
+ """
+ self._data += data
+
+ def _validate_prelude(self, prelude):
+ if prelude.headers_length > _MAX_HEADERS_LENGTH:
+ raise InvalidHeadersLength(prelude.headers_length)
+
+ if prelude.payload_length > _MAX_PAYLOAD_LENGTH:
+ raise InvalidPayloadLength(prelude.payload_length)
+
+ def _parse_prelude(self):
+ prelude_bytes = self._data[:_PRELUDE_LENGTH]
+ raw_prelude, _ = DecodeUtils.unpack_prelude(prelude_bytes)
+ prelude = MessagePrelude(*raw_prelude)
+ self._validate_prelude(prelude)
+ # The minus 4 removes the prelude crc from the bytes to be checked
+ _validate_checksum(prelude_bytes[: _PRELUDE_LENGTH - 4], prelude.crc)
+ return prelude
+
+ def _parse_headers(self):
+ header_bytes = self._data[_PRELUDE_LENGTH : self._prelude.headers_end]
+ return self._header_parser.parse(header_bytes)
+
+ def _parse_payload(self):
+ prelude = self._prelude
+ payload_bytes = self._data[prelude.headers_end : prelude.payload_end]
+ return payload_bytes
+
+ def _parse_message_crc(self):
+ prelude = self._prelude
+ crc_bytes = self._data[prelude.payload_end : prelude.total_length]
+ message_crc, _ = DecodeUtils.unpack_uint32(crc_bytes)
+ return message_crc
+
+ def _parse_message_bytes(self):
+ # The minus 4 includes the prelude crc to the bytes to be checked
+ message_bytes = self._data[
+ _PRELUDE_LENGTH - 4 : self._prelude.payload_end
+ ]
+ return message_bytes
+
+ def _validate_message_crc(self):
+ message_crc = self._parse_message_crc()
+ message_bytes = self._parse_message_bytes()
+ _validate_checksum(message_bytes, message_crc, crc=self._prelude.crc)
+ return message_crc
+
+ def _parse_message(self):
+ crc = self._validate_message_crc()
+ headers = self._parse_headers()
+ payload = self._parse_payload()
+ message = EventStreamMessage(self._prelude, headers, payload, crc)
+ self._prepare_for_next_message()
+ return message
+
+ def _prepare_for_next_message(self):
+ # Advance the data and reset the current prelude
+ self._data = self._data[self._prelude.total_length :]
+ self._prelude = None
+
+ def next(self):
+ """Provides the next available message parsed from the stream
+
+ :rtype: EventStreamMessage
+ :returns: The next event stream message
+ """
+ if len(self._data) < _PRELUDE_LENGTH:
+ raise StopIteration()
+
+ if self._prelude is None:
+ self._prelude = self._parse_prelude()
+
+ if len(self._data) < self._prelude.total_length:
+ raise StopIteration()
+
+ return self._parse_message()
+
+ def __next__(self):
+ return self.next()
+
+ def __iter__(self):
+ return self
+
+
+class EventStream:
+ """Wrapper class for an event stream body.
+
+ This wraps the underlying streaming body, parsing it for individual events
+ and yielding them as they come available through the iterator interface.
+
+ The following example uses the S3 select API to get structured data out of
+ an object stored in S3 using an event stream.
+
+ **Example:**
+ ::
+ from botocore.session import Session
+
+ s3 = Session().create_client('s3')
+ response = s3.select_object_content(
+ Bucket='bucketname',
+ Key='keyname',
+ ExpressionType='SQL',
+ RequestProgress={'Enabled': True},
+ Expression="SELECT * FROM S3Object s",
+ InputSerialization={'CSV': {}},
+ OutputSerialization={'CSV': {}},
+ )
+ # This is the event stream in the response
+ event_stream = response['Payload']
+ end_event_received = False
+ with open('output', 'wb') as f:
+ # Iterate over events in the event stream as they come
+ for event in event_stream:
+ # If we received a records event, write the data to a file
+ if 'Records' in event:
+ data = event['Records']['Payload']
+ f.write(data)
+ # If we received a progress event, print the details
+ elif 'Progress' in event:
+ print(event['Progress']['Details'])
+ # End event indicates that the request finished successfully
+ elif 'End' in event:
+ print('Result is complete')
+ end_event_received = True
+ if not end_event_received:
+ raise Exception("End event not received, request incomplete.")
+ """
+
+ def __init__(self, raw_stream, output_shape, parser, operation_name):
+ self._raw_stream = raw_stream
+ self._output_shape = output_shape
+ self._operation_name = operation_name
+ self._parser = parser
+ self._event_generator = self._create_raw_event_generator()
+
+ def __iter__(self):
+ for event in self._event_generator:
+ parsed_event = self._parse_event(event)
+ if parsed_event:
+ yield parsed_event
+
+ def _create_raw_event_generator(self):
+ event_stream_buffer = EventStreamBuffer()
+ for chunk in self._raw_stream.stream():
+ event_stream_buffer.add_data(chunk)
+ yield from event_stream_buffer
+
+ def _parse_event(self, event):
+ response_dict = event.to_response_dict()
+ parsed_response = self._parser.parse(response_dict, self._output_shape)
+ if response_dict['status_code'] == 200:
+ return parsed_response
+ else:
+ raise EventStreamError(parsed_response, self._operation_name)
+
+ def get_initial_response(self):
+ try:
+ initial_event = next(self._event_generator)
+ event_type = initial_event.headers.get(':event-type')
+ if event_type == 'initial-response':
+ return initial_event
+ except StopIteration:
+ pass
+ raise NoInitialResponseError()
+
+ def close(self):
+ """Closes the underlying streaming body."""
+ self._raw_stream.close()
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/exceptions.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/exceptions.py
new file mode 100644
index 0000000000..1c480abbf8
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/exceptions.py
@@ -0,0 +1,816 @@
+# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+from botocore.vendored import requests
+from botocore.vendored.requests.packages import urllib3
+
+
+def _exception_from_packed_args(exception_cls, args=None, kwargs=None):
+ # This is helpful for reducing Exceptions that only accept kwargs as
+ # only positional arguments can be provided for __reduce__
+ # Ideally, this would also be a class method on the BotoCoreError
+ # but instance methods cannot be pickled.
+ if args is None:
+ args = ()
+ if kwargs is None:
+ kwargs = {}
+ return exception_cls(*args, **kwargs)
+
+
+class BotoCoreError(Exception):
+ """
+ The base exception class for BotoCore exceptions.
+
+ :ivar msg: The descriptive message associated with the error.
+ """
+
+ fmt = 'An unspecified error occurred'
+
+ def __init__(self, **kwargs):
+ msg = self.fmt.format(**kwargs)
+ Exception.__init__(self, msg)
+ self.kwargs = kwargs
+
+ def __reduce__(self):
+ return _exception_from_packed_args, (self.__class__, None, self.kwargs)
+
+
+class DataNotFoundError(BotoCoreError):
+ """
+ The data associated with a particular path could not be loaded.
+
+ :ivar data_path: The data path that the user attempted to load.
+ """
+
+ fmt = 'Unable to load data for: {data_path}'
+
+
+class UnknownServiceError(DataNotFoundError):
+ """Raised when trying to load data for an unknown service.
+
+ :ivar service_name: The name of the unknown service.
+
+ """
+
+ fmt = (
+ "Unknown service: '{service_name}'. Valid service names are: "
+ "{known_service_names}"
+ )
+
+
+class UnknownRegionError(BotoCoreError):
+ """Raised when trying to load data for an unknown region.
+
+ :ivar region_name: The name of the unknown region.
+
+ """
+
+ fmt = "Unknown region: '{region_name}'. {error_msg}"
+
+
+class ApiVersionNotFoundError(BotoCoreError):
+ """
+ The data associated with either the API version or a compatible one
+ could not be loaded.
+
+ :ivar data_path: The data path that the user attempted to load.
+ :ivar api_version: The API version that the user attempted to load.
+ """
+
+ fmt = 'Unable to load data {data_path} for: {api_version}'
+
+
+class HTTPClientError(BotoCoreError):
+ fmt = 'An HTTP Client raised an unhandled exception: {error}'
+
+ def __init__(self, request=None, response=None, **kwargs):
+ self.request = request
+ self.response = response
+ super().__init__(**kwargs)
+
+ def __reduce__(self):
+ return _exception_from_packed_args, (
+ self.__class__,
+ (self.request, self.response),
+ self.kwargs,
+ )
+
+
+class ConnectionError(BotoCoreError):
+ fmt = 'An HTTP Client failed to establish a connection: {error}'
+
+
+class InvalidIMDSEndpointError(BotoCoreError):
+ fmt = 'Invalid endpoint EC2 Instance Metadata endpoint: {endpoint}'
+
+
+class InvalidIMDSEndpointModeError(BotoCoreError):
+ fmt = (
+ 'Invalid EC2 Instance Metadata endpoint mode: {mode}'
+ ' Valid endpoint modes (case-insensitive): {valid_modes}.'
+ )
+
+
+class EndpointConnectionError(ConnectionError):
+ fmt = 'Could not connect to the endpoint URL: "{endpoint_url}"'
+
+
+class SSLError(ConnectionError, requests.exceptions.SSLError):
+ fmt = 'SSL validation failed for {endpoint_url} {error}'
+
+
+class ConnectionClosedError(HTTPClientError):
+ fmt = (
+ 'Connection was closed before we received a valid response '
+ 'from endpoint URL: "{endpoint_url}".'
+ )
+
+
+class ReadTimeoutError(
+ HTTPClientError,
+ requests.exceptions.ReadTimeout,
+ urllib3.exceptions.ReadTimeoutError,
+):
+ fmt = 'Read timeout on endpoint URL: "{endpoint_url}"'
+
+
+class ConnectTimeoutError(ConnectionError, requests.exceptions.ConnectTimeout):
+ fmt = 'Connect timeout on endpoint URL: "{endpoint_url}"'
+
+
+class ProxyConnectionError(ConnectionError, requests.exceptions.ProxyError):
+ fmt = 'Failed to connect to proxy URL: "{proxy_url}"'
+
+
+class ResponseStreamingError(HTTPClientError):
+ fmt = 'An error occurred while reading from response stream: {error}'
+
+
+class NoCredentialsError(BotoCoreError):
+ """
+ No credentials could be found.
+ """
+
+ fmt = 'Unable to locate credentials'
+
+
+class NoAuthTokenError(BotoCoreError):
+ """
+ No authorization token could be found.
+ """
+
+ fmt = 'Unable to locate authorization token'
+
+
+class TokenRetrievalError(BotoCoreError):
+ """
+ Error attempting to retrieve a token from a remote source.
+
+ :ivar provider: The name of the token provider.
+ :ivar error_msg: The msg explaining why the token could not be retrieved.
+
+ """
+
+ fmt = 'Error when retrieving token from {provider}: {error_msg}'
+
+
+class PartialCredentialsError(BotoCoreError):
+ """
+ Only partial credentials were found.
+
+ :ivar cred_var: The missing credential variable name.
+
+ """
+
+ fmt = 'Partial credentials found in {provider}, missing: {cred_var}'
+
+
+class CredentialRetrievalError(BotoCoreError):
+ """
+ Error attempting to retrieve credentials from a remote source.
+
+ :ivar provider: The name of the credential provider.
+ :ivar error_msg: The msg explaining why credentials could not be
+ retrieved.
+
+ """
+
+ fmt = 'Error when retrieving credentials from {provider}: {error_msg}'
+
+
+class UnknownSignatureVersionError(BotoCoreError):
+ """
+ Requested Signature Version is not known.
+
+ :ivar signature_version: The name of the requested signature version.
+ """
+
+ fmt = 'Unknown Signature Version: {signature_version}.'
+
+
+class ServiceNotInRegionError(BotoCoreError):
+ """
+ The service is not available in requested region.
+
+ :ivar service_name: The name of the service.
+ :ivar region_name: The name of the region.
+ """
+
+ fmt = 'Service {service_name} not available in region {region_name}'
+
+
+class BaseEndpointResolverError(BotoCoreError):
+ """Base error for endpoint resolving errors.
+
+ Should never be raised directly, but clients can catch
+ this exception if they want to generically handle any errors
+ during the endpoint resolution process.
+
+ """
+
+
+class NoRegionError(BaseEndpointResolverError):
+ """No region was specified."""
+
+ fmt = 'You must specify a region.'
+
+
+class EndpointVariantError(BaseEndpointResolverError):
+ """
+ Could not construct modeled endpoint variant.
+
+ :ivar error_msg: The message explaining why the modeled endpoint variant
+ is unable to be constructed.
+
+ """
+
+ fmt = (
+ 'Unable to construct a modeled endpoint with the following '
+ 'variant(s) {tags}: '
+ )
+
+
+class UnknownEndpointError(BaseEndpointResolverError, ValueError):
+ """
+ Could not construct an endpoint.
+
+ :ivar service_name: The name of the service.
+ :ivar region_name: The name of the region.
+ """
+
+ fmt = (
+ 'Unable to construct an endpoint for '
+ '{service_name} in region {region_name}'
+ )
+
+
+class UnknownFIPSEndpointError(BaseEndpointResolverError):
+ """
+ Could not construct a FIPS endpoint.
+
+ :ivar service_name: The name of the service.
+ :ivar region_name: The name of the region.
+ """
+
+ fmt = (
+ 'The provided FIPS pseudo-region "{region_name}" is not known for '
+ 'the service "{service_name}". A FIPS compliant endpoint cannot be '
+ 'constructed.'
+ )
+
+
+class ProfileNotFound(BotoCoreError):
+ """
+ The specified configuration profile was not found in the
+ configuration file.
+
+ :ivar profile: The name of the profile the user attempted to load.
+ """
+
+ fmt = 'The config profile ({profile}) could not be found'
+
+
+class ConfigParseError(BotoCoreError):
+ """
+ The configuration file could not be parsed.
+
+ :ivar path: The path to the configuration file.
+ """
+
+ fmt = 'Unable to parse config file: {path}'
+
+
+class ConfigNotFound(BotoCoreError):
+ """
+ The specified configuration file could not be found.
+
+ :ivar path: The path to the configuration file.
+ """
+
+ fmt = 'The specified config file ({path}) could not be found.'
+
+
+class MissingParametersError(BotoCoreError):
+ """
+ One or more required parameters were not supplied.
+
+ :ivar object: The object that has missing parameters.
+ This can be an operation or a parameter (in the
+ case of inner params). The str() of this object
+ will be used so it doesn't need to implement anything
+ other than str().
+ :ivar missing: The names of the missing parameters.
+ """
+
+ fmt = (
+ 'The following required parameters are missing for '
+ '{object_name}: {missing}'
+ )
+
+
+class ValidationError(BotoCoreError):
+ """
+ An exception occurred validating parameters.
+
+ Subclasses must accept a ``value`` and ``param``
+ argument in their ``__init__``.
+
+ :ivar value: The value that was being validated.
+ :ivar param: The parameter that failed validation.
+ :ivar type_name: The name of the underlying type.
+ """
+
+ fmt = "Invalid value ('{value}') for param {param} " "of type {type_name} "
+
+
+class ParamValidationError(BotoCoreError):
+ fmt = 'Parameter validation failed:\n{report}'
+
+
+# These exceptions subclass from ValidationError so that code
+# can just 'except ValidationError' to catch any possibly validation
+# error.
+class UnknownKeyError(ValidationError):
+ """
+ Unknown key in a struct parameter.
+
+ :ivar value: The value that was being checked.
+ :ivar param: The name of the parameter.
+ :ivar choices: The valid choices the value can be.
+ """
+
+ fmt = (
+ "Unknown key '{value}' for param '{param}'. Must be one "
+ "of: {choices}"
+ )
+
+
+class RangeError(ValidationError):
+ """
+ A parameter value was out of the valid range.
+
+ :ivar value: The value that was being checked.
+ :ivar param: The parameter that failed validation.
+ :ivar min_value: The specified minimum value.
+ :ivar max_value: The specified maximum value.
+ """
+
+ fmt = (
+ 'Value out of range for param {param}: '
+ '{min_value} <= {value} <= {max_value}'
+ )
+
+
+class UnknownParameterError(ValidationError):
+ """
+ Unknown top level parameter.
+
+ :ivar name: The name of the unknown parameter.
+ :ivar operation: The name of the operation.
+ :ivar choices: The valid choices the parameter name can be.
+ """
+
+ fmt = (
+ "Unknown parameter '{name}' for operation {operation}. Must be one "
+ "of: {choices}"
+ )
+
+
+class InvalidRegionError(ValidationError, ValueError):
+ """
+ Invalid region_name provided to client or resource.
+
+ :ivar region_name: region_name that was being validated.
+ """
+
+ fmt = "Provided region_name '{region_name}' doesn't match a supported format."
+
+
+class AliasConflictParameterError(ValidationError):
+ """
+ Error when an alias is provided for a parameter as well as the original.
+
+ :ivar original: The name of the original parameter.
+ :ivar alias: The name of the alias
+ :ivar operation: The name of the operation.
+ """
+
+ fmt = (
+ "Parameter '{original}' and its alias '{alias}' were provided "
+ "for operation {operation}. Only one of them may be used."
+ )
+
+
+class UnknownServiceStyle(BotoCoreError):
+ """
+ Unknown style of service invocation.
+
+ :ivar service_style: The style requested.
+ """
+
+ fmt = 'The service style ({service_style}) is not understood.'
+
+
+class PaginationError(BotoCoreError):
+ fmt = 'Error during pagination: {message}'
+
+
+class OperationNotPageableError(BotoCoreError):
+ fmt = 'Operation cannot be paginated: {operation_name}'
+
+
+class ChecksumError(BotoCoreError):
+ """The expected checksum did not match the calculated checksum."""
+
+ fmt = (
+ 'Checksum {checksum_type} failed, expected checksum '
+ '{expected_checksum} did not match calculated checksum '
+ '{actual_checksum}.'
+ )
+
+
+class UnseekableStreamError(BotoCoreError):
+ """Need to seek a stream, but stream does not support seeking."""
+
+ fmt = (
+ 'Need to rewind the stream {stream_object}, but stream '
+ 'is not seekable.'
+ )
+
+
+class WaiterError(BotoCoreError):
+ """Waiter failed to reach desired state."""
+
+ fmt = 'Waiter {name} failed: {reason}'
+
+ def __init__(self, name, reason, last_response):
+ super().__init__(name=name, reason=reason)
+ self.last_response = last_response
+
+
+class IncompleteReadError(BotoCoreError):
+ """HTTP response did not return expected number of bytes."""
+
+ fmt = (
+ '{actual_bytes} read, but total bytes ' 'expected is {expected_bytes}.'
+ )
+
+
+class InvalidExpressionError(BotoCoreError):
+ """Expression is either invalid or too complex."""
+
+ fmt = 'Invalid expression {expression}: Only dotted lookups are supported.'
+
+
+class UnknownCredentialError(BotoCoreError):
+ """Tried to insert before/after an unregistered credential type."""
+
+ fmt = 'Credential named {name} not found.'
+
+
+class WaiterConfigError(BotoCoreError):
+ """Error when processing waiter configuration."""
+
+ fmt = 'Error processing waiter config: {error_msg}'
+
+
+class UnknownClientMethodError(BotoCoreError):
+ """Error when trying to access a method on a client that does not exist."""
+
+ fmt = 'Client does not have method: {method_name}'
+
+
+class UnsupportedSignatureVersionError(BotoCoreError):
+ """Error when trying to use an unsupported Signature Version."""
+
+ fmt = 'Signature version is not supported: {signature_version}'
+
+
+class ClientError(Exception):
+ MSG_TEMPLATE = (
+ 'An error occurred ({error_code}) when calling the {operation_name} '
+ 'operation{retry_info}: {error_message}'
+ )
+
+ def __init__(self, error_response, operation_name):
+ retry_info = self._get_retry_info(error_response)
+ error = error_response.get('Error', {})
+ msg = self.MSG_TEMPLATE.format(
+ error_code=error.get('Code', 'Unknown'),
+ error_message=error.get('Message', 'Unknown'),
+ operation_name=operation_name,
+ retry_info=retry_info,
+ )
+ super().__init__(msg)
+ self.response = error_response
+ self.operation_name = operation_name
+
+ def _get_retry_info(self, response):
+ retry_info = ''
+ if 'ResponseMetadata' in response:
+ metadata = response['ResponseMetadata']
+ if metadata.get('MaxAttemptsReached', False):
+ if 'RetryAttempts' in metadata:
+ retry_info = (
+ f" (reached max retries: {metadata['RetryAttempts']})"
+ )
+ return retry_info
+
+ def __reduce__(self):
+ # Subclasses of ClientError's are dynamically generated and
+ # cannot be pickled unless they are attributes of a
+ # module. So at the very least return a ClientError back.
+ return ClientError, (self.response, self.operation_name)
+
+
+class EventStreamError(ClientError):
+ pass
+
+
+class UnsupportedTLSVersionWarning(Warning):
+ """Warn when an openssl version that uses TLS 1.2 is required"""
+
+ pass
+
+
+class ImminentRemovalWarning(Warning):
+ pass
+
+
+class InvalidDNSNameError(BotoCoreError):
+ """Error when virtual host path is forced on a non-DNS compatible bucket"""
+
+ fmt = (
+ 'Bucket named {bucket_name} is not DNS compatible. Virtual '
+ 'hosted-style addressing cannot be used. The addressing style '
+ 'can be configured by removing the addressing_style value '
+ 'or setting that value to \'path\' or \'auto\' in the AWS Config '
+ 'file or in the botocore.client.Config object.'
+ )
+
+
+class InvalidS3AddressingStyleError(BotoCoreError):
+ """Error when an invalid path style is specified"""
+
+ fmt = (
+ 'S3 addressing style {s3_addressing_style} is invalid. Valid options '
+ 'are: \'auto\', \'virtual\', and \'path\''
+ )
+
+
+class UnsupportedS3ArnError(BotoCoreError):
+ """Error when S3 ARN provided to Bucket parameter is not supported"""
+
+ fmt = (
+ 'S3 ARN {arn} provided to "Bucket" parameter is invalid. Only '
+ 'ARNs for S3 access-points are supported.'
+ )
+
+
+class UnsupportedS3ControlArnError(BotoCoreError):
+ """Error when S3 ARN provided to S3 control parameter is not supported"""
+
+ fmt = 'S3 ARN "{arn}" provided is invalid for this operation. {msg}'
+
+
+class InvalidHostLabelError(BotoCoreError):
+ """Error when an invalid host label would be bound to an endpoint"""
+
+ fmt = (
+ 'Invalid host label to be bound to the hostname of the endpoint: '
+ '"{label}".'
+ )
+
+
+class UnsupportedOutpostResourceError(BotoCoreError):
+ """Error when S3 Outpost ARN provided to Bucket parameter is incomplete"""
+
+ fmt = (
+ 'S3 Outpost ARN resource "{resource_name}" provided to "Bucket" '
+ 'parameter is invalid. Only ARNs for S3 Outpost arns with an '
+ 'access-point sub-resource are supported.'
+ )
+
+
+class UnsupportedS3ConfigurationError(BotoCoreError):
+ """Error when an unsupported configuration is used with access-points"""
+
+ fmt = 'Unsupported configuration when using S3: {msg}'
+
+
+class UnsupportedS3AccesspointConfigurationError(BotoCoreError):
+ """Error when an unsupported configuration is used with access-points"""
+
+ fmt = 'Unsupported configuration when using S3 access-points: {msg}'
+
+
+class InvalidEndpointDiscoveryConfigurationError(BotoCoreError):
+ """Error when invalid value supplied for endpoint_discovery_enabled"""
+
+ fmt = (
+ 'Unsupported configuration value for endpoint_discovery_enabled. '
+ 'Expected one of ("true", "false", "auto") but got {config_value}.'
+ )
+
+
+class UnsupportedS3ControlConfigurationError(BotoCoreError):
+ """Error when an unsupported configuration is used with S3 Control"""
+
+ fmt = 'Unsupported configuration when using S3 Control: {msg}'
+
+
+class InvalidRetryConfigurationError(BotoCoreError):
+ """Error when invalid retry configuration is specified"""
+
+ fmt = (
+ 'Cannot provide retry configuration for "{retry_config_option}". '
+ 'Valid retry configuration options are: {valid_options}'
+ )
+
+
+class InvalidMaxRetryAttemptsError(InvalidRetryConfigurationError):
+ """Error when invalid retry configuration is specified"""
+
+ fmt = (
+ 'Value provided to "max_attempts": {provided_max_attempts} must '
+ 'be an integer greater than or equal to {min_value}.'
+ )
+
+
+class InvalidRetryModeError(InvalidRetryConfigurationError):
+ """Error when invalid retry mode configuration is specified"""
+
+ fmt = (
+ 'Invalid value provided to "mode": "{provided_retry_mode}" must '
+ 'be one of: {valid_modes}'
+ )
+
+
+class InvalidS3UsEast1RegionalEndpointConfigError(BotoCoreError):
+ """Error for invalid s3 us-east-1 regional endpoints configuration"""
+
+ fmt = (
+ 'S3 us-east-1 regional endpoint option '
+ '{s3_us_east_1_regional_endpoint_config} is '
+ 'invalid. Valid options are: "legacy", "regional"'
+ )
+
+
+class InvalidSTSRegionalEndpointsConfigError(BotoCoreError):
+ """Error when invalid sts regional endpoints configuration is specified"""
+
+ fmt = (
+ 'STS regional endpoints option {sts_regional_endpoints_config} is '
+ 'invalid. Valid options are: "legacy", "regional"'
+ )
+
+
+class StubResponseError(BotoCoreError):
+ fmt = (
+ 'Error getting response stub for operation {operation_name}: {reason}'
+ )
+
+
+class StubAssertionError(StubResponseError, AssertionError):
+ pass
+
+
+class UnStubbedResponseError(StubResponseError):
+ pass
+
+
+class InvalidConfigError(BotoCoreError):
+ fmt = '{error_msg}'
+
+
+class InfiniteLoopConfigError(InvalidConfigError):
+ fmt = (
+ 'Infinite loop in credential configuration detected. Attempting to '
+ 'load from profile {source_profile} which has already been visited. '
+ 'Visited profiles: {visited_profiles}'
+ )
+
+
+class RefreshWithMFAUnsupportedError(BotoCoreError):
+ fmt = 'Cannot refresh credentials: MFA token required.'
+
+
+class MD5UnavailableError(BotoCoreError):
+ fmt = "This system does not support MD5 generation."
+
+
+class MissingDependencyException(BotoCoreError):
+ fmt = "Missing Dependency: {msg}"
+
+
+class MetadataRetrievalError(BotoCoreError):
+ fmt = "Error retrieving metadata: {error_msg}"
+
+
+class UndefinedModelAttributeError(Exception):
+ pass
+
+
+class MissingServiceIdError(UndefinedModelAttributeError):
+ fmt = (
+ "The model being used for the service {service_name} is missing the "
+ "serviceId metadata property, which is required."
+ )
+
+ def __init__(self, **kwargs):
+ msg = self.fmt.format(**kwargs)
+ Exception.__init__(self, msg)
+ self.kwargs = kwargs
+
+
+class SSOError(BotoCoreError):
+ fmt = (
+ "An unspecified error happened when resolving AWS credentials or an "
+ "access token from SSO."
+ )
+
+
+class SSOTokenLoadError(SSOError):
+ fmt = "Error loading SSO Token: {error_msg}"
+
+
+class UnauthorizedSSOTokenError(SSOError):
+ fmt = (
+ "The SSO session associated with this profile has expired or is "
+ "otherwise invalid. To refresh this SSO session run aws sso login "
+ "with the corresponding profile."
+ )
+
+
+class CapacityNotAvailableError(BotoCoreError):
+ fmt = 'Insufficient request capacity available.'
+
+
+class InvalidProxiesConfigError(BotoCoreError):
+ fmt = 'Invalid configuration value(s) provided for proxies_config.'
+
+
+class InvalidDefaultsMode(BotoCoreError):
+ fmt = (
+ 'Client configured with invalid defaults mode: {mode}. '
+ 'Valid defaults modes include: {valid_modes}.'
+ )
+
+
+class AwsChunkedWrapperError(BotoCoreError):
+ fmt = '{error_msg}'
+
+
+class FlexibleChecksumError(BotoCoreError):
+ fmt = '{error_msg}'
+
+
+class InvalidEndpointConfigurationError(BotoCoreError):
+ fmt = 'Invalid endpoint configuration: {msg}'
+
+
+class EndpointProviderError(BotoCoreError):
+ """Base error for the EndpointProvider class"""
+
+ fmt = '{msg}'
+
+
+class EndpointResolutionError(EndpointProviderError):
+ """Error when input parameters resolve to an error rule"""
+
+ fmt = '{msg}'
+
+
+class UnknownEndpointResolutionBuiltInName(EndpointProviderError):
+ fmt = 'Unknown builtin variable name: {name}'
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/handlers.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/handlers.py
new file mode 100644
index 0000000000..36828603ca
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/handlers.py
@@ -0,0 +1,1411 @@
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+"""Builtin event handlers.
+
+This module contains builtin handlers for events emitted by botocore.
+"""
+
+import base64
+import copy
+import logging
+import os
+import re
+import uuid
+import warnings
+from io import BytesIO
+
+import botocore
+import botocore.auth
+from botocore import utils
+from botocore.compat import (
+ ETree,
+ OrderedDict,
+ XMLParseError,
+ ensure_bytes,
+ get_md5,
+ json,
+ quote,
+ unquote,
+ unquote_str,
+ urlsplit,
+ urlunsplit,
+)
+from botocore.docs.utils import (
+ AppendParamDocumentation,
+ AutoPopulatedParam,
+ HideParamFromOperations,
+)
+from botocore.endpoint_provider import VALID_HOST_LABEL_RE
+from botocore.exceptions import (
+ AliasConflictParameterError,
+ ParamValidationError,
+ UnsupportedTLSVersionWarning,
+)
+from botocore.regions import EndpointResolverBuiltins
+from botocore.signers import (
+ add_generate_db_auth_token,
+ add_generate_presigned_post,
+ add_generate_presigned_url,
+)
+from botocore.utils import (
+ SAFE_CHARS,
+ ArnParser,
+ conditionally_calculate_md5,
+ percent_encode,
+ switch_host_with_param,
+)
+
+# Keep these imported. There's pre-existing code that uses them.
+from botocore import retryhandler # noqa
+from botocore import translate # noqa
+from botocore.compat import MD5_AVAILABLE # noqa
+from botocore.exceptions import MissingServiceIdError # noqa
+from botocore.utils import hyphenize_service_id # noqa
+from botocore.utils import is_global_accesspoint # noqa
+from botocore.utils import SERVICE_NAME_ALIASES # noqa
+
+
+logger = logging.getLogger(__name__)
+
+REGISTER_FIRST = object()
+REGISTER_LAST = object()
+# From the S3 docs:
+# The rules for bucket names in the US Standard region allow bucket names
+# to be as long as 255 characters, and bucket names can contain any
+# combination of uppercase letters, lowercase letters, numbers, periods
+# (.), hyphens (-), and underscores (_).
+VALID_BUCKET = re.compile(r'^[a-zA-Z0-9.\-_]{1,255}$')
+_ACCESSPOINT_ARN = (
+ r'^arn:(aws).*:(s3|s3-object-lambda):[a-z\-0-9]*:[0-9]{12}:accesspoint[/:]'
+ r'[a-zA-Z0-9\-.]{1,63}$'
+)
+_OUTPOST_ARN = (
+ r'^arn:(aws).*:s3-outposts:[a-z\-0-9]+:[0-9]{12}:outpost[/:]'
+ r'[a-zA-Z0-9\-]{1,63}[/:]accesspoint[/:][a-zA-Z0-9\-]{1,63}$'
+)
+VALID_S3_ARN = re.compile('|'.join([_ACCESSPOINT_ARN, _OUTPOST_ARN]))
+# signing names used for the services s3 and s3-control, for example in
+# botocore/data/s3/2006-03-01/endpoints-rule-set-1.json
+S3_SIGNING_NAMES = ('s3', 's3-outposts', 's3-object-lambda')
+VERSION_ID_SUFFIX = re.compile(r'\?versionId=[^\s]+$')
+
+
+def handle_service_name_alias(service_name, **kwargs):
+ return SERVICE_NAME_ALIASES.get(service_name, service_name)
+
+
+def add_recursion_detection_header(params, **kwargs):
+ has_lambda_name = 'AWS_LAMBDA_FUNCTION_NAME' in os.environ
+ trace_id = os.environ.get('_X_AMZN_TRACE_ID')
+ if has_lambda_name and trace_id:
+ headers = params['headers']
+ if 'X-Amzn-Trace-Id' not in headers:
+ headers['X-Amzn-Trace-Id'] = quote(trace_id, safe='-=;:+&[]{}"\',')
+
+
+def escape_xml_payload(params, **kwargs):
+ # Replace \r and \n with the escaped sequence over the whole XML document
+ # to avoid linebreak normalization modifying customer input when the
+ # document is parsed. Ideally, we would do this in ElementTree.tostring,
+ # but it doesn't allow us to override entity escaping for text fields. For
+ # this operation \r and \n can only appear in the XML document if they were
+ # passed as part of the customer input.
+ body = params['body']
+ if b'\r' in body:
+ body = body.replace(b'\r', b'
')
+ if b'\n' in body:
+ body = body.replace(b'\n', b'
')
+
+ params['body'] = body
+
+
+def check_for_200_error(response, **kwargs):
+ # From: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html
+ # There are two opportunities for a copy request to return an error. One
+ # can occur when Amazon S3 receives the copy request and the other can
+ # occur while Amazon S3 is copying the files. If the error occurs before
+ # the copy operation starts, you receive a standard Amazon S3 error. If the
+ # error occurs during the copy operation, the error response is embedded in
+ # the 200 OK response. This means that a 200 OK response can contain either
+ # a success or an error. Make sure to design your application to parse the
+ # contents of the response and handle it appropriately.
+ #
+ # So this handler checks for this case. Even though the server sends a
+ # 200 response, conceptually this should be handled exactly like a
+ # 500 response (with respect to raising exceptions, retries, etc.)
+ # We're connected *before* all the other retry logic handlers, so as long
+ # as we switch the error code to 500, we'll retry the error as expected.
+ if response is None:
+ # A None response can happen if an exception is raised while
+ # trying to retrieve the response. See Endpoint._get_response().
+ return
+ http_response, parsed = response
+ if _looks_like_special_case_error(http_response):
+ logger.debug(
+ "Error found for response with 200 status code, "
+ "errors: %s, changing status code to "
+ "500.",
+ parsed,
+ )
+ http_response.status_code = 500
+
+
+def _looks_like_special_case_error(http_response):
+ if http_response.status_code == 200:
+ try:
+ parser = ETree.XMLParser(
+ target=ETree.TreeBuilder(), encoding='utf-8'
+ )
+ parser.feed(http_response.content)
+ root = parser.close()
+ except XMLParseError:
+ # In cases of network disruptions, we may end up with a partial
+ # streamed response from S3. We need to treat these cases as
+ # 500 Service Errors and try again.
+ return True
+ if root.tag == 'Error':
+ return True
+ return False
+
+
+def set_operation_specific_signer(context, signing_name, **kwargs):
+ """Choose the operation-specific signer.
+
+ Individual operations may have a different auth type than the service as a
+ whole. This will most often manifest as operations that should not be
+ authenticated at all, but can include other auth modes such as sigv4
+ without body signing.
+ """
+ auth_type = context.get('auth_type')
+
+ # Auth type will be None if the operation doesn't have a configured auth
+ # type.
+ if not auth_type:
+ return
+
+ # Auth type will be the string value 'none' if the operation should not
+ # be signed at all.
+ if auth_type == 'none':
+ return botocore.UNSIGNED
+
+ if auth_type == 'bearer':
+ return 'bearer'
+
+ if auth_type.startswith('v4'):
+ if auth_type == 'v4a':
+ # If sigv4a is chosen, we must add additional signing config for
+ # global signature.
+ signing = {'region': '*', 'signing_name': signing_name}
+ if 'signing' in context:
+ context['signing'].update(signing)
+ else:
+ context['signing'] = signing
+ signature_version = 'v4a'
+ else:
+ signature_version = 'v4'
+
+ # If the operation needs an unsigned body, we set additional context
+ # allowing the signer to be aware of this.
+ if auth_type == 'v4-unsigned-body':
+ context['payload_signing_enabled'] = False
+
+ # Signing names used by s3 and s3-control use customized signers "s3v4"
+ # and "s3v4a".
+ if signing_name in S3_SIGNING_NAMES:
+ signature_version = f's3{signature_version}'
+
+ return signature_version
+
+
+def decode_console_output(parsed, **kwargs):
+ if 'Output' in parsed:
+ try:
+ # We're using 'replace' for errors because it is
+ # possible that console output contains non string
+ # chars we can't utf-8 decode.
+ value = base64.b64decode(
+ bytes(parsed['Output'], 'latin-1')
+ ).decode('utf-8', 'replace')
+ parsed['Output'] = value
+ except (ValueError, TypeError, AttributeError):
+ logger.debug('Error decoding base64', exc_info=True)
+
+
+def generate_idempotent_uuid(params, model, **kwargs):
+ for name in model.idempotent_members:
+ if name not in params:
+ params[name] = str(uuid.uuid4())
+ logger.debug(
+ "injecting idempotency token (%s) into param '%s'."
+ % (params[name], name)
+ )
+
+
+def decode_quoted_jsondoc(value):
+ try:
+ value = json.loads(unquote(value))
+ except (ValueError, TypeError):
+ logger.debug('Error loading quoted JSON', exc_info=True)
+ return value
+
+
+def json_decode_template_body(parsed, **kwargs):
+ if 'TemplateBody' in parsed:
+ try:
+ value = json.loads(
+ parsed['TemplateBody'], object_pairs_hook=OrderedDict
+ )
+ parsed['TemplateBody'] = value
+ except (ValueError, TypeError):
+ logger.debug('error loading JSON', exc_info=True)
+
+
+def validate_bucket_name(params, **kwargs):
+ if 'Bucket' not in params:
+ return
+ bucket = params['Bucket']
+ if not VALID_BUCKET.search(bucket) and not VALID_S3_ARN.search(bucket):
+ error_msg = (
+ f'Invalid bucket name "{bucket}": Bucket name must match '
+ f'the regex "{VALID_BUCKET.pattern}" or be an ARN matching '
+ f'the regex "{VALID_S3_ARN.pattern}"'
+ )
+ raise ParamValidationError(report=error_msg)
+
+
+def sse_md5(params, **kwargs):
+ """
+ S3 server-side encryption requires the encryption key to be sent to the
+ server base64 encoded, as well as a base64-encoded MD5 hash of the
+ encryption key. This handler does both if the MD5 has not been set by
+ the caller.
+ """
+ _sse_md5(params, 'SSECustomer')
+
+
+def copy_source_sse_md5(params, **kwargs):
+ """
+ S3 server-side encryption requires the encryption key to be sent to the
+ server base64 encoded, as well as a base64-encoded MD5 hash of the
+ encryption key. This handler does both if the MD5 has not been set by
+ the caller specifically if the parameter is for the copy-source sse-c key.
+ """
+ _sse_md5(params, 'CopySourceSSECustomer')
+
+
+def _sse_md5(params, sse_member_prefix='SSECustomer'):
+ if not _needs_s3_sse_customization(params, sse_member_prefix):
+ return
+
+ sse_key_member = sse_member_prefix + 'Key'
+ sse_md5_member = sse_member_prefix + 'KeyMD5'
+ key_as_bytes = params[sse_key_member]
+ if isinstance(key_as_bytes, str):
+ key_as_bytes = key_as_bytes.encode('utf-8')
+ key_md5_str = base64.b64encode(get_md5(key_as_bytes).digest()).decode(
+ 'utf-8'
+ )
+ key_b64_encoded = base64.b64encode(key_as_bytes).decode('utf-8')
+ params[sse_key_member] = key_b64_encoded
+ params[sse_md5_member] = key_md5_str
+
+
+def _needs_s3_sse_customization(params, sse_member_prefix):
+ return (
+ params.get(sse_member_prefix + 'Key') is not None
+ and sse_member_prefix + 'KeyMD5' not in params
+ )
+
+
+def disable_signing(**kwargs):
+ """
+ This handler disables request signing by setting the signer
+ name to a special sentinel value.
+ """
+ return botocore.UNSIGNED
+
+
+def add_expect_header(model, params, **kwargs):
+ if model.http.get('method', '') not in ['PUT', 'POST']:
+ return
+ if 'body' in params:
+ body = params['body']
+ if hasattr(body, 'read'):
+ # Any file like object will use an expect 100-continue
+ # header regardless of size.
+ logger.debug("Adding expect 100 continue header to request.")
+ params['headers']['Expect'] = '100-continue'
+
+
+class DeprecatedServiceDocumenter:
+ def __init__(self, replacement_service_name):
+ self._replacement_service_name = replacement_service_name
+
+ def inject_deprecation_notice(self, section, event_name, **kwargs):
+ section.style.start_important()
+ section.write('This service client is deprecated. Please use ')
+ section.style.ref(
+ self._replacement_service_name,
+ self._replacement_service_name,
+ )
+ section.write(' instead.')
+ section.style.end_important()
+
+
+def document_copy_source_form(section, event_name, **kwargs):
+ if 'request-example' in event_name:
+ parent = section.get_section('structure-value')
+ param_line = parent.get_section('CopySource')
+ value_portion = param_line.get_section('member-value')
+ value_portion.clear_text()
+ value_portion.write(
+ "'string' or {'Bucket': 'string', "
+ "'Key': 'string', 'VersionId': 'string'}"
+ )
+ elif 'request-params' in event_name:
+ param_section = section.get_section('CopySource')
+ type_section = param_section.get_section('param-type')
+ type_section.clear_text()
+ type_section.write(':type CopySource: str or dict')
+ doc_section = param_section.get_section('param-documentation')
+ doc_section.clear_text()
+ doc_section.write(
+ "The name of the source bucket, key name of the source object, "
+ "and optional version ID of the source object. You can either "
+ "provide this value as a string or a dictionary. The "
+ "string form is {bucket}/{key} or "
+ "{bucket}/{key}?versionId={versionId} if you want to copy a "
+ "specific version. You can also provide this value as a "
+ "dictionary. The dictionary format is recommended over "
+ "the string format because it is more explicit. The dictionary "
+ "format is: {'Bucket': 'bucket', 'Key': 'key', 'VersionId': 'id'}."
+ " Note that the VersionId key is optional and may be omitted."
+ " To specify an S3 access point, provide the access point"
+ " ARN for the ``Bucket`` key in the copy source dictionary. If you"
+ " want to provide the copy source for an S3 access point as a"
+ " string instead of a dictionary, the ARN provided must be the"
+ " full S3 access point object ARN"
+ " (i.e. {accesspoint_arn}/object/{key})"
+ )
+
+
+def handle_copy_source_param(params, **kwargs):
+ """Convert CopySource param for CopyObject/UploadPartCopy.
+
+ This handler will deal with two cases:
+
+ * CopySource provided as a string. We'll make a best effort
+ to URL encode the key name as required. This will require
+ parsing the bucket and version id from the CopySource value
+ and only encoding the key.
+ * CopySource provided as a dict. In this case we're
+ explicitly given the Bucket, Key, and VersionId so we're
+ able to encode the key and ensure this value is serialized
+ and correctly sent to S3.
+
+ """
+ source = params.get('CopySource')
+ if source is None:
+ # The call will eventually fail but we'll let the
+ # param validator take care of this. It will
+ # give a better error message.
+ return
+ if isinstance(source, str):
+ params['CopySource'] = _quote_source_header(source)
+ elif isinstance(source, dict):
+ params['CopySource'] = _quote_source_header_from_dict(source)
+
+
+def _quote_source_header_from_dict(source_dict):
+ try:
+ bucket = source_dict['Bucket']
+ key = source_dict['Key']
+ version_id = source_dict.get('VersionId')
+ if VALID_S3_ARN.search(bucket):
+ final = f'{bucket}/object/{key}'
+ else:
+ final = f'{bucket}/{key}'
+ except KeyError as e:
+ raise ParamValidationError(
+ report=f'Missing required parameter: {str(e)}'
+ )
+ final = percent_encode(final, safe=SAFE_CHARS + '/')
+ if version_id is not None:
+ final += '?versionId=%s' % version_id
+ return final
+
+
+def _quote_source_header(value):
+ result = VERSION_ID_SUFFIX.search(value)
+ if result is None:
+ return percent_encode(value, safe=SAFE_CHARS + '/')
+ else:
+ first, version_id = value[: result.start()], value[result.start() :]
+ return percent_encode(first, safe=SAFE_CHARS + '/') + version_id
+
+
+def _get_cross_region_presigned_url(
+ request_signer, request_dict, model, source_region, destination_region
+):
+ # The better way to do this is to actually get the
+ # endpoint_resolver and get the endpoint_url given the
+ # source region. In this specific case, we know that
+ # we can safely replace the dest region with the source
+ # region because of the supported EC2 regions, but in
+ # general this is not a safe assumption to make.
+ # I think eventually we should try to plumb through something
+ # that allows us to resolve endpoints from regions.
+ request_dict_copy = copy.deepcopy(request_dict)
+ request_dict_copy['body']['DestinationRegion'] = destination_region
+ request_dict_copy['url'] = request_dict['url'].replace(
+ destination_region, source_region
+ )
+ request_dict_copy['method'] = 'GET'
+ request_dict_copy['headers'] = {}
+ return request_signer.generate_presigned_url(
+ request_dict_copy, region_name=source_region, operation_name=model.name
+ )
+
+
+def _get_presigned_url_source_and_destination_regions(request_signer, params):
+ # Gets the source and destination regions to be used
+ destination_region = request_signer._region_name
+ source_region = params.get('SourceRegion')
+ return source_region, destination_region
+
+
+def inject_presigned_url_ec2(params, request_signer, model, **kwargs):
+ # The customer can still provide this, so we should pass if they do.
+ if 'PresignedUrl' in params['body']:
+ return
+ src, dest = _get_presigned_url_source_and_destination_regions(
+ request_signer, params['body']
+ )
+ url = _get_cross_region_presigned_url(
+ request_signer, params, model, src, dest
+ )
+ params['body']['PresignedUrl'] = url
+ # EC2 Requires that the destination region be sent over the wire in
+ # addition to the source region.
+ params['body']['DestinationRegion'] = dest
+
+
+def inject_presigned_url_rds(params, request_signer, model, **kwargs):
+ # SourceRegion is not required for RDS operations, so it's possible that
+ # it isn't set. In that case it's probably a local copy so we don't need
+ # to do anything else.
+ if 'SourceRegion' not in params['body']:
+ return
+
+ src, dest = _get_presigned_url_source_and_destination_regions(
+ request_signer, params['body']
+ )
+
+ # Since SourceRegion isn't actually modeled for RDS, it needs to be
+ # removed from the request params before we send the actual request.
+ del params['body']['SourceRegion']
+
+ if 'PreSignedUrl' in params['body']:
+ return
+
+ url = _get_cross_region_presigned_url(
+ request_signer, params, model, src, dest
+ )
+ params['body']['PreSignedUrl'] = url
+
+
+def json_decode_policies(parsed, model, **kwargs):
+ # Any time an IAM operation returns a policy document
+ # it is a string that is json that has been urlencoded,
+ # i.e urlencode(json.dumps(policy_document)).
+ # To give users something more useful, we will urldecode
+ # this value and json.loads() the result so that they have
+ # the policy document as a dictionary.
+ output_shape = model.output_shape
+ if output_shape is not None:
+ _decode_policy_types(parsed, model.output_shape)
+
+
+def _decode_policy_types(parsed, shape):
+ # IAM consistently uses the policyDocumentType shape to indicate
+ # strings that have policy documents.
+ shape_name = 'policyDocumentType'
+ if shape.type_name == 'structure':
+ for member_name, member_shape in shape.members.items():
+ if (
+ member_shape.type_name == 'string'
+ and member_shape.name == shape_name
+ and member_name in parsed
+ ):
+ parsed[member_name] = decode_quoted_jsondoc(
+ parsed[member_name]
+ )
+ elif member_name in parsed:
+ _decode_policy_types(parsed[member_name], member_shape)
+ if shape.type_name == 'list':
+ shape_member = shape.member
+ for item in parsed:
+ _decode_policy_types(item, shape_member)
+
+
+def parse_get_bucket_location(parsed, http_response, **kwargs):
+ # s3.GetBucketLocation cannot be modeled properly. To
+ # account for this we just manually parse the XML document.
+ # The "parsed" passed in only has the ResponseMetadata
+ # filled out. This handler will fill in the LocationConstraint
+ # value.
+ if http_response.raw is None:
+ return
+ response_body = http_response.content
+ parser = ETree.XMLParser(target=ETree.TreeBuilder(), encoding='utf-8')
+ parser.feed(response_body)
+ root = parser.close()
+ region = root.text
+ parsed['LocationConstraint'] = region
+
+
+def base64_encode_user_data(params, **kwargs):
+ if 'UserData' in params:
+ if isinstance(params['UserData'], str):
+ # Encode it to bytes if it is text.
+ params['UserData'] = params['UserData'].encode('utf-8')
+ params['UserData'] = base64.b64encode(params['UserData']).decode(
+ 'utf-8'
+ )
+
+
+def document_base64_encoding(param):
+ description = (
+ '**This value will be base64 encoded automatically. Do '
+ 'not base64 encode this value prior to performing the '
+ 'operation.**'
+ )
+ append = AppendParamDocumentation(param, description)
+ return append.append_documentation
+
+
+def validate_ascii_metadata(params, **kwargs):
+ """Verify S3 Metadata only contains ascii characters.
+
+ From: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
+
+ "Amazon S3 stores user-defined metadata in lowercase. Each name, value pair
+ must conform to US-ASCII when using REST and UTF-8 when using SOAP or
+ browser-based uploads via POST."
+
+ """
+ metadata = params.get('Metadata')
+ if not metadata or not isinstance(metadata, dict):
+ # We have to at least type check the metadata as a dict type
+ # because this handler is called before param validation.
+ # We'll go ahead and return because the param validator will
+ # give a descriptive error message for us.
+ # We might need a post-param validation event.
+ return
+ for key, value in metadata.items():
+ try:
+ key.encode('ascii')
+ value.encode('ascii')
+ except UnicodeEncodeError:
+ error_msg = (
+ 'Non ascii characters found in S3 metadata '
+ 'for key "%s", value: "%s". \nS3 metadata can only '
+ 'contain ASCII characters. ' % (key, value)
+ )
+ raise ParamValidationError(report=error_msg)
+
+
+def fix_route53_ids(params, model, **kwargs):
+ """
+ Check for and split apart Route53 resource IDs, setting
+ only the last piece. This allows the output of one operation
+ (e.g. ``'foo/1234'``) to be used as input in another
+ operation (e.g. it expects just ``'1234'``).
+ """
+ input_shape = model.input_shape
+ if not input_shape or not hasattr(input_shape, 'members'):
+ return
+
+ members = [
+ name
+ for (name, shape) in input_shape.members.items()
+ if shape.name in ['ResourceId', 'DelegationSetId', 'ChangeId']
+ ]
+
+ for name in members:
+ if name in params:
+ orig_value = params[name]
+ params[name] = orig_value.split('/')[-1]
+ logger.debug('%s %s -> %s', name, orig_value, params[name])
+
+
+def inject_account_id(params, **kwargs):
+ if params.get('accountId') is None:
+ # Glacier requires accountId, but allows you
+ # to specify '-' for the current owners account.
+ # We add this default value if the user does not
+ # provide the accountId as a convenience.
+ params['accountId'] = '-'
+
+
+def add_glacier_version(model, params, **kwargs):
+ request_dict = params
+ request_dict['headers']['x-amz-glacier-version'] = model.metadata[
+ 'apiVersion'
+ ]
+
+
+def add_accept_header(model, params, **kwargs):
+ if params['headers'].get('Accept', None) is None:
+ request_dict = params
+ request_dict['headers']['Accept'] = 'application/json'
+
+
+def add_glacier_checksums(params, **kwargs):
+ """Add glacier checksums to the http request.
+
+ This will add two headers to the http request:
+
+ * x-amz-content-sha256
+ * x-amz-sha256-tree-hash
+
+ These values will only be added if they are not present
+ in the HTTP request.
+
+ """
+ request_dict = params
+ headers = request_dict['headers']
+ body = request_dict['body']
+ if isinstance(body, bytes):
+ # If the user provided a bytes type instead of a file
+ # like object, we're temporarily create a BytesIO object
+ # so we can use the util functions to calculate the
+ # checksums which assume file like objects. Note that
+ # we're not actually changing the body in the request_dict.
+ body = BytesIO(body)
+ starting_position = body.tell()
+ if 'x-amz-content-sha256' not in headers:
+ headers['x-amz-content-sha256'] = utils.calculate_sha256(
+ body, as_hex=True
+ )
+ body.seek(starting_position)
+ if 'x-amz-sha256-tree-hash' not in headers:
+ headers['x-amz-sha256-tree-hash'] = utils.calculate_tree_hash(body)
+ body.seek(starting_position)
+
+
+def document_glacier_tree_hash_checksum():
+ doc = '''
+ This is a required field.
+
+ Ideally you will want to compute this value with checksums from
+ previous uploaded parts, using the algorithm described in
+ `Glacier documentation `_.
+
+ But if you prefer, you can also use botocore.utils.calculate_tree_hash()
+ to compute it from raw file by::
+
+ checksum = calculate_tree_hash(open('your_file.txt', 'rb'))
+
+ '''
+ return AppendParamDocumentation('checksum', doc).append_documentation
+
+
+def document_cloudformation_get_template_return_type(
+ section, event_name, **kwargs
+):
+ if 'response-params' in event_name:
+ template_body_section = section.get_section('TemplateBody')
+ type_section = template_body_section.get_section('param-type')
+ type_section.clear_text()
+ type_section.write('(*dict*) --')
+ elif 'response-example' in event_name:
+ parent = section.get_section('structure-value')
+ param_line = parent.get_section('TemplateBody')
+ value_portion = param_line.get_section('member-value')
+ value_portion.clear_text()
+ value_portion.write('{}')
+
+
+def switch_host_machinelearning(request, **kwargs):
+ switch_host_with_param(request, 'PredictEndpoint')
+
+
+def check_openssl_supports_tls_version_1_2(**kwargs):
+ import ssl
+
+ try:
+ openssl_version_tuple = ssl.OPENSSL_VERSION_INFO
+ if openssl_version_tuple < (1, 0, 1):
+ warnings.warn(
+ 'Currently installed openssl version: %s does not '
+ 'support TLS 1.2, which is required for use of iot-data. '
+ 'Please use python installed with openssl version 1.0.1 or '
+ 'higher.' % (ssl.OPENSSL_VERSION),
+ UnsupportedTLSVersionWarning,
+ )
+ # We cannot check the openssl version on python2.6, so we should just
+ # pass on this conveniency check.
+ except AttributeError:
+ pass
+
+
+def change_get_to_post(request, **kwargs):
+ # This is useful when we need to change a potentially large GET request
+ # into a POST with x-www-form-urlencoded encoding.
+ if request.method == 'GET' and '?' in request.url:
+ request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
+ request.method = 'POST'
+ request.url, request.data = request.url.split('?', 1)
+
+
+def set_list_objects_encoding_type_url(params, context, **kwargs):
+ if 'EncodingType' not in params:
+ # We set this context so that we know it wasn't the customer that
+ # requested the encoding.
+ context['encoding_type_auto_set'] = True
+ params['EncodingType'] = 'url'
+
+
+def decode_list_object(parsed, context, **kwargs):
+ # This is needed because we are passing url as the encoding type. Since the
+ # paginator is based on the key, we need to handle it before it can be
+ # round tripped.
+ #
+ # From the documentation: If you specify encoding-type request parameter,
+ # Amazon S3 includes this element in the response, and returns encoded key
+ # name values in the following response elements:
+ # Delimiter, Marker, Prefix, NextMarker, Key.
+ _decode_list_object(
+ top_level_keys=['Delimiter', 'Marker', 'NextMarker'],
+ nested_keys=[('Contents', 'Key'), ('CommonPrefixes', 'Prefix')],
+ parsed=parsed,
+ context=context,
+ )
+
+
+def decode_list_object_v2(parsed, context, **kwargs):
+ # From the documentation: If you specify encoding-type request parameter,
+ # Amazon S3 includes this element in the response, and returns encoded key
+ # name values in the following response elements:
+ # Delimiter, Prefix, ContinuationToken, Key, and StartAfter.
+ _decode_list_object(
+ top_level_keys=['Delimiter', 'Prefix', 'StartAfter'],
+ nested_keys=[('Contents', 'Key'), ('CommonPrefixes', 'Prefix')],
+ parsed=parsed,
+ context=context,
+ )
+
+
+def decode_list_object_versions(parsed, context, **kwargs):
+ # From the documentation: If you specify encoding-type request parameter,
+ # Amazon S3 includes this element in the response, and returns encoded key
+ # name values in the following response elements:
+ # KeyMarker, NextKeyMarker, Prefix, Key, and Delimiter.
+ _decode_list_object(
+ top_level_keys=[
+ 'KeyMarker',
+ 'NextKeyMarker',
+ 'Prefix',
+ 'Delimiter',
+ ],
+ nested_keys=[
+ ('Versions', 'Key'),
+ ('DeleteMarkers', 'Key'),
+ ('CommonPrefixes', 'Prefix'),
+ ],
+ parsed=parsed,
+ context=context,
+ )
+
+
+def _decode_list_object(top_level_keys, nested_keys, parsed, context):
+ if parsed.get('EncodingType') == 'url' and context.get(
+ 'encoding_type_auto_set'
+ ):
+ # URL decode top-level keys in the response if present.
+ for key in top_level_keys:
+ if key in parsed:
+ parsed[key] = unquote_str(parsed[key])
+ # URL decode nested keys from the response if present.
+ for top_key, child_key in nested_keys:
+ if top_key in parsed:
+ for member in parsed[top_key]:
+ member[child_key] = unquote_str(member[child_key])
+
+
+def convert_body_to_file_like_object(params, **kwargs):
+ if 'Body' in params:
+ if isinstance(params['Body'], str):
+ params['Body'] = BytesIO(ensure_bytes(params['Body']))
+ elif isinstance(params['Body'], bytes):
+ params['Body'] = BytesIO(params['Body'])
+
+
+def _add_parameter_aliases(handler_list):
+ # Mapping of original parameter to parameter alias.
+ # The key is ..parameter
+ # The first part of the key is used for event registration.
+ # The last part is the original parameter name and the value is the
+ # alias to expose in documentation.
+ aliases = {
+ 'ec2.*.Filter': 'Filters',
+ 'logs.CreateExportTask.from': 'fromTime',
+ 'cloudsearchdomain.Search.return': 'returnFields',
+ }
+
+ for original, new_name in aliases.items():
+ event_portion, original_name = original.rsplit('.', 1)
+ parameter_alias = ParameterAlias(original_name, new_name)
+
+ # Add the handlers to the list of handlers.
+ # One handler is to handle when users provide the alias.
+ # The other handler is to update the documentation to show only
+ # the alias.
+ parameter_build_event_handler_tuple = (
+ 'before-parameter-build.' + event_portion,
+ parameter_alias.alias_parameter_in_call,
+ REGISTER_FIRST,
+ )
+ docs_event_handler_tuple = (
+ 'docs.*.' + event_portion + '.complete-section',
+ parameter_alias.alias_parameter_in_documentation,
+ )
+ handler_list.append(parameter_build_event_handler_tuple)
+ handler_list.append(docs_event_handler_tuple)
+
+
+class ParameterAlias:
+ def __init__(self, original_name, alias_name):
+ self._original_name = original_name
+ self._alias_name = alias_name
+
+ def alias_parameter_in_call(self, params, model, **kwargs):
+ if model.input_shape:
+ # Only consider accepting the alias if it is modeled in the
+ # input shape.
+ if self._original_name in model.input_shape.members:
+ if self._alias_name in params:
+ if self._original_name in params:
+ raise AliasConflictParameterError(
+ original=self._original_name,
+ alias=self._alias_name,
+ operation=model.name,
+ )
+ # Remove the alias parameter value and use the old name
+ # instead.
+ params[self._original_name] = params.pop(self._alias_name)
+
+ def alias_parameter_in_documentation(self, event_name, section, **kwargs):
+ if event_name.startswith('docs.request-params'):
+ if self._original_name not in section.available_sections:
+ return
+ # Replace the name for parameter type
+ param_section = section.get_section(self._original_name)
+ param_type_section = param_section.get_section('param-type')
+ self._replace_content(param_type_section)
+
+ # Replace the name for the parameter description
+ param_name_section = param_section.get_section('param-name')
+ self._replace_content(param_name_section)
+ elif event_name.startswith('docs.request-example'):
+ section = section.get_section('structure-value')
+ if self._original_name not in section.available_sections:
+ return
+ # Replace the name for the example
+ param_section = section.get_section(self._original_name)
+ self._replace_content(param_section)
+
+ def _replace_content(self, section):
+ content = section.getvalue().decode('utf-8')
+ updated_content = content.replace(
+ self._original_name, self._alias_name
+ )
+ section.clear_text()
+ section.write(updated_content)
+
+
+class ClientMethodAlias:
+ def __init__(self, actual_name):
+ """Aliases a non-extant method to an existing method.
+
+ :param actual_name: The name of the method that actually exists on
+ the client.
+ """
+ self._actual = actual_name
+
+ def __call__(self, client, **kwargs):
+ return getattr(client, self._actual)
+
+
+# TODO: Remove this class as it is no longer used
+class HeaderToHostHoister:
+ """Takes a header and moves it to the front of the hoststring."""
+
+ _VALID_HOSTNAME = re.compile(r'(?!-)[a-z\d-]{1,63}(? 1 and ArnParser.is_arn(
+ unquote(auth_path_parts[1])
+ ):
+ request.auth_path = '/'.join(['', *auth_path_parts[2:]])
+
+
+def customize_endpoint_resolver_builtins(
+ builtins, model, params, context, **kwargs
+):
+ """Modify builtin parameter values for endpoint resolver
+
+ Modifies the builtins dict in place. Changes are in effect for one call.
+ The corresponding event is emitted only if at least one builtin parameter
+ value is required for endpoint resolution for the operation.
+ """
+ bucket_name = params.get('Bucket')
+ bucket_is_arn = bucket_name is not None and ArnParser.is_arn(bucket_name)
+ # In some situations the host will return AuthorizationHeaderMalformed
+ # when the signing region of a sigv4 request is not the bucket's
+ # region (which is likely unknown by the user of GetBucketLocation).
+ # Avoid this by always using path-style addressing.
+ if model.name == 'GetBucketLocation':
+ builtins[EndpointResolverBuiltins.AWS_S3_FORCE_PATH_STYLE] = True
+ # All situations where the bucket name is an ARN are not compatible
+ # with path style addressing.
+ elif bucket_is_arn:
+ builtins[EndpointResolverBuiltins.AWS_S3_FORCE_PATH_STYLE] = False
+
+ # Bucket names that are invalid host labels require path-style addressing.
+ # If path-style addressing was specifically requested, the default builtin
+ # value is already set.
+ path_style_required = (
+ bucket_name is not None and not VALID_HOST_LABEL_RE.match(bucket_name)
+ )
+ path_style_requested = builtins[
+ EndpointResolverBuiltins.AWS_S3_FORCE_PATH_STYLE
+ ]
+
+ # Path-style addressing is incompatible with the global endpoint for
+ # presigned URLs. If the bucket name is an ARN, the ARN's region should be
+ # used in the endpoint.
+ if (
+ context.get('use_global_endpoint')
+ and not path_style_required
+ and not path_style_requested
+ and not bucket_is_arn
+ ):
+ builtins[EndpointResolverBuiltins.AWS_REGION] = 'aws-global'
+ builtins[EndpointResolverBuiltins.AWS_S3_USE_GLOBAL_ENDPOINT] = True
+
+
+def remove_content_type_header_for_presigning(request, **kwargs):
+ if (
+ request.context.get('is_presign_request') is True
+ and 'Content-Type' in request.headers
+ ):
+ del request.headers['Content-Type']
+
+
+# This is a list of (event_name, handler).
+# When a Session is created, everything in this list will be
+# automatically registered with that Session.
+
+BUILTIN_HANDLERS = [
+ ('choose-service-name', handle_service_name_alias),
+ (
+ 'getattr.mturk.list_hi_ts_for_qualification_type',
+ ClientMethodAlias('list_hits_for_qualification_type'),
+ ),
+ (
+ 'before-parameter-build.s3.UploadPart',
+ convert_body_to_file_like_object,
+ REGISTER_LAST,
+ ),
+ (
+ 'before-parameter-build.s3.PutObject',
+ convert_body_to_file_like_object,
+ REGISTER_LAST,
+ ),
+ ('creating-client-class', add_generate_presigned_url),
+ ('creating-client-class.s3', add_generate_presigned_post),
+ ('creating-client-class.iot-data', check_openssl_supports_tls_version_1_2),
+ ('creating-client-class.lex-runtime-v2', remove_lex_v2_start_conversation),
+ ('after-call.iam', json_decode_policies),
+ ('after-call.ec2.GetConsoleOutput', decode_console_output),
+ ('after-call.cloudformation.GetTemplate', json_decode_template_body),
+ ('after-call.s3.GetBucketLocation', parse_get_bucket_location),
+ ('before-parameter-build', generate_idempotent_uuid),
+ ('before-parameter-build.s3', validate_bucket_name),
+ ('before-parameter-build.s3', remove_bucket_from_url_paths_from_model),
+ (
+ 'before-parameter-build.s3.ListObjects',
+ set_list_objects_encoding_type_url,
+ ),
+ (
+ 'before-parameter-build.s3.ListObjectsV2',
+ set_list_objects_encoding_type_url,
+ ),
+ (
+ 'before-parameter-build.s3.ListObjectVersions',
+ set_list_objects_encoding_type_url,
+ ),
+ ('before-parameter-build.s3.CopyObject', handle_copy_source_param),
+ ('before-parameter-build.s3.UploadPartCopy', handle_copy_source_param),
+ ('before-parameter-build.s3.CopyObject', validate_ascii_metadata),
+ ('before-parameter-build.s3.PutObject', validate_ascii_metadata),
+ (
+ 'before-parameter-build.s3.CreateMultipartUpload',
+ validate_ascii_metadata,
+ ),
+ ('before-parameter-build.s3-control', remove_accid_host_prefix_from_model),
+ ('docs.*.s3.CopyObject.complete-section', document_copy_source_form),
+ ('docs.*.s3.UploadPartCopy.complete-section', document_copy_source_form),
+ ('before-endpoint-resolution.s3', customize_endpoint_resolver_builtins),
+ ('before-call', add_recursion_detection_header),
+ ('before-call.s3', add_expect_header),
+ ('before-call.glacier', add_glacier_version),
+ ('before-call.apigateway', add_accept_header),
+ ('before-call.s3.PutObject', conditionally_calculate_md5),
+ ('before-call.s3.UploadPart', conditionally_calculate_md5),
+ ('before-call.s3.DeleteObjects', escape_xml_payload),
+ ('before-call.s3.PutBucketLifecycleConfiguration', escape_xml_payload),
+ ('before-call.glacier.UploadArchive', add_glacier_checksums),
+ ('before-call.glacier.UploadMultipartPart', add_glacier_checksums),
+ ('before-call.ec2.CopySnapshot', inject_presigned_url_ec2),
+ ('request-created', add_retry_headers),
+ ('request-created.machinelearning.Predict', switch_host_machinelearning),
+ ('needs-retry.s3.UploadPartCopy', check_for_200_error, REGISTER_FIRST),
+ ('needs-retry.s3.CopyObject', check_for_200_error, REGISTER_FIRST),
+ (
+ 'needs-retry.s3.CompleteMultipartUpload',
+ check_for_200_error,
+ REGISTER_FIRST,
+ ),
+ ('choose-signer.cognito-identity.GetId', disable_signing),
+ ('choose-signer.cognito-identity.GetOpenIdToken', disable_signing),
+ ('choose-signer.cognito-identity.UnlinkIdentity', disable_signing),
+ (
+ 'choose-signer.cognito-identity.GetCredentialsForIdentity',
+ disable_signing,
+ ),
+ ('choose-signer.sts.AssumeRoleWithSAML', disable_signing),
+ ('choose-signer.sts.AssumeRoleWithWebIdentity', disable_signing),
+ ('choose-signer', set_operation_specific_signer),
+ ('before-parameter-build.s3.HeadObject', sse_md5),
+ ('before-parameter-build.s3.GetObject', sse_md5),
+ ('before-parameter-build.s3.PutObject', sse_md5),
+ ('before-parameter-build.s3.CopyObject', sse_md5),
+ ('before-parameter-build.s3.CopyObject', copy_source_sse_md5),
+ ('before-parameter-build.s3.CreateMultipartUpload', sse_md5),
+ ('before-parameter-build.s3.UploadPart', sse_md5),
+ ('before-parameter-build.s3.UploadPartCopy', sse_md5),
+ ('before-parameter-build.s3.UploadPartCopy', copy_source_sse_md5),
+ ('before-parameter-build.s3.CompleteMultipartUpload', sse_md5),
+ ('before-parameter-build.s3.SelectObjectContent', sse_md5),
+ ('before-parameter-build.ec2.RunInstances', base64_encode_user_data),
+ (
+ 'before-parameter-build.autoscaling.CreateLaunchConfiguration',
+ base64_encode_user_data,
+ ),
+ ('before-parameter-build.route53', fix_route53_ids),
+ ('before-parameter-build.glacier', inject_account_id),
+ ('before-sign.s3', remove_arn_from_signing_path),
+ (
+ 'before-sign.polly.SynthesizeSpeech',
+ remove_content_type_header_for_presigning,
+ ),
+ ('after-call.s3.ListObjects', decode_list_object),
+ ('after-call.s3.ListObjectsV2', decode_list_object_v2),
+ ('after-call.s3.ListObjectVersions', decode_list_object_versions),
+ # Cloudsearchdomain search operation will be sent by HTTP POST
+ ('request-created.cloudsearchdomain.Search', change_get_to_post),
+ # Glacier documentation customizations
+ (
+ 'docs.*.glacier.*.complete-section',
+ AutoPopulatedParam(
+ 'accountId',
+ 'Note: this parameter is set to "-" by'
+ 'default if no value is not specified.',
+ ).document_auto_populated_param,
+ ),
+ (
+ 'docs.*.glacier.UploadArchive.complete-section',
+ AutoPopulatedParam('checksum').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.glacier.UploadMultipartPart.complete-section',
+ AutoPopulatedParam('checksum').document_auto_populated_param,
+ ),
+ (
+ 'docs.request-params.glacier.CompleteMultipartUpload.complete-section',
+ document_glacier_tree_hash_checksum(),
+ ),
+ # Cloudformation documentation customizations
+ (
+ 'docs.*.cloudformation.GetTemplate.complete-section',
+ document_cloudformation_get_template_return_type,
+ ),
+ # UserData base64 encoding documentation customizations
+ (
+ 'docs.*.ec2.RunInstances.complete-section',
+ document_base64_encoding('UserData'),
+ ),
+ (
+ 'docs.*.autoscaling.CreateLaunchConfiguration.complete-section',
+ document_base64_encoding('UserData'),
+ ),
+ # EC2 CopySnapshot documentation customizations
+ (
+ 'docs.*.ec2.CopySnapshot.complete-section',
+ AutoPopulatedParam('PresignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.ec2.CopySnapshot.complete-section',
+ AutoPopulatedParam('DestinationRegion').document_auto_populated_param,
+ ),
+ # S3 SSE documentation modifications
+ (
+ 'docs.*.s3.*.complete-section',
+ AutoPopulatedParam('SSECustomerKeyMD5').document_auto_populated_param,
+ ),
+ # S3 SSE Copy Source documentation modifications
+ (
+ 'docs.*.s3.*.complete-section',
+ AutoPopulatedParam(
+ 'CopySourceSSECustomerKeyMD5'
+ ).document_auto_populated_param,
+ ),
+ # Add base64 information to Lambda
+ (
+ 'docs.*.lambda.UpdateFunctionCode.complete-section',
+ document_base64_encoding('ZipFile'),
+ ),
+ # The following S3 operations cannot actually accept a ContentMD5
+ (
+ 'docs.*.s3.*.complete-section',
+ HideParamFromOperations(
+ 's3',
+ 'ContentMD5',
+ [
+ 'DeleteObjects',
+ 'PutBucketAcl',
+ 'PutBucketCors',
+ 'PutBucketLifecycle',
+ 'PutBucketLogging',
+ 'PutBucketNotification',
+ 'PutBucketPolicy',
+ 'PutBucketReplication',
+ 'PutBucketRequestPayment',
+ 'PutBucketTagging',
+ 'PutBucketVersioning',
+ 'PutBucketWebsite',
+ 'PutObjectAcl',
+ ],
+ ).hide_param,
+ ),
+ #############
+ # RDS
+ #############
+ ('creating-client-class.rds', add_generate_db_auth_token),
+ ('before-call.rds.CopyDBClusterSnapshot', inject_presigned_url_rds),
+ ('before-call.rds.CreateDBCluster', inject_presigned_url_rds),
+ ('before-call.rds.CopyDBSnapshot', inject_presigned_url_rds),
+ ('before-call.rds.CreateDBInstanceReadReplica', inject_presigned_url_rds),
+ (
+ 'before-call.rds.StartDBInstanceAutomatedBackupsReplication',
+ inject_presigned_url_rds,
+ ),
+ # RDS PresignedUrl documentation customizations
+ (
+ 'docs.*.rds.CopyDBClusterSnapshot.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.rds.CreateDBCluster.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.rds.CopyDBSnapshot.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.rds.CreateDBInstanceReadReplica.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.rds.StartDBInstanceAutomatedBackupsReplication.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ #############
+ # Neptune
+ #############
+ ('before-call.neptune.CopyDBClusterSnapshot', inject_presigned_url_rds),
+ ('before-call.neptune.CreateDBCluster', inject_presigned_url_rds),
+ # Neptune PresignedUrl documentation customizations
+ (
+ 'docs.*.neptune.CopyDBClusterSnapshot.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.neptune.CreateDBCluster.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ #############
+ # DocDB
+ #############
+ ('before-call.docdb.CopyDBClusterSnapshot', inject_presigned_url_rds),
+ ('before-call.docdb.CreateDBCluster', inject_presigned_url_rds),
+ # DocDB PresignedUrl documentation customizations
+ (
+ 'docs.*.docdb.CopyDBClusterSnapshot.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ (
+ 'docs.*.docdb.CreateDBCluster.complete-section',
+ AutoPopulatedParam('PreSignedUrl').document_auto_populated_param,
+ ),
+ ('before-call', inject_api_version_header_if_needed),
+]
+_add_parameter_aliases(BUILTIN_HANDLERS)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/history.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/history.py
new file mode 100644
index 0000000000..59d9481d7f
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/history.py
@@ -0,0 +1,55 @@
+# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import logging
+
+HISTORY_RECORDER = None
+logger = logging.getLogger(__name__)
+
+
+class BaseHistoryHandler:
+ def emit(self, event_type, payload, source):
+ raise NotImplementedError('emit()')
+
+
+class HistoryRecorder:
+ def __init__(self):
+ self._enabled = False
+ self._handlers = []
+
+ def enable(self):
+ self._enabled = True
+
+ def disable(self):
+ self._enabled = False
+
+ def add_handler(self, handler):
+ self._handlers.append(handler)
+
+ def record(self, event_type, payload, source='BOTOCORE'):
+ if self._enabled and self._handlers:
+ for handler in self._handlers:
+ try:
+ handler.emit(event_type, payload, source)
+ except Exception:
+ # Never let the process die because we had a failure in
+ # a record collection handler.
+ logger.debug(
+ "Exception raised in %s.", handler, exc_info=True
+ )
+
+
+def get_global_history_recorder():
+ global HISTORY_RECORDER
+ if HISTORY_RECORDER is None:
+ HISTORY_RECORDER = HistoryRecorder()
+ return HISTORY_RECORDER
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/hooks.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/hooks.py
new file mode 100644
index 0000000000..01248a1ea9
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/hooks.py
@@ -0,0 +1,660 @@
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import copy
+import logging
+from collections import deque, namedtuple
+
+from botocore.compat import accepts_kwargs
+from botocore.utils import EVENT_ALIASES
+
+logger = logging.getLogger(__name__)
+
+
+_NodeList = namedtuple('NodeList', ['first', 'middle', 'last'])
+_FIRST = 0
+_MIDDLE = 1
+_LAST = 2
+
+
+class NodeList(_NodeList):
+ def __copy__(self):
+ first_copy = copy.copy(self.first)
+ middle_copy = copy.copy(self.middle)
+ last_copy = copy.copy(self.last)
+ copied = NodeList(first_copy, middle_copy, last_copy)
+ return copied
+
+
+def first_non_none_response(responses, default=None):
+ """Find first non None response in a list of tuples.
+
+ This function can be used to find the first non None response from
+ handlers connected to an event. This is useful if you are interested
+ in the returned responses from event handlers. Example usage::
+
+ print(first_non_none_response([(func1, None), (func2, 'foo'),
+ (func3, 'bar')]))
+ # This will print 'foo'
+
+ :type responses: list of tuples
+ :param responses: The responses from the ``EventHooks.emit`` method.
+ This is a list of tuples, and each tuple is
+ (handler, handler_response).
+
+ :param default: If no non-None responses are found, then this default
+ value will be returned.
+
+ :return: The first non-None response in the list of tuples.
+
+ """
+ for response in responses:
+ if response[1] is not None:
+ return response[1]
+ return default
+
+
+class BaseEventHooks:
+ def emit(self, event_name, **kwargs):
+ """Call all handlers subscribed to an event.
+
+ :type event_name: str
+ :param event_name: The name of the event to emit.
+
+ :type **kwargs: dict
+ :param **kwargs: Arbitrary kwargs to pass through to the
+ subscribed handlers. The ``event_name`` will be injected
+ into the kwargs so it's not necessary to add this to **kwargs.
+
+ :rtype: list of tuples
+ :return: A list of ``(handler_func, handler_func_return_value)``
+
+ """
+ return []
+
+ def register(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ """Register an event handler for a given event.
+
+ If a ``unique_id`` is given, the handler will not be registered
+ if a handler with the ``unique_id`` has already been registered.
+
+ Handlers are called in the order they have been registered.
+ Note handlers can also be registered with ``register_first()``
+ and ``register_last()``. All handlers registered with
+ ``register_first()`` are called before handlers registered
+ with ``register()`` which are called before handlers registered
+ with ``register_last()``.
+
+ """
+ self._verify_and_register(
+ event_name,
+ handler,
+ unique_id,
+ register_method=self._register,
+ unique_id_uses_count=unique_id_uses_count,
+ )
+
+ def register_first(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ """Register an event handler to be called first for an event.
+
+ All event handlers registered with ``register_first()`` will
+ be called before handlers registered with ``register()`` and
+ ``register_last()``.
+
+ """
+ self._verify_and_register(
+ event_name,
+ handler,
+ unique_id,
+ register_method=self._register_first,
+ unique_id_uses_count=unique_id_uses_count,
+ )
+
+ def register_last(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ """Register an event handler to be called last for an event.
+
+ All event handlers registered with ``register_last()`` will be called
+ after handlers registered with ``register_first()`` and ``register()``.
+
+ """
+ self._verify_and_register(
+ event_name,
+ handler,
+ unique_id,
+ register_method=self._register_last,
+ unique_id_uses_count=unique_id_uses_count,
+ )
+
+ def _verify_and_register(
+ self,
+ event_name,
+ handler,
+ unique_id,
+ register_method,
+ unique_id_uses_count,
+ ):
+ self._verify_is_callable(handler)
+ self._verify_accept_kwargs(handler)
+ register_method(event_name, handler, unique_id, unique_id_uses_count)
+
+ def unregister(
+ self,
+ event_name,
+ handler=None,
+ unique_id=None,
+ unique_id_uses_count=False,
+ ):
+ """Unregister an event handler for a given event.
+
+ If no ``unique_id`` was given during registration, then the
+ first instance of the event handler is removed (if the event
+ handler has been registered multiple times).
+
+ """
+ pass
+
+ def _verify_is_callable(self, func):
+ if not callable(func):
+ raise ValueError("Event handler %s must be callable." % func)
+
+ def _verify_accept_kwargs(self, func):
+ """Verifies a callable accepts kwargs
+
+ :type func: callable
+ :param func: A callable object.
+
+ :returns: True, if ``func`` accepts kwargs, otherwise False.
+
+ """
+ try:
+ if not accepts_kwargs(func):
+ raise ValueError(
+ f"Event handler {func} must accept keyword "
+ f"arguments (**kwargs)"
+ )
+ except TypeError:
+ return False
+
+
+class HierarchicalEmitter(BaseEventHooks):
+ def __init__(self):
+ # We keep a reference to the handlers for quick
+ # read only access (we never modify self._handlers).
+ # A cache of event name to handler list.
+ self._lookup_cache = {}
+ self._handlers = _PrefixTrie()
+ # This is used to ensure that unique_id's are only
+ # registered once.
+ self._unique_id_handlers = {}
+
+ def _emit(self, event_name, kwargs, stop_on_response=False):
+ """
+ Emit an event with optional keyword arguments.
+
+ :type event_name: string
+ :param event_name: Name of the event
+ :type kwargs: dict
+ :param kwargs: Arguments to be passed to the handler functions.
+ :type stop_on_response: boolean
+ :param stop_on_response: Whether to stop on the first non-None
+ response. If False, then all handlers
+ will be called. This is especially useful
+ to handlers which mutate data and then
+ want to stop propagation of the event.
+ :rtype: list
+ :return: List of (handler, response) tuples from all processed
+ handlers.
+ """
+ responses = []
+ # Invoke the event handlers from most specific
+ # to least specific, each time stripping off a dot.
+ handlers_to_call = self._lookup_cache.get(event_name)
+ if handlers_to_call is None:
+ handlers_to_call = self._handlers.prefix_search(event_name)
+ self._lookup_cache[event_name] = handlers_to_call
+ elif not handlers_to_call:
+ # Short circuit and return an empty response is we have
+ # no handlers to call. This is the common case where
+ # for the majority of signals, nothing is listening.
+ return []
+ kwargs['event_name'] = event_name
+ responses = []
+ for handler in handlers_to_call:
+ logger.debug('Event %s: calling handler %s', event_name, handler)
+ response = handler(**kwargs)
+ responses.append((handler, response))
+ if stop_on_response and response is not None:
+ return responses
+ return responses
+
+ def emit(self, event_name, **kwargs):
+ """
+ Emit an event by name with arguments passed as keyword args.
+
+ >>> responses = emitter.emit(
+ ... 'my-event.service.operation', arg1='one', arg2='two')
+
+ :rtype: list
+ :return: List of (handler, response) tuples from all processed
+ handlers.
+ """
+ return self._emit(event_name, kwargs)
+
+ def emit_until_response(self, event_name, **kwargs):
+ """
+ Emit an event by name with arguments passed as keyword args,
+ until the first non-``None`` response is received. This
+ method prevents subsequent handlers from being invoked.
+
+ >>> handler, response = emitter.emit_until_response(
+ 'my-event.service.operation', arg1='one', arg2='two')
+
+ :rtype: tuple
+ :return: The first (handler, response) tuple where the response
+ is not ``None``, otherwise (``None``, ``None``).
+ """
+ responses = self._emit(event_name, kwargs, stop_on_response=True)
+ if responses:
+ return responses[-1]
+ else:
+ return (None, None)
+
+ def _register(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ self._register_section(
+ event_name,
+ handler,
+ unique_id,
+ unique_id_uses_count,
+ section=_MIDDLE,
+ )
+
+ def _register_first(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ self._register_section(
+ event_name,
+ handler,
+ unique_id,
+ unique_id_uses_count,
+ section=_FIRST,
+ )
+
+ def _register_last(
+ self, event_name, handler, unique_id, unique_id_uses_count=False
+ ):
+ self._register_section(
+ event_name, handler, unique_id, unique_id_uses_count, section=_LAST
+ )
+
+ def _register_section(
+ self, event_name, handler, unique_id, unique_id_uses_count, section
+ ):
+ if unique_id is not None:
+ if unique_id in self._unique_id_handlers:
+ # We've already registered a handler using this unique_id
+ # so we don't need to register it again.
+ count = self._unique_id_handlers[unique_id].get('count', None)
+ if unique_id_uses_count:
+ if not count:
+ raise ValueError(
+ "Initial registration of unique id %s was "
+ "specified to use a counter. Subsequent register "
+ "calls to unique id must specify use of a counter "
+ "as well." % unique_id
+ )
+ else:
+ self._unique_id_handlers[unique_id]['count'] += 1
+ else:
+ if count:
+ raise ValueError(
+ "Initial registration of unique id %s was "
+ "specified to not use a counter. Subsequent "
+ "register calls to unique id must specify not to "
+ "use a counter as well." % unique_id
+ )
+ return
+ else:
+ # Note that the trie knows nothing about the unique
+ # id. We track uniqueness in this class via the
+ # _unique_id_handlers.
+ self._handlers.append_item(
+ event_name, handler, section=section
+ )
+ unique_id_handler_item = {'handler': handler}
+ if unique_id_uses_count:
+ unique_id_handler_item['count'] = 1
+ self._unique_id_handlers[unique_id] = unique_id_handler_item
+ else:
+ self._handlers.append_item(event_name, handler, section=section)
+ # Super simple caching strategy for now, if we change the registrations
+ # clear the cache. This has the opportunity for smarter invalidations.
+ self._lookup_cache = {}
+
+ def unregister(
+ self,
+ event_name,
+ handler=None,
+ unique_id=None,
+ unique_id_uses_count=False,
+ ):
+ if unique_id is not None:
+ try:
+ count = self._unique_id_handlers[unique_id].get('count', None)
+ except KeyError:
+ # There's no handler matching that unique_id so we have
+ # nothing to unregister.
+ return
+ if unique_id_uses_count:
+ if count is None:
+ raise ValueError(
+ "Initial registration of unique id %s was specified to "
+ "use a counter. Subsequent unregister calls to unique "
+ "id must specify use of a counter as well." % unique_id
+ )
+ elif count == 1:
+ handler = self._unique_id_handlers.pop(unique_id)[
+ 'handler'
+ ]
+ else:
+ self._unique_id_handlers[unique_id]['count'] -= 1
+ return
+ else:
+ if count:
+ raise ValueError(
+ "Initial registration of unique id %s was specified "
+ "to not use a counter. Subsequent unregister calls "
+ "to unique id must specify not to use a counter as "
+ "well." % unique_id
+ )
+ handler = self._unique_id_handlers.pop(unique_id)['handler']
+ try:
+ self._handlers.remove_item(event_name, handler)
+ self._lookup_cache = {}
+ except ValueError:
+ pass
+
+ def __copy__(self):
+ new_instance = self.__class__()
+ new_state = self.__dict__.copy()
+ new_state['_handlers'] = copy.copy(self._handlers)
+ new_state['_unique_id_handlers'] = copy.copy(self._unique_id_handlers)
+ new_instance.__dict__ = new_state
+ return new_instance
+
+
+class EventAliaser(BaseEventHooks):
+ def __init__(self, event_emitter, event_aliases=None):
+ self._event_aliases = event_aliases
+ if event_aliases is None:
+ self._event_aliases = EVENT_ALIASES
+ self._alias_name_cache = {}
+ self._emitter = event_emitter
+
+ def emit(self, event_name, **kwargs):
+ aliased_event_name = self._alias_event_name(event_name)
+ return self._emitter.emit(aliased_event_name, **kwargs)
+
+ def emit_until_response(self, event_name, **kwargs):
+ aliased_event_name = self._alias_event_name(event_name)
+ return self._emitter.emit_until_response(aliased_event_name, **kwargs)
+
+ def register(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ aliased_event_name = self._alias_event_name(event_name)
+ return self._emitter.register(
+ aliased_event_name, handler, unique_id, unique_id_uses_count
+ )
+
+ def register_first(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ aliased_event_name = self._alias_event_name(event_name)
+ return self._emitter.register_first(
+ aliased_event_name, handler, unique_id, unique_id_uses_count
+ )
+
+ def register_last(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ aliased_event_name = self._alias_event_name(event_name)
+ return self._emitter.register_last(
+ aliased_event_name, handler, unique_id, unique_id_uses_count
+ )
+
+ def unregister(
+ self,
+ event_name,
+ handler=None,
+ unique_id=None,
+ unique_id_uses_count=False,
+ ):
+ aliased_event_name = self._alias_event_name(event_name)
+ return self._emitter.unregister(
+ aliased_event_name, handler, unique_id, unique_id_uses_count
+ )
+
+ def _alias_event_name(self, event_name):
+ if event_name in self._alias_name_cache:
+ return self._alias_name_cache[event_name]
+
+ for old_part, new_part in self._event_aliases.items():
+ # We can't simply do a string replace for everything, otherwise we
+ # might end up translating substrings that we never intended to
+ # translate. When there aren't any dots in the old event name
+ # part, then we can quickly replace the item in the list if it's
+ # there.
+ event_parts = event_name.split('.')
+ if '.' not in old_part:
+ try:
+ # Theoretically a given event name could have the same part
+ # repeated, but in practice this doesn't happen
+ event_parts[event_parts.index(old_part)] = new_part
+ except ValueError:
+ continue
+
+ # If there's dots in the name, it gets more complicated. Now we
+ # have to replace multiple sections of the original event.
+ elif old_part in event_name:
+ old_parts = old_part.split('.')
+ self._replace_subsection(event_parts, old_parts, new_part)
+ else:
+ continue
+
+ new_name = '.'.join(event_parts)
+ logger.debug(
+ f"Changing event name from {event_name} to {new_name}"
+ )
+ self._alias_name_cache[event_name] = new_name
+ return new_name
+
+ self._alias_name_cache[event_name] = event_name
+ return event_name
+
+ def _replace_subsection(self, sections, old_parts, new_part):
+ for i in range(len(sections)):
+ if (
+ sections[i] == old_parts[0]
+ and sections[i : i + len(old_parts)] == old_parts
+ ):
+ sections[i : i + len(old_parts)] = [new_part]
+ return
+
+ def __copy__(self):
+ return self.__class__(
+ copy.copy(self._emitter), copy.copy(self._event_aliases)
+ )
+
+
+class _PrefixTrie:
+ """Specialized prefix trie that handles wildcards.
+
+ The prefixes in this case are based on dot separated
+ names so 'foo.bar.baz' is::
+
+ foo -> bar -> baz
+
+ Wildcard support just means that having a key such as 'foo.bar.*.baz' will
+ be matched with a call to ``get_items(key='foo.bar.ANYTHING.baz')``.
+
+ You can think of this prefix trie as the equivalent as defaultdict(list),
+ except that it can do prefix searches:
+
+ foo.bar.baz -> A
+ foo.bar -> B
+ foo -> C
+
+ Calling ``get_items('foo.bar.baz')`` will return [A + B + C], from
+ most specific to least specific.
+
+ """
+
+ def __init__(self):
+ # Each dictionary can be though of as a node, where a node
+ # has values associated with the node, and children is a link
+ # to more nodes. So 'foo.bar' would have a 'foo' node with
+ # a 'bar' node as a child of foo.
+ # {'foo': {'children': {'bar': {...}}}}.
+ self._root = {'chunk': None, 'children': {}, 'values': None}
+
+ def append_item(self, key, value, section=_MIDDLE):
+ """Add an item to a key.
+
+ If a value is already associated with that key, the new
+ value is appended to the list for the key.
+ """
+ key_parts = key.split('.')
+ current = self._root
+ for part in key_parts:
+ if part not in current['children']:
+ new_child = {'chunk': part, 'values': None, 'children': {}}
+ current['children'][part] = new_child
+ current = new_child
+ else:
+ current = current['children'][part]
+ if current['values'] is None:
+ current['values'] = NodeList([], [], [])
+ current['values'][section].append(value)
+
+ def prefix_search(self, key):
+ """Collect all items that are prefixes of key.
+
+ Prefix in this case are delineated by '.' characters so
+ 'foo.bar.baz' is a 3 chunk sequence of 3 "prefixes" (
+ "foo", "bar", and "baz").
+
+ """
+ collected = deque()
+ key_parts = key.split('.')
+ current = self._root
+ self._get_items(current, key_parts, collected, 0)
+ return collected
+
+ def _get_items(self, starting_node, key_parts, collected, starting_index):
+ stack = [(starting_node, starting_index)]
+ key_parts_len = len(key_parts)
+ # Traverse down the nodes, where at each level we add the
+ # next part from key_parts as well as the wildcard element '*'.
+ # This means for each node we see we potentially add two more
+ # elements to our stack.
+ while stack:
+ current_node, index = stack.pop()
+ if current_node['values']:
+ # We're using extendleft because we want
+ # the values associated with the node furthest
+ # from the root to come before nodes closer
+ # to the root. extendleft() also adds its items
+ # in right-left order so .extendleft([1, 2, 3])
+ # will result in final_list = [3, 2, 1], which is
+ # why we reverse the lists.
+ node_list = current_node['values']
+ complete_order = (
+ node_list.first + node_list.middle + node_list.last
+ )
+ collected.extendleft(reversed(complete_order))
+ if not index == key_parts_len:
+ children = current_node['children']
+ directs = children.get(key_parts[index])
+ wildcard = children.get('*')
+ next_index = index + 1
+ if wildcard is not None:
+ stack.append((wildcard, next_index))
+ if directs is not None:
+ stack.append((directs, next_index))
+
+ def remove_item(self, key, value):
+ """Remove an item associated with a key.
+
+ If the value is not associated with the key a ``ValueError``
+ will be raised. If the key does not exist in the trie, a
+ ``ValueError`` will be raised.
+
+ """
+ key_parts = key.split('.')
+ current = self._root
+ self._remove_item(current, key_parts, value, index=0)
+
+ def _remove_item(self, current_node, key_parts, value, index):
+ if current_node is None:
+ return
+ elif index < len(key_parts):
+ next_node = current_node['children'].get(key_parts[index])
+ if next_node is not None:
+ self._remove_item(next_node, key_parts, value, index + 1)
+ if index == len(key_parts) - 1:
+ node_list = next_node['values']
+ if value in node_list.first:
+ node_list.first.remove(value)
+ elif value in node_list.middle:
+ node_list.middle.remove(value)
+ elif value in node_list.last:
+ node_list.last.remove(value)
+ if not next_node['children'] and not next_node['values']:
+ # Then this is a leaf node with no values so
+ # we can just delete this link from the parent node.
+ # This makes subsequent search faster in the case
+ # where a key does not exist.
+ del current_node['children'][key_parts[index]]
+ else:
+ raise ValueError(f"key is not in trie: {'.'.join(key_parts)}")
+
+ def __copy__(self):
+ # The fact that we're using a nested dict under the covers
+ # is an implementation detail, and the user shouldn't have
+ # to know that they'd normally need a deepcopy so we expose
+ # __copy__ instead of __deepcopy__.
+ new_copy = self.__class__()
+ copied_attrs = self._recursive_copy(self.__dict__)
+ new_copy.__dict__ = copied_attrs
+ return new_copy
+
+ def _recursive_copy(self, node):
+ # We can't use copy.deepcopy because we actually only want to copy
+ # the structure of the trie, not the handlers themselves.
+ # Each node has a chunk, children, and values.
+ copied_node = {}
+ for key, value in node.items():
+ if isinstance(value, NodeList):
+ copied_node[key] = copy.copy(value)
+ elif isinstance(value, dict):
+ copied_node[key] = self._recursive_copy(value)
+ else:
+ copied_node[key] = value
+ return copied_node
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/httpchecksum.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/httpchecksum.py
new file mode 100644
index 0000000000..3e812c65e7
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/httpchecksum.py
@@ -0,0 +1,483 @@
+# Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+""" The interfaces in this module are not intended for public use.
+
+This module defines interfaces for applying checksums to HTTP requests within
+the context of botocore. This involves both resolving the checksum to be used
+based on client configuration and environment, as well as application of the
+checksum to the request.
+"""
+import base64
+import io
+import logging
+from binascii import crc32
+from hashlib import sha1, sha256
+
+from botocore.compat import HAS_CRT
+from botocore.exceptions import (
+ AwsChunkedWrapperError,
+ FlexibleChecksumError,
+ MissingDependencyException,
+)
+from botocore.response import StreamingBody
+from botocore.utils import (
+ conditionally_calculate_md5,
+ determine_content_length,
+)
+
+if HAS_CRT:
+ from awscrt import checksums as crt_checksums
+else:
+ crt_checksums = None
+
+logger = logging.getLogger(__name__)
+
+
+class BaseChecksum:
+ _CHUNK_SIZE = 1024 * 1024
+
+ def update(self, chunk):
+ pass
+
+ def digest(self):
+ pass
+
+ def b64digest(self):
+ bs = self.digest()
+ return base64.b64encode(bs).decode("ascii")
+
+ def _handle_fileobj(self, fileobj):
+ start_position = fileobj.tell()
+ for chunk in iter(lambda: fileobj.read(self._CHUNK_SIZE), b""):
+ self.update(chunk)
+ fileobj.seek(start_position)
+
+ def handle(self, body):
+ if isinstance(body, (bytes, bytearray)):
+ self.update(body)
+ else:
+ self._handle_fileobj(body)
+ return self.b64digest()
+
+
+class Crc32Checksum(BaseChecksum):
+ def __init__(self):
+ self._int_crc32 = 0
+
+ def update(self, chunk):
+ self._int_crc32 = crc32(chunk, self._int_crc32) & 0xFFFFFFFF
+
+ def digest(self):
+ return self._int_crc32.to_bytes(4, byteorder="big")
+
+
+class CrtCrc32Checksum(BaseChecksum):
+ # Note: This class is only used if the CRT is available
+ def __init__(self):
+ self._int_crc32 = 0
+
+ def update(self, chunk):
+ new_checksum = crt_checksums.crc32(chunk, self._int_crc32)
+ self._int_crc32 = new_checksum & 0xFFFFFFFF
+
+ def digest(self):
+ return self._int_crc32.to_bytes(4, byteorder="big")
+
+
+class CrtCrc32cChecksum(BaseChecksum):
+ # Note: This class is only used if the CRT is available
+ def __init__(self):
+ self._int_crc32c = 0
+
+ def update(self, chunk):
+ new_checksum = crt_checksums.crc32c(chunk, self._int_crc32c)
+ self._int_crc32c = new_checksum & 0xFFFFFFFF
+
+ def digest(self):
+ return self._int_crc32c.to_bytes(4, byteorder="big")
+
+
+class Sha1Checksum(BaseChecksum):
+ def __init__(self):
+ self._checksum = sha1()
+
+ def update(self, chunk):
+ self._checksum.update(chunk)
+
+ def digest(self):
+ return self._checksum.digest()
+
+
+class Sha256Checksum(BaseChecksum):
+ def __init__(self):
+ self._checksum = sha256()
+
+ def update(self, chunk):
+ self._checksum.update(chunk)
+
+ def digest(self):
+ return self._checksum.digest()
+
+
+class AwsChunkedWrapper:
+ _DEFAULT_CHUNK_SIZE = 1024 * 1024
+
+ def __init__(
+ self,
+ raw,
+ checksum_cls=None,
+ checksum_name="x-amz-checksum",
+ chunk_size=None,
+ ):
+ self._raw = raw
+ self._checksum_name = checksum_name
+ self._checksum_cls = checksum_cls
+ self._reset()
+
+ if chunk_size is None:
+ chunk_size = self._DEFAULT_CHUNK_SIZE
+ self._chunk_size = chunk_size
+
+ def _reset(self):
+ self._remaining = b""
+ self._complete = False
+ self._checksum = None
+ if self._checksum_cls:
+ self._checksum = self._checksum_cls()
+
+ def seek(self, offset, whence=0):
+ if offset != 0 or whence != 0:
+ raise AwsChunkedWrapperError(
+ error_msg="Can only seek to start of stream"
+ )
+ self._reset()
+ self._raw.seek(0)
+
+ def read(self, size=None):
+ # Normalize "read all" size values to None
+ if size is not None and size <= 0:
+ size = None
+
+ # If the underlying body is done and we have nothing left then
+ # end the stream
+ if self._complete and not self._remaining:
+ return b""
+
+ # While we're not done and want more bytes
+ want_more_bytes = size is None or size > len(self._remaining)
+ while not self._complete and want_more_bytes:
+ self._remaining += self._make_chunk()
+ want_more_bytes = size is None or size > len(self._remaining)
+
+ # If size was None, we want to return everything
+ if size is None:
+ size = len(self._remaining)
+
+ # Return a chunk up to the size asked for
+ to_return = self._remaining[:size]
+ self._remaining = self._remaining[size:]
+ return to_return
+
+ def _make_chunk(self):
+ # NOTE: Chunk size is not deterministic as read could return less. This
+ # means we cannot know the content length of the encoded aws-chunked
+ # stream ahead of time without ensuring a consistent chunk size
+ raw_chunk = self._raw.read(self._chunk_size)
+ hex_len = hex(len(raw_chunk))[2:].encode("ascii")
+ self._complete = not raw_chunk
+
+ if self._checksum:
+ self._checksum.update(raw_chunk)
+
+ if self._checksum and self._complete:
+ name = self._checksum_name.encode("ascii")
+ checksum = self._checksum.b64digest().encode("ascii")
+ return b"0\r\n%s:%s\r\n\r\n" % (name, checksum)
+
+ return b"%s\r\n%s\r\n" % (hex_len, raw_chunk)
+
+ def __iter__(self):
+ while not self._complete:
+ yield self._make_chunk()
+
+
+class StreamingChecksumBody(StreamingBody):
+ def __init__(self, raw_stream, content_length, checksum, expected):
+ super().__init__(raw_stream, content_length)
+ self._checksum = checksum
+ self._expected = expected
+
+ def read(self, amt=None):
+ chunk = super().read(amt=amt)
+ self._checksum.update(chunk)
+ if amt is None or (not chunk and amt > 0):
+ self._validate_checksum()
+ return chunk
+
+ def _validate_checksum(self):
+ if self._checksum.digest() != base64.b64decode(self._expected):
+ error_msg = (
+ f"Expected checksum {self._expected} did not match calculated "
+ f"checksum: {self._checksum.b64digest()}"
+ )
+ raise FlexibleChecksumError(error_msg=error_msg)
+
+
+def resolve_checksum_context(request, operation_model, params):
+ resolve_request_checksum_algorithm(request, operation_model, params)
+ resolve_response_checksum_algorithms(request, operation_model, params)
+
+
+def resolve_request_checksum_algorithm(
+ request,
+ operation_model,
+ params,
+ supported_algorithms=None,
+):
+ http_checksum = operation_model.http_checksum
+ algorithm_member = http_checksum.get("requestAlgorithmMember")
+ if algorithm_member and algorithm_member in params:
+ # If the client has opted into using flexible checksums and the
+ # request supports it, use that instead of checksum required
+ if supported_algorithms is None:
+ supported_algorithms = _SUPPORTED_CHECKSUM_ALGORITHMS
+
+ algorithm_name = params[algorithm_member].lower()
+ if algorithm_name not in supported_algorithms:
+ if not HAS_CRT and algorithm_name in _CRT_CHECKSUM_ALGORITHMS:
+ raise MissingDependencyException(
+ msg=(
+ f"Using {algorithm_name.upper()} requires an "
+ "additional dependency. You will need to pip install "
+ "botocore[crt] before proceeding."
+ )
+ )
+ raise FlexibleChecksumError(
+ error_msg="Unsupported checksum algorithm: %s" % algorithm_name
+ )
+
+ location_type = "header"
+ if operation_model.has_streaming_input:
+ # Operations with streaming input must support trailers.
+ if request["url"].startswith("https:"):
+ # We only support unsigned trailer checksums currently. As this
+ # disables payload signing we'll only use trailers over TLS.
+ location_type = "trailer"
+
+ algorithm = {
+ "algorithm": algorithm_name,
+ "in": location_type,
+ "name": "x-amz-checksum-%s" % algorithm_name,
+ }
+
+ if algorithm["name"] in request["headers"]:
+ # If the header is already set by the customer, skip calculation
+ return
+
+ checksum_context = request["context"].get("checksum", {})
+ checksum_context["request_algorithm"] = algorithm
+ request["context"]["checksum"] = checksum_context
+ elif operation_model.http_checksum_required or http_checksum.get(
+ "requestChecksumRequired"
+ ):
+ # Otherwise apply the old http checksum behavior via Content-MD5
+ checksum_context = request["context"].get("checksum", {})
+ checksum_context["request_algorithm"] = "conditional-md5"
+ request["context"]["checksum"] = checksum_context
+
+
+def apply_request_checksum(request):
+ checksum_context = request.get("context", {}).get("checksum", {})
+ algorithm = checksum_context.get("request_algorithm")
+
+ if not algorithm:
+ return
+
+ if algorithm == "conditional-md5":
+ # Special case to handle the http checksum required trait
+ conditionally_calculate_md5(request)
+ elif algorithm["in"] == "header":
+ _apply_request_header_checksum(request)
+ elif algorithm["in"] == "trailer":
+ _apply_request_trailer_checksum(request)
+ else:
+ raise FlexibleChecksumError(
+ error_msg="Unknown checksum variant: %s" % algorithm["in"]
+ )
+
+
+def _apply_request_header_checksum(request):
+ checksum_context = request.get("context", {}).get("checksum", {})
+ algorithm = checksum_context.get("request_algorithm")
+ location_name = algorithm["name"]
+ if location_name in request["headers"]:
+ # If the header is already set by the customer, skip calculation
+ return
+ checksum_cls = _CHECKSUM_CLS.get(algorithm["algorithm"])
+ digest = checksum_cls().handle(request["body"])
+ request["headers"][location_name] = digest
+
+
+def _apply_request_trailer_checksum(request):
+ checksum_context = request.get("context", {}).get("checksum", {})
+ algorithm = checksum_context.get("request_algorithm")
+ location_name = algorithm["name"]
+ checksum_cls = _CHECKSUM_CLS.get(algorithm["algorithm"])
+
+ headers = request["headers"]
+ body = request["body"]
+
+ if location_name in headers:
+ # If the header is already set by the customer, skip calculation
+ return
+
+ headers["Transfer-Encoding"] = "chunked"
+ if "Content-Encoding" in headers:
+ # We need to preserve the existing content encoding and add
+ # aws-chunked as a new content encoding.
+ headers["Content-Encoding"] += ",aws-chunked"
+ else:
+ headers["Content-Encoding"] = "aws-chunked"
+ headers["X-Amz-Trailer"] = location_name
+
+ content_length = determine_content_length(body)
+ if content_length is not None:
+ # Send the decoded content length if we can determine it. Some
+ # services such as S3 may require the decoded content length
+ headers["X-Amz-Decoded-Content-Length"] = str(content_length)
+
+ if isinstance(body, (bytes, bytearray)):
+ body = io.BytesIO(body)
+
+ request["body"] = AwsChunkedWrapper(
+ body,
+ checksum_cls=checksum_cls,
+ checksum_name=location_name,
+ )
+
+
+def resolve_response_checksum_algorithms(
+ request, operation_model, params, supported_algorithms=None
+):
+ http_checksum = operation_model.http_checksum
+ mode_member = http_checksum.get("requestValidationModeMember")
+ if mode_member and mode_member in params:
+ if supported_algorithms is None:
+ supported_algorithms = _SUPPORTED_CHECKSUM_ALGORITHMS
+ response_algorithms = {
+ a.lower() for a in http_checksum.get("responseAlgorithms", [])
+ }
+
+ usable_algorithms = []
+ for algorithm in _ALGORITHMS_PRIORITY_LIST:
+ if algorithm not in response_algorithms:
+ continue
+ if algorithm in supported_algorithms:
+ usable_algorithms.append(algorithm)
+
+ checksum_context = request["context"].get("checksum", {})
+ checksum_context["response_algorithms"] = usable_algorithms
+ request["context"]["checksum"] = checksum_context
+
+
+def handle_checksum_body(http_response, response, context, operation_model):
+ headers = response["headers"]
+ checksum_context = context.get("checksum", {})
+ algorithms = checksum_context.get("response_algorithms")
+
+ if not algorithms:
+ return
+
+ for algorithm in algorithms:
+ header_name = "x-amz-checksum-%s" % algorithm
+ # If the header is not found, check the next algorithm
+ if header_name not in headers:
+ continue
+
+ # If a - is in the checksum this is not valid Base64. S3 returns
+ # checksums that include a -# suffix to indicate a checksum derived
+ # from the hash of all part checksums. We cannot wrap this response
+ if "-" in headers[header_name]:
+ continue
+
+ if operation_model.has_streaming_output:
+ response["body"] = _handle_streaming_response(
+ http_response, response, algorithm
+ )
+ else:
+ response["body"] = _handle_bytes_response(
+ http_response, response, algorithm
+ )
+
+ # Expose metadata that the checksum check actually occurred
+ checksum_context = response["context"].get("checksum", {})
+ checksum_context["response_algorithm"] = algorithm
+ response["context"]["checksum"] = checksum_context
+ return
+
+ logger.info(
+ f'Skipping checksum validation. Response did not contain one of the '
+ f'following algorithms: {algorithms}.'
+ )
+
+
+def _handle_streaming_response(http_response, response, algorithm):
+ checksum_cls = _CHECKSUM_CLS.get(algorithm)
+ header_name = "x-amz-checksum-%s" % algorithm
+ return StreamingChecksumBody(
+ http_response.raw,
+ response["headers"].get("content-length"),
+ checksum_cls(),
+ response["headers"][header_name],
+ )
+
+
+def _handle_bytes_response(http_response, response, algorithm):
+ body = http_response.content
+ header_name = "x-amz-checksum-%s" % algorithm
+ checksum_cls = _CHECKSUM_CLS.get(algorithm)
+ checksum = checksum_cls()
+ checksum.update(body)
+ expected = response["headers"][header_name]
+ if checksum.digest() != base64.b64decode(expected):
+ error_msg = (
+ "Expected checksum %s did not match calculated checksum: %s"
+ % (
+ expected,
+ checksum.b64digest(),
+ )
+ )
+ raise FlexibleChecksumError(error_msg=error_msg)
+ return body
+
+
+_CHECKSUM_CLS = {
+ "crc32": Crc32Checksum,
+ "sha1": Sha1Checksum,
+ "sha256": Sha256Checksum,
+}
+_CRT_CHECKSUM_ALGORITHMS = ["crc32", "crc32c"]
+if HAS_CRT:
+ # Use CRT checksum implementations if available
+ _CRT_CHECKSUM_CLS = {
+ "crc32": CrtCrc32Checksum,
+ "crc32c": CrtCrc32cChecksum,
+ }
+ _CHECKSUM_CLS.update(_CRT_CHECKSUM_CLS)
+ # Validate this list isn't out of sync with _CRT_CHECKSUM_CLS keys
+ assert all(
+ name in _CRT_CHECKSUM_ALGORITHMS for name in _CRT_CHECKSUM_CLS.keys()
+ )
+_SUPPORTED_CHECKSUM_ALGORITHMS = list(_CHECKSUM_CLS.keys())
+_ALGORITHMS_PRIORITY_LIST = ['crc32c', 'crc32', 'sha1', 'sha256']
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/httpsession.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/httpsession.py
new file mode 100644
index 0000000000..bd8b82fafa
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/httpsession.py
@@ -0,0 +1,509 @@
+import logging
+import os
+import os.path
+import socket
+import sys
+import warnings
+from base64 import b64encode
+
+from urllib3 import PoolManager, Timeout, proxy_from_url
+from urllib3.exceptions import (
+ ConnectTimeoutError as URLLib3ConnectTimeoutError,
+)
+from urllib3.exceptions import (
+ LocationParseError,
+ NewConnectionError,
+ ProtocolError,
+ ProxyError,
+)
+from urllib3.exceptions import ReadTimeoutError as URLLib3ReadTimeoutError
+from urllib3.exceptions import SSLError as URLLib3SSLError
+from urllib3.util.retry import Retry
+from urllib3.util.ssl_ import (
+ OP_NO_COMPRESSION,
+ PROTOCOL_TLS,
+ OP_NO_SSLv2,
+ OP_NO_SSLv3,
+ is_ipaddress,
+ ssl,
+)
+from urllib3.util.url import parse_url
+
+try:
+ from urllib3.util.ssl_ import OP_NO_TICKET, PROTOCOL_TLS_CLIENT
+except ImportError:
+ # Fallback directly to ssl for version of urllib3 before 1.26.
+ # They are available in the standard library starting in Python 3.6.
+ from ssl import OP_NO_TICKET, PROTOCOL_TLS_CLIENT
+
+try:
+ # pyopenssl will be removed in urllib3 2.0, we'll fall back to ssl_ at that point.
+ # This can be removed once our urllib3 floor is raised to >= 2.0.
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", category=DeprecationWarning)
+ # Always import the original SSLContext, even if it has been patched
+ from urllib3.contrib.pyopenssl import (
+ orig_util_SSLContext as SSLContext,
+ )
+except ImportError:
+ from urllib3.util.ssl_ import SSLContext
+
+try:
+ from urllib3.util.ssl_ import DEFAULT_CIPHERS
+except ImportError:
+ # Defer to system configuration starting with
+ # urllib3 2.0. This will choose the ciphers provided by
+ # Openssl 1.1.1+ or secure system defaults.
+ DEFAULT_CIPHERS = None
+
+import botocore.awsrequest
+from botocore.compat import (
+ IPV6_ADDRZ_RE,
+ ensure_bytes,
+ filter_ssl_warnings,
+ unquote,
+ urlparse,
+)
+from botocore.exceptions import (
+ ConnectionClosedError,
+ ConnectTimeoutError,
+ EndpointConnectionError,
+ HTTPClientError,
+ InvalidProxiesConfigError,
+ ProxyConnectionError,
+ ReadTimeoutError,
+ SSLError,
+)
+
+filter_ssl_warnings()
+logger = logging.getLogger(__name__)
+DEFAULT_TIMEOUT = 60
+MAX_POOL_CONNECTIONS = 10
+DEFAULT_CA_BUNDLE = os.path.join(os.path.dirname(__file__), 'cacert.pem')
+
+try:
+ from certifi import where
+except ImportError:
+
+ def where():
+ return DEFAULT_CA_BUNDLE
+
+
+def get_cert_path(verify):
+ if verify is not True:
+ return verify
+
+ cert_path = where()
+ logger.debug(f"Certificate path: {cert_path}")
+
+ return cert_path
+
+
+def create_urllib3_context(
+ ssl_version=None, cert_reqs=None, options=None, ciphers=None
+):
+ """This function is a vendored version of the same function in urllib3
+
+ We vendor this function to ensure that the SSL contexts we construct
+ always use the std lib SSLContext instead of pyopenssl.
+ """
+ # PROTOCOL_TLS is deprecated in Python 3.10
+ if not ssl_version or ssl_version == PROTOCOL_TLS:
+ ssl_version = PROTOCOL_TLS_CLIENT
+
+ context = SSLContext(ssl_version)
+
+ if ciphers:
+ context.set_ciphers(ciphers)
+ elif DEFAULT_CIPHERS:
+ context.set_ciphers(DEFAULT_CIPHERS)
+
+ # Setting the default here, as we may have no ssl module on import
+ cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
+
+ if options is None:
+ options = 0
+ # SSLv2 is easily broken and is considered harmful and dangerous
+ options |= OP_NO_SSLv2
+ # SSLv3 has several problems and is now dangerous
+ options |= OP_NO_SSLv3
+ # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
+ # (issue urllib3#309)
+ options |= OP_NO_COMPRESSION
+ # TLSv1.2 only. Unless set explicitly, do not request tickets.
+ # This may save some bandwidth on wire, and although the ticket is encrypted,
+ # there is a risk associated with it being on wire,
+ # if the server is not rotating its ticketing keys properly.
+ options |= OP_NO_TICKET
+
+ context.options |= options
+
+ # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
+ # necessary for conditional client cert authentication with TLS 1.3.
+ # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
+ # versions of Python. We only enable on Python 3.7.4+ or if certificate
+ # verification is enabled to work around Python issue #37428
+ # See: https://bugs.python.org/issue37428
+ if (
+ cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)
+ ) and getattr(context, "post_handshake_auth", None) is not None:
+ context.post_handshake_auth = True
+
+ def disable_check_hostname():
+ if (
+ getattr(context, "check_hostname", None) is not None
+ ): # Platform-specific: Python 3.2
+ # We do our own verification, including fingerprints and alternative
+ # hostnames. So disable it here
+ context.check_hostname = False
+
+ # The order of the below lines setting verify_mode and check_hostname
+ # matter due to safe-guards SSLContext has to prevent an SSLContext with
+ # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more
+ # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used
+ # or not so we don't know the initial state of the freshly created SSLContext.
+ if cert_reqs == ssl.CERT_REQUIRED:
+ context.verify_mode = cert_reqs
+ disable_check_hostname()
+ else:
+ disable_check_hostname()
+ context.verify_mode = cert_reqs
+
+ # Enable logging of TLS session keys via defacto standard environment variable
+ # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
+ if hasattr(context, "keylog_filename"):
+ sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
+ if sslkeylogfile and not sys.flags.ignore_environment:
+ context.keylog_filename = sslkeylogfile
+
+ return context
+
+
+def ensure_boolean(val):
+ """Ensures a boolean value if a string or boolean is provided
+
+ For strings, the value for True/False is case insensitive
+ """
+ if isinstance(val, bool):
+ return val
+ else:
+ return val.lower() == 'true'
+
+
+def mask_proxy_url(proxy_url):
+ """
+ Mask proxy url credentials.
+
+ :type proxy_url: str
+ :param proxy_url: The proxy url, i.e. https://username:password@proxy.com
+
+ :return: Masked proxy url, i.e. https://***:***@proxy.com
+ """
+ mask = '*' * 3
+ parsed_url = urlparse(proxy_url)
+ if parsed_url.username:
+ proxy_url = proxy_url.replace(parsed_url.username, mask, 1)
+ if parsed_url.password:
+ proxy_url = proxy_url.replace(parsed_url.password, mask, 1)
+ return proxy_url
+
+
+def _is_ipaddress(host):
+ """Wrap urllib3's is_ipaddress to support bracketed IPv6 addresses."""
+ return is_ipaddress(host) or bool(IPV6_ADDRZ_RE.match(host))
+
+
+class ProxyConfiguration:
+ """Represents a proxy configuration dictionary and additional settings.
+
+ This class represents a proxy configuration dictionary and provides utility
+ functions to retrieve well structured proxy urls and proxy headers from the
+ proxy configuration dictionary.
+ """
+
+ def __init__(self, proxies=None, proxies_settings=None):
+ if proxies is None:
+ proxies = {}
+ if proxies_settings is None:
+ proxies_settings = {}
+
+ self._proxies = proxies
+ self._proxies_settings = proxies_settings
+
+ def proxy_url_for(self, url):
+ """Retrieves the corresponding proxy url for a given url."""
+ parsed_url = urlparse(url)
+ proxy = self._proxies.get(parsed_url.scheme)
+ if proxy:
+ proxy = self._fix_proxy_url(proxy)
+ return proxy
+
+ def proxy_headers_for(self, proxy_url):
+ """Retrieves the corresponding proxy headers for a given proxy url."""
+ headers = {}
+ username, password = self._get_auth_from_url(proxy_url)
+ if username and password:
+ basic_auth = self._construct_basic_auth(username, password)
+ headers['Proxy-Authorization'] = basic_auth
+ return headers
+
+ @property
+ def settings(self):
+ return self._proxies_settings
+
+ def _fix_proxy_url(self, proxy_url):
+ if proxy_url.startswith('http:') or proxy_url.startswith('https:'):
+ return proxy_url
+ elif proxy_url.startswith('//'):
+ return 'http:' + proxy_url
+ else:
+ return 'http://' + proxy_url
+
+ def _construct_basic_auth(self, username, password):
+ auth_str = f'{username}:{password}'
+ encoded_str = b64encode(auth_str.encode('ascii')).strip().decode()
+ return f'Basic {encoded_str}'
+
+ def _get_auth_from_url(self, url):
+ parsed_url = urlparse(url)
+ try:
+ return unquote(parsed_url.username), unquote(parsed_url.password)
+ except (AttributeError, TypeError):
+ return None, None
+
+
+class URLLib3Session:
+ """A basic HTTP client that supports connection pooling and proxies.
+
+ This class is inspired by requests.adapters.HTTPAdapter, but has been
+ boiled down to meet the use cases needed by botocore. For the most part
+ this classes matches the functionality of HTTPAdapter in requests v2.7.0
+ (the same as our vendored version). The only major difference of note is
+ that we currently do not support sending chunked requests. While requests
+ v2.7.0 implemented this themselves, later version urllib3 support this
+ directly via a flag to urlopen so enabling it if needed should be trivial.
+ """
+
+ def __init__(
+ self,
+ verify=True,
+ proxies=None,
+ timeout=None,
+ max_pool_connections=MAX_POOL_CONNECTIONS,
+ socket_options=None,
+ client_cert=None,
+ proxies_config=None,
+ ):
+ self._verify = verify
+ self._proxy_config = ProxyConfiguration(
+ proxies=proxies, proxies_settings=proxies_config
+ )
+ self._pool_classes_by_scheme = {
+ 'http': botocore.awsrequest.AWSHTTPConnectionPool,
+ 'https': botocore.awsrequest.AWSHTTPSConnectionPool,
+ }
+ if timeout is None:
+ timeout = DEFAULT_TIMEOUT
+ if not isinstance(timeout, (int, float)):
+ timeout = Timeout(connect=timeout[0], read=timeout[1])
+
+ self._cert_file = None
+ self._key_file = None
+ if isinstance(client_cert, str):
+ self._cert_file = client_cert
+ elif isinstance(client_cert, tuple):
+ self._cert_file, self._key_file = client_cert
+
+ self._timeout = timeout
+ self._max_pool_connections = max_pool_connections
+ self._socket_options = socket_options
+ if socket_options is None:
+ self._socket_options = []
+ self._proxy_managers = {}
+ self._manager = PoolManager(**self._get_pool_manager_kwargs())
+ self._manager.pool_classes_by_scheme = self._pool_classes_by_scheme
+
+ def _proxies_kwargs(self, **kwargs):
+ proxies_settings = self._proxy_config.settings
+ proxies_kwargs = {
+ 'use_forwarding_for_https': proxies_settings.get(
+ 'proxy_use_forwarding_for_https'
+ ),
+ **kwargs,
+ }
+ return {k: v for k, v in proxies_kwargs.items() if v is not None}
+
+ def _get_pool_manager_kwargs(self, **extra_kwargs):
+ pool_manager_kwargs = {
+ 'timeout': self._timeout,
+ 'maxsize': self._max_pool_connections,
+ 'ssl_context': self._get_ssl_context(),
+ 'socket_options': self._socket_options,
+ 'cert_file': self._cert_file,
+ 'key_file': self._key_file,
+ }
+ pool_manager_kwargs.update(**extra_kwargs)
+ return pool_manager_kwargs
+
+ def _get_ssl_context(self):
+ return create_urllib3_context()
+
+ def _get_proxy_manager(self, proxy_url):
+ if proxy_url not in self._proxy_managers:
+ proxy_headers = self._proxy_config.proxy_headers_for(proxy_url)
+ proxy_ssl_context = self._setup_proxy_ssl_context(proxy_url)
+ proxy_manager_kwargs = self._get_pool_manager_kwargs(
+ proxy_headers=proxy_headers
+ )
+ proxy_manager_kwargs.update(
+ self._proxies_kwargs(proxy_ssl_context=proxy_ssl_context)
+ )
+ proxy_manager = proxy_from_url(proxy_url, **proxy_manager_kwargs)
+ proxy_manager.pool_classes_by_scheme = self._pool_classes_by_scheme
+ self._proxy_managers[proxy_url] = proxy_manager
+
+ return self._proxy_managers[proxy_url]
+
+ def _path_url(self, url):
+ parsed_url = urlparse(url)
+ path = parsed_url.path
+ if not path:
+ path = '/'
+ if parsed_url.query:
+ path = path + '?' + parsed_url.query
+ return path
+
+ def _setup_ssl_cert(self, conn, url, verify):
+ if url.lower().startswith('https') and verify:
+ conn.cert_reqs = 'CERT_REQUIRED'
+ conn.ca_certs = get_cert_path(verify)
+ else:
+ conn.cert_reqs = 'CERT_NONE'
+ conn.ca_certs = None
+
+ def _setup_proxy_ssl_context(self, proxy_url):
+ proxies_settings = self._proxy_config.settings
+ proxy_ca_bundle = proxies_settings.get('proxy_ca_bundle')
+ proxy_cert = proxies_settings.get('proxy_client_cert')
+ if proxy_ca_bundle is None and proxy_cert is None:
+ return None
+
+ context = self._get_ssl_context()
+ try:
+ url = parse_url(proxy_url)
+ # urllib3 disables this by default but we need it for proper
+ # proxy tls negotiation when proxy_url is not an IP Address
+ if not _is_ipaddress(url.host):
+ context.check_hostname = True
+ if proxy_ca_bundle is not None:
+ context.load_verify_locations(cafile=proxy_ca_bundle)
+
+ if isinstance(proxy_cert, tuple):
+ context.load_cert_chain(proxy_cert[0], keyfile=proxy_cert[1])
+ elif isinstance(proxy_cert, str):
+ context.load_cert_chain(proxy_cert)
+
+ return context
+ except (OSError, URLLib3SSLError, LocationParseError) as e:
+ raise InvalidProxiesConfigError(error=e)
+
+ def _get_connection_manager(self, url, proxy_url=None):
+ if proxy_url:
+ manager = self._get_proxy_manager(proxy_url)
+ else:
+ manager = self._manager
+ return manager
+
+ def _get_request_target(self, url, proxy_url):
+ has_proxy = proxy_url is not None
+
+ if not has_proxy:
+ return self._path_url(url)
+
+ # HTTP proxies expect the request_target to be the absolute url to know
+ # which host to establish a connection to. urllib3 also supports
+ # forwarding for HTTPS through the 'use_forwarding_for_https' parameter.
+ proxy_scheme = urlparse(proxy_url).scheme
+ using_https_forwarding_proxy = (
+ proxy_scheme == 'https'
+ and self._proxies_kwargs().get('use_forwarding_for_https', False)
+ )
+
+ if using_https_forwarding_proxy or url.startswith('http:'):
+ return url
+ else:
+ return self._path_url(url)
+
+ def _chunked(self, headers):
+ transfer_encoding = headers.get('Transfer-Encoding', b'')
+ transfer_encoding = ensure_bytes(transfer_encoding)
+ return transfer_encoding.lower() == b'chunked'
+
+ def close(self):
+ self._manager.clear()
+ for manager in self._proxy_managers.values():
+ manager.clear()
+
+ def send(self, request):
+ try:
+ proxy_url = self._proxy_config.proxy_url_for(request.url)
+ manager = self._get_connection_manager(request.url, proxy_url)
+ conn = manager.connection_from_url(request.url)
+ self._setup_ssl_cert(conn, request.url, self._verify)
+ if ensure_boolean(
+ os.environ.get('BOTO_EXPERIMENTAL__ADD_PROXY_HOST_HEADER', '')
+ ):
+ # This is currently an "experimental" feature which provides
+ # no guarantees of backwards compatibility. It may be subject
+ # to change or removal in any patch version. Anyone opting in
+ # to this feature should strictly pin botocore.
+ host = urlparse(request.url).hostname
+ conn.proxy_headers['host'] = host
+
+ request_target = self._get_request_target(request.url, proxy_url)
+ urllib_response = conn.urlopen(
+ method=request.method,
+ url=request_target,
+ body=request.body,
+ headers=request.headers,
+ retries=Retry(False),
+ assert_same_host=False,
+ preload_content=False,
+ decode_content=False,
+ chunked=self._chunked(request.headers),
+ )
+
+ http_response = botocore.awsrequest.AWSResponse(
+ request.url,
+ urllib_response.status,
+ urllib_response.headers,
+ urllib_response,
+ )
+
+ if not request.stream_output:
+ # Cause the raw stream to be exhausted immediately. We do it
+ # this way instead of using preload_content because
+ # preload_content will never buffer chunked responses
+ http_response.content
+
+ return http_response
+ except URLLib3SSLError as e:
+ raise SSLError(endpoint_url=request.url, error=e)
+ except (NewConnectionError, socket.gaierror) as e:
+ raise EndpointConnectionError(endpoint_url=request.url, error=e)
+ except ProxyError as e:
+ raise ProxyConnectionError(
+ proxy_url=mask_proxy_url(proxy_url), error=e
+ )
+ except URLLib3ConnectTimeoutError as e:
+ raise ConnectTimeoutError(endpoint_url=request.url, error=e)
+ except URLLib3ReadTimeoutError as e:
+ raise ReadTimeoutError(endpoint_url=request.url, error=e)
+ except ProtocolError as e:
+ raise ConnectionClosedError(
+ error=e, request=request, endpoint_url=request.url
+ )
+ except Exception as e:
+ message = 'Exception received when sending urllib3 HTTP request'
+ logger.debug(message, exc_info=True)
+ raise HTTPClientError(error=e)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/loaders.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/loaders.py
new file mode 100644
index 0000000000..2baf4196fc
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/loaders.py
@@ -0,0 +1,524 @@
+# Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""Module for loading various model files.
+
+This module provides the classes that are used to load models used
+by botocore. This can include:
+
+ * Service models (e.g. the model for EC2, S3, DynamoDB, etc.)
+ * Service model extras which customize the service models
+ * Other models associated with a service (pagination, waiters)
+ * Non service-specific config (Endpoint data, retry config)
+
+Loading a module is broken down into several steps:
+
+ * Determining the path to load
+ * Search the data_path for files to load
+ * The mechanics of loading the file
+ * Searching for extras and applying them to the loaded file
+
+The last item is used so that other faster loading mechanism
+besides the default JSON loader can be used.
+
+The Search Path
+===============
+
+Similar to how the PATH environment variable is to finding executables
+and the PYTHONPATH environment variable is to finding python modules
+to import, the botocore loaders have the concept of a data path exposed
+through AWS_DATA_PATH.
+
+This enables end users to provide additional search paths where we
+will attempt to load models outside of the models we ship with
+botocore. When you create a ``Loader``, there are two paths
+automatically added to the model search path:
+
+ * /data/
+ * ~/.aws/models
+
+The first value is the path where all the model files shipped with
+botocore are located.
+
+The second path is so that users can just drop new model files in
+``~/.aws/models`` without having to mess around with the AWS_DATA_PATH.
+
+The AWS_DATA_PATH using the platform specific path separator to
+separate entries (typically ``:`` on linux and ``;`` on windows).
+
+
+Directory Layout
+================
+
+The Loader expects a particular directory layout. In order for any
+directory specified in AWS_DATA_PATH to be considered, it must have
+this structure for service models::
+
+
+ |
+ |-- servicename1
+ | |-- 2012-10-25
+ | |-- service-2.json
+ |-- ec2
+ | |-- 2014-01-01
+ | | |-- paginators-1.json
+ | | |-- service-2.json
+ | | |-- waiters-2.json
+ | |-- 2015-03-01
+ | |-- paginators-1.json
+ | |-- service-2.json
+ | |-- waiters-2.json
+ | |-- service-2.sdk-extras.json
+
+
+That is:
+
+ * The root directory contains sub directories that are the name
+ of the services.
+ * Within each service directory, there's a sub directory for each
+ available API version.
+ * Within each API version, there are model specific files, including
+ (but not limited to): service-2.json, waiters-2.json, paginators-1.json
+
+The ``-1`` and ``-2`` suffix at the end of the model files denote which version
+schema is used within the model. Even though this information is available in
+the ``version`` key within the model, this version is also part of the filename
+so that code does not need to load the JSON model in order to determine which
+version to use.
+
+The ``sdk-extras`` and similar files represent extra data that needs to be
+applied to the model after it is loaded. Data in these files might represent
+information that doesn't quite fit in the original models, but is still needed
+for the sdk. For instance, additional operation parameters might be added here
+which don't represent the actual service api.
+"""
+import logging
+import os
+
+from botocore import BOTOCORE_ROOT
+from botocore.compat import HAS_GZIP, OrderedDict, json
+from botocore.exceptions import DataNotFoundError, UnknownServiceError
+from botocore.utils import deep_merge
+
+_JSON_OPEN_METHODS = {
+ '.json': open,
+}
+
+
+if HAS_GZIP:
+ from gzip import open as gzip_open
+
+ _JSON_OPEN_METHODS['.json.gz'] = gzip_open
+
+
+logger = logging.getLogger(__name__)
+
+
+def instance_cache(func):
+ """Cache the result of a method on a per instance basis.
+
+ This is not a general purpose caching decorator. In order
+ for this to be used, it must be used on methods on an
+ instance, and that instance *must* provide a
+ ``self._cache`` dictionary.
+
+ """
+
+ def _wrapper(self, *args, **kwargs):
+ key = (func.__name__,) + args
+ for pair in sorted(kwargs.items()):
+ key += pair
+ if key in self._cache:
+ return self._cache[key]
+ data = func(self, *args, **kwargs)
+ self._cache[key] = data
+ return data
+
+ return _wrapper
+
+
+class JSONFileLoader:
+ """Loader JSON files.
+
+ This class can load the default format of models, which is a JSON file.
+
+ """
+
+ def exists(self, file_path):
+ """Checks if the file exists.
+
+ :type file_path: str
+ :param file_path: The full path to the file to load without
+ the '.json' extension.
+
+ :return: True if file path exists, False otherwise.
+
+ """
+ for ext in _JSON_OPEN_METHODS:
+ if os.path.isfile(file_path + ext):
+ return True
+ return False
+
+ def _load_file(self, full_path, open_method):
+ if not os.path.isfile(full_path):
+ return
+
+ # By default the file will be opened with locale encoding on Python 3.
+ # We specify "utf8" here to ensure the correct behavior.
+ with open_method(full_path, 'rb') as fp:
+ payload = fp.read().decode('utf-8')
+
+ logger.debug("Loading JSON file: %s", full_path)
+ return json.loads(payload, object_pairs_hook=OrderedDict)
+
+ def load_file(self, file_path):
+ """Attempt to load the file path.
+
+ :type file_path: str
+ :param file_path: The full path to the file to load without
+ the '.json' extension.
+
+ :return: The loaded data if it exists, otherwise None.
+
+ """
+ for ext, open_method in _JSON_OPEN_METHODS.items():
+ data = self._load_file(file_path + ext, open_method)
+ if data is not None:
+ return data
+ return None
+
+
+def create_loader(search_path_string=None):
+ """Create a Loader class.
+
+ This factory function creates a loader given a search string path.
+
+ :type search_string_path: str
+ :param search_string_path: The AWS_DATA_PATH value. A string
+ of data path values separated by the ``os.path.pathsep`` value,
+ which is typically ``:`` on POSIX platforms and ``;`` on
+ windows.
+
+ :return: A ``Loader`` instance.
+
+ """
+ if search_path_string is None:
+ return Loader()
+ paths = []
+ extra_paths = search_path_string.split(os.pathsep)
+ for path in extra_paths:
+ path = os.path.expanduser(os.path.expandvars(path))
+ paths.append(path)
+ return Loader(extra_search_paths=paths)
+
+
+class Loader:
+ """Find and load data models.
+
+ This class will handle searching for and loading data models.
+
+ The main method used here is ``load_service_model``, which is a
+ convenience method over ``load_data`` and ``determine_latest_version``.
+
+ """
+
+ FILE_LOADER_CLASS = JSONFileLoader
+ # The included models in botocore/data/ that we ship with botocore.
+ BUILTIN_DATA_PATH = os.path.join(BOTOCORE_ROOT, 'data')
+ # For convenience we automatically add ~/.aws/models to the data path.
+ CUSTOMER_DATA_PATH = os.path.join(
+ os.path.expanduser('~'), '.aws', 'models'
+ )
+ BUILTIN_EXTRAS_TYPES = ['sdk']
+
+ def __init__(
+ self,
+ extra_search_paths=None,
+ file_loader=None,
+ cache=None,
+ include_default_search_paths=True,
+ include_default_extras=True,
+ ):
+ self._cache = {}
+ if file_loader is None:
+ file_loader = self.FILE_LOADER_CLASS()
+ self.file_loader = file_loader
+ if extra_search_paths is not None:
+ self._search_paths = extra_search_paths
+ else:
+ self._search_paths = []
+ if include_default_search_paths:
+ self._search_paths.extend(
+ [self.CUSTOMER_DATA_PATH, self.BUILTIN_DATA_PATH]
+ )
+
+ self._extras_types = []
+ if include_default_extras:
+ self._extras_types.extend(self.BUILTIN_EXTRAS_TYPES)
+
+ self._extras_processor = ExtrasProcessor()
+
+ @property
+ def search_paths(self):
+ return self._search_paths
+
+ @property
+ def extras_types(self):
+ return self._extras_types
+
+ @instance_cache
+ def list_available_services(self, type_name):
+ """List all known services.
+
+ This will traverse the search path and look for all known
+ services.
+
+ :type type_name: str
+ :param type_name: The type of the service (service-2,
+ paginators-1, waiters-2, etc). This is needed because
+ the list of available services depends on the service
+ type. For example, the latest API version available for
+ a resource-1.json file may not be the latest API version
+ available for a services-2.json file.
+
+ :return: A list of all services. The list of services will
+ be sorted.
+
+ """
+ services = set()
+ for possible_path in self._potential_locations():
+ # Any directory in the search path is potentially a service.
+ # We'll collect any initial list of potential services,
+ # but we'll then need to further process these directories
+ # by searching for the corresponding type_name in each
+ # potential directory.
+ possible_services = [
+ d
+ for d in os.listdir(possible_path)
+ if os.path.isdir(os.path.join(possible_path, d))
+ ]
+ for service_name in possible_services:
+ full_dirname = os.path.join(possible_path, service_name)
+ api_versions = os.listdir(full_dirname)
+ for api_version in api_versions:
+ full_load_path = os.path.join(
+ full_dirname, api_version, type_name
+ )
+ if self.file_loader.exists(full_load_path):
+ services.add(service_name)
+ break
+ return sorted(services)
+
+ @instance_cache
+ def determine_latest_version(self, service_name, type_name):
+ """Find the latest API version available for a service.
+
+ :type service_name: str
+ :param service_name: The name of the service.
+
+ :type type_name: str
+ :param type_name: The type of the service (service-2,
+ paginators-1, waiters-2, etc). This is needed because
+ the latest API version available can depend on the service
+ type. For example, the latest API version available for
+ a resource-1.json file may not be the latest API version
+ available for a services-2.json file.
+
+ :rtype: str
+ :return: The latest API version. If the service does not exist
+ or does not have any available API data, then a
+ ``DataNotFoundError`` exception will be raised.
+
+ """
+ return max(self.list_api_versions(service_name, type_name))
+
+ @instance_cache
+ def list_api_versions(self, service_name, type_name):
+ """List all API versions available for a particular service type
+
+ :type service_name: str
+ :param service_name: The name of the service
+
+ :type type_name: str
+ :param type_name: The type name for the service (i.e service-2,
+ paginators-1, etc.)
+
+ :rtype: list
+ :return: A list of API version strings in sorted order.
+
+ """
+ known_api_versions = set()
+ for possible_path in self._potential_locations(
+ service_name, must_exist=True, is_dir=True
+ ):
+ for dirname in os.listdir(possible_path):
+ full_path = os.path.join(possible_path, dirname, type_name)
+ # Only add to the known_api_versions if the directory
+ # contains a service-2, paginators-1, etc. file corresponding
+ # to the type_name passed in.
+ if self.file_loader.exists(full_path):
+ known_api_versions.add(dirname)
+ if not known_api_versions:
+ raise DataNotFoundError(data_path=service_name)
+ return sorted(known_api_versions)
+
+ @instance_cache
+ def load_service_model(self, service_name, type_name, api_version=None):
+ """Load a botocore service model
+
+ This is the main method for loading botocore models (e.g. a service
+ model, pagination configs, waiter configs, etc.).
+
+ :type service_name: str
+ :param service_name: The name of the service (e.g ``ec2``, ``s3``).
+
+ :type type_name: str
+ :param type_name: The model type. Valid types include, but are not
+ limited to: ``service-2``, ``paginators-1``, ``waiters-2``.
+
+ :type api_version: str
+ :param api_version: The API version to load. If this is not
+ provided, then the latest API version will be used.
+
+ :type load_extras: bool
+ :param load_extras: Whether or not to load the tool extras which
+ contain additional data to be added to the model.
+
+ :raises: UnknownServiceError if there is no known service with
+ the provided service_name.
+
+ :raises: DataNotFoundError if no data could be found for the
+ service_name/type_name/api_version.
+
+ :return: The loaded data, as a python type (e.g. dict, list, etc).
+ """
+ # Wrapper around the load_data. This will calculate the path
+ # to call load_data with.
+ known_services = self.list_available_services(type_name)
+ if service_name not in known_services:
+ raise UnknownServiceError(
+ service_name=service_name,
+ known_service_names=', '.join(sorted(known_services)),
+ )
+ if api_version is None:
+ api_version = self.determine_latest_version(
+ service_name, type_name
+ )
+ full_path = os.path.join(service_name, api_version, type_name)
+ model = self.load_data(full_path)
+
+ # Load in all the extras
+ extras_data = self._find_extras(service_name, type_name, api_version)
+ self._extras_processor.process(model, extras_data)
+
+ return model
+
+ def _find_extras(self, service_name, type_name, api_version):
+ """Creates an iterator over all the extras data."""
+ for extras_type in self.extras_types:
+ extras_name = f'{type_name}.{extras_type}-extras'
+ full_path = os.path.join(service_name, api_version, extras_name)
+
+ try:
+ yield self.load_data(full_path)
+ except DataNotFoundError:
+ pass
+
+ @instance_cache
+ def load_data_with_path(self, name):
+ """Same as ``load_data`` but returns file path as second return value.
+
+ :type name: str
+ :param name: The data path, i.e ``ec2/2015-03-01/service-2``.
+
+ :return: Tuple of the loaded data and the path to the data file
+ where the data was loaded from. If no data could be found then a
+ DataNotFoundError is raised.
+ """
+ for possible_path in self._potential_locations(name):
+ found = self.file_loader.load_file(possible_path)
+ if found is not None:
+ return found, possible_path
+
+ # We didn't find anything that matched on any path.
+ raise DataNotFoundError(data_path=name)
+
+ def load_data(self, name):
+ """Load data given a data path.
+
+ This is a low level method that will search through the various
+ search paths until it's able to load a value. This is typically
+ only needed to load *non* model files (such as _endpoints and
+ _retry). If you need to load model files, you should prefer
+ ``load_service_model``. Use ``load_data_with_path`` to get the
+ data path of the data file as second return value.
+
+ :type name: str
+ :param name: The data path, i.e ``ec2/2015-03-01/service-2``.
+
+ :return: The loaded data. If no data could be found then
+ a DataNotFoundError is raised.
+ """
+ data, _ = self.load_data_with_path(name)
+ return data
+
+ def _potential_locations(self, name=None, must_exist=False, is_dir=False):
+ # Will give an iterator over the full path of potential locations
+ # according to the search path.
+ for path in self.search_paths:
+ if os.path.isdir(path):
+ full_path = path
+ if name is not None:
+ full_path = os.path.join(path, name)
+ if not must_exist:
+ yield full_path
+ else:
+ if is_dir and os.path.isdir(full_path):
+ yield full_path
+ elif os.path.exists(full_path):
+ yield full_path
+
+ def is_builtin_path(self, path):
+ """Whether a given path is within the package's data directory.
+
+ This method can be used together with load_data_with_path(name)
+ to determine if data has been loaded from a file bundled with the
+ package, as opposed to a file in a separate location.
+
+ :type path: str
+ :param path: The file path to check.
+
+ :return: Whether the given path is within the package's data directory.
+ """
+ path = os.path.expanduser(os.path.expandvars(path))
+ return path.startswith(self.BUILTIN_DATA_PATH)
+
+
+class ExtrasProcessor:
+ """Processes data from extras files into service models."""
+
+ def process(self, original_model, extra_models):
+ """Processes data from a list of loaded extras files into a model
+
+ :type original_model: dict
+ :param original_model: The service model to load all the extras into.
+
+ :type extra_models: iterable of dict
+ :param extra_models: A list of loaded extras models.
+ """
+ for extras in extra_models:
+ self._process(original_model, extras)
+
+ def _process(self, model, extra_model):
+ """Process a single extras model into a service model."""
+ if 'merge' in extra_model:
+ deep_merge(model, extra_model['merge'])
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/model.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/model.py
new file mode 100644
index 0000000000..8aa3d2dcc6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/model.py
@@ -0,0 +1,954 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""Abstractions to interact with service models."""
+from collections import defaultdict
+from typing import NamedTuple, Union
+
+from botocore.compat import OrderedDict
+from botocore.exceptions import (
+ MissingServiceIdError,
+ UndefinedModelAttributeError,
+)
+from botocore.utils import CachedProperty, hyphenize_service_id, instance_cache
+
+NOT_SET = object()
+
+
+class NoShapeFoundError(Exception):
+ pass
+
+
+class InvalidShapeError(Exception):
+ pass
+
+
+class OperationNotFoundError(Exception):
+ pass
+
+
+class InvalidShapeReferenceError(Exception):
+ pass
+
+
+class ServiceId(str):
+ def hyphenize(self):
+ return hyphenize_service_id(self)
+
+
+class Shape:
+ """Object representing a shape from the service model."""
+
+ # To simplify serialization logic, all shape params that are
+ # related to serialization are moved from the top level hash into
+ # a 'serialization' hash. This list below contains the names of all
+ # the attributes that should be moved.
+ SERIALIZED_ATTRS = [
+ 'locationName',
+ 'queryName',
+ 'flattened',
+ 'location',
+ 'payload',
+ 'streaming',
+ 'timestampFormat',
+ 'xmlNamespace',
+ 'resultWrapper',
+ 'xmlAttribute',
+ 'eventstream',
+ 'event',
+ 'eventheader',
+ 'eventpayload',
+ 'jsonvalue',
+ 'timestampFormat',
+ 'hostLabel',
+ ]
+ METADATA_ATTRS = [
+ 'required',
+ 'min',
+ 'max',
+ 'pattern',
+ 'sensitive',
+ 'enum',
+ 'idempotencyToken',
+ 'error',
+ 'exception',
+ 'endpointdiscoveryid',
+ 'retryable',
+ 'document',
+ 'union',
+ 'contextParam',
+ 'clientContextParams',
+ 'requiresLength',
+ ]
+ MAP_TYPE = OrderedDict
+
+ def __init__(self, shape_name, shape_model, shape_resolver=None):
+ """
+
+ :type shape_name: string
+ :param shape_name: The name of the shape.
+
+ :type shape_model: dict
+ :param shape_model: The shape model. This would be the value
+ associated with the key in the "shapes" dict of the
+ service model (i.e ``model['shapes'][shape_name]``)
+
+ :type shape_resolver: botocore.model.ShapeResolver
+ :param shape_resolver: A shape resolver object. This is used to
+ resolve references to other shapes. For scalar shape types
+ (string, integer, boolean, etc.), this argument is not
+ required. If a shape_resolver is not provided for a complex
+ type, then a ``ValueError`` will be raised when an attempt
+ to resolve a shape is made.
+
+ """
+ self.name = shape_name
+ self.type_name = shape_model['type']
+ self.documentation = shape_model.get('documentation', '')
+ self._shape_model = shape_model
+ if shape_resolver is None:
+ # If a shape_resolver is not provided, we create an object
+ # that will throw errors if you attempt to resolve
+ # a shape. This is actually ok for scalar shapes
+ # because they don't need to resolve shapes and shouldn't
+ # be required to provide an object they won't use.
+ shape_resolver = UnresolvableShapeMap()
+ self._shape_resolver = shape_resolver
+ self._cache = {}
+
+ @CachedProperty
+ def serialization(self):
+ """Serialization information about the shape.
+
+ This contains information that may be needed for input serialization
+ or response parsing. This can include:
+
+ * name
+ * queryName
+ * flattened
+ * location
+ * payload
+ * streaming
+ * xmlNamespace
+ * resultWrapper
+ * xmlAttribute
+ * jsonvalue
+ * timestampFormat
+
+ :rtype: dict
+ :return: Serialization information about the shape.
+
+ """
+ model = self._shape_model
+ serialization = {}
+ for attr in self.SERIALIZED_ATTRS:
+ if attr in self._shape_model:
+ serialization[attr] = model[attr]
+ # For consistency, locationName is renamed to just 'name'.
+ if 'locationName' in serialization:
+ serialization['name'] = serialization.pop('locationName')
+ return serialization
+
+ @CachedProperty
+ def metadata(self):
+ """Metadata about the shape.
+
+ This requires optional information about the shape, including:
+
+ * min
+ * max
+ * pattern
+ * enum
+ * sensitive
+ * required
+ * idempotencyToken
+ * document
+ * union
+ * contextParam
+ * clientContextParams
+ * requiresLength
+
+ :rtype: dict
+ :return: Metadata about the shape.
+
+ """
+ model = self._shape_model
+ metadata = {}
+ for attr in self.METADATA_ATTRS:
+ if attr in self._shape_model:
+ metadata[attr] = model[attr]
+ return metadata
+
+ @CachedProperty
+ def required_members(self):
+ """A list of members that are required.
+
+ A structure shape can define members that are required.
+ This value will return a list of required members. If there
+ are no required members an empty list is returned.
+
+ """
+ return self.metadata.get('required', [])
+
+ def _resolve_shape_ref(self, shape_ref):
+ return self._shape_resolver.resolve_shape_ref(shape_ref)
+
+ def __repr__(self):
+ return f"<{self.__class__.__name__}({self.name})>"
+
+ @property
+ def event_stream_name(self):
+ return None
+
+
+class StructureShape(Shape):
+ @CachedProperty
+ def members(self):
+ members = self._shape_model.get('members', self.MAP_TYPE())
+ # The members dict looks like:
+ # 'members': {
+ # 'MemberName': {'shape': 'shapeName'},
+ # 'MemberName2': {'shape': 'shapeName'},
+ # }
+ # We return a dict of member name to Shape object.
+ shape_members = self.MAP_TYPE()
+ for name, shape_ref in members.items():
+ shape_members[name] = self._resolve_shape_ref(shape_ref)
+ return shape_members
+
+ @CachedProperty
+ def event_stream_name(self):
+ for member_name, member in self.members.items():
+ if member.serialization.get('eventstream'):
+ return member_name
+ return None
+
+ @CachedProperty
+ def error_code(self):
+ if not self.metadata.get('exception', False):
+ return None
+ error_metadata = self.metadata.get("error", {})
+ code = error_metadata.get("code")
+ if code:
+ return code
+ # Use the exception name if there is no explicit code modeled
+ return self.name
+
+ @CachedProperty
+ def is_document_type(self):
+ return self.metadata.get('document', False)
+
+ @CachedProperty
+ def is_tagged_union(self):
+ return self.metadata.get('union', False)
+
+
+class ListShape(Shape):
+ @CachedProperty
+ def member(self):
+ return self._resolve_shape_ref(self._shape_model['member'])
+
+
+class MapShape(Shape):
+ @CachedProperty
+ def key(self):
+ return self._resolve_shape_ref(self._shape_model['key'])
+
+ @CachedProperty
+ def value(self):
+ return self._resolve_shape_ref(self._shape_model['value'])
+
+
+class StringShape(Shape):
+ @CachedProperty
+ def enum(self):
+ return self.metadata.get('enum', [])
+
+
+class StaticContextParameter(NamedTuple):
+ name: str
+ value: Union[bool, str]
+
+
+class ContextParameter(NamedTuple):
+ name: str
+ member_name: str
+
+
+class ClientContextParameter(NamedTuple):
+ name: str
+ type: str
+ documentation: str
+
+
+class ServiceModel:
+ """
+
+ :ivar service_description: The parsed service description dictionary.
+
+ """
+
+ def __init__(self, service_description, service_name=None):
+ """
+
+ :type service_description: dict
+ :param service_description: The service description model. This value
+ is obtained from a botocore.loader.Loader, or from directly loading
+ the file yourself::
+
+ service_description = json.load(
+ open('/path/to/service-description-model.json'))
+ model = ServiceModel(service_description)
+
+ :type service_name: str
+ :param service_name: The name of the service. Normally this is
+ the endpoint prefix defined in the service_description. However,
+ you can override this value to provide a more convenient name.
+ This is done in a few places in botocore (ses instead of email,
+ emr instead of elasticmapreduce). If this value is not provided,
+ it will default to the endpointPrefix defined in the model.
+
+ """
+ self._service_description = service_description
+ # We want clients to be able to access metadata directly.
+ self.metadata = service_description.get('metadata', {})
+ self._shape_resolver = ShapeResolver(
+ service_description.get('shapes', {})
+ )
+ self._signature_version = NOT_SET
+ self._service_name = service_name
+ self._instance_cache = {}
+
+ def shape_for(self, shape_name, member_traits=None):
+ return self._shape_resolver.get_shape_by_name(
+ shape_name, member_traits
+ )
+
+ def shape_for_error_code(self, error_code):
+ return self._error_code_cache.get(error_code, None)
+
+ @CachedProperty
+ def _error_code_cache(self):
+ error_code_cache = {}
+ for error_shape in self.error_shapes:
+ code = error_shape.error_code
+ error_code_cache[code] = error_shape
+ return error_code_cache
+
+ def resolve_shape_ref(self, shape_ref):
+ return self._shape_resolver.resolve_shape_ref(shape_ref)
+
+ @CachedProperty
+ def shape_names(self):
+ return list(self._service_description.get('shapes', {}))
+
+ @CachedProperty
+ def error_shapes(self):
+ error_shapes = []
+ for shape_name in self.shape_names:
+ error_shape = self.shape_for(shape_name)
+ if error_shape.metadata.get('exception', False):
+ error_shapes.append(error_shape)
+ return error_shapes
+
+ @instance_cache
+ def operation_model(self, operation_name):
+ try:
+ model = self._service_description['operations'][operation_name]
+ except KeyError:
+ raise OperationNotFoundError(operation_name)
+ return OperationModel(model, self, operation_name)
+
+ @CachedProperty
+ def documentation(self):
+ return self._service_description.get('documentation', '')
+
+ @CachedProperty
+ def operation_names(self):
+ return list(self._service_description.get('operations', []))
+
+ @CachedProperty
+ def service_name(self):
+ """The name of the service.
+
+ This defaults to the endpointPrefix defined in the service model.
+ However, this value can be overriden when a ``ServiceModel`` is
+ created. If a service_name was not provided when the ``ServiceModel``
+ was created and if there is no endpointPrefix defined in the
+ service model, then an ``UndefinedModelAttributeError`` exception
+ will be raised.
+
+ """
+ if self._service_name is not None:
+ return self._service_name
+ else:
+ return self.endpoint_prefix
+
+ @CachedProperty
+ def service_id(self):
+ try:
+ return ServiceId(self._get_metadata_property('serviceId'))
+ except UndefinedModelAttributeError:
+ raise MissingServiceIdError(service_name=self._service_name)
+
+ @CachedProperty
+ def signing_name(self):
+ """The name to use when computing signatures.
+
+ If the model does not define a signing name, this
+ value will be the endpoint prefix defined in the model.
+ """
+ signing_name = self.metadata.get('signingName')
+ if signing_name is None:
+ signing_name = self.endpoint_prefix
+ return signing_name
+
+ @CachedProperty
+ def api_version(self):
+ return self._get_metadata_property('apiVersion')
+
+ @CachedProperty
+ def protocol(self):
+ return self._get_metadata_property('protocol')
+
+ @CachedProperty
+ def endpoint_prefix(self):
+ return self._get_metadata_property('endpointPrefix')
+
+ @CachedProperty
+ def endpoint_discovery_operation(self):
+ for operation in self.operation_names:
+ model = self.operation_model(operation)
+ if model.is_endpoint_discovery_operation:
+ return model
+
+ @CachedProperty
+ def endpoint_discovery_required(self):
+ for operation in self.operation_names:
+ model = self.operation_model(operation)
+ if (
+ model.endpoint_discovery is not None
+ and model.endpoint_discovery.get('required')
+ ):
+ return True
+ return False
+
+ @CachedProperty
+ def client_context_parameters(self):
+ params = self._service_description.get('clientContextParams', {})
+ return [
+ ClientContextParameter(
+ name=param_name,
+ type=param_val['type'],
+ documentation=param_val['documentation'],
+ )
+ for param_name, param_val in params.items()
+ ]
+
+ def _get_metadata_property(self, name):
+ try:
+ return self.metadata[name]
+ except KeyError:
+ raise UndefinedModelAttributeError(
+ f'"{name}" not defined in the metadata of the model: {self}'
+ )
+
+ # Signature version is one of the rare properties
+ # that can be modified so a CachedProperty is not used here.
+
+ @property
+ def signature_version(self):
+ if self._signature_version is NOT_SET:
+ signature_version = self.metadata.get('signatureVersion')
+ self._signature_version = signature_version
+ return self._signature_version
+
+ @signature_version.setter
+ def signature_version(self, value):
+ self._signature_version = value
+
+ def __repr__(self):
+ return f'{self.__class__.__name__}({self.service_name})'
+
+
+class OperationModel:
+ def __init__(self, operation_model, service_model, name=None):
+ """
+
+ :type operation_model: dict
+ :param operation_model: The operation model. This comes from the
+ service model, and is the value associated with the operation
+ name in the service model (i.e ``model['operations'][op_name]``).
+
+ :type service_model: botocore.model.ServiceModel
+ :param service_model: The service model associated with the operation.
+
+ :type name: string
+ :param name: The operation name. This is the operation name exposed to
+ the users of this model. This can potentially be different from
+ the "wire_name", which is the operation name that *must* by
+ provided over the wire. For example, given::
+
+ "CreateCloudFrontOriginAccessIdentity":{
+ "name":"CreateCloudFrontOriginAccessIdentity2014_11_06",
+ ...
+ }
+
+ The ``name`` would be ``CreateCloudFrontOriginAccessIdentity``,
+ but the ``self.wire_name`` would be
+ ``CreateCloudFrontOriginAccessIdentity2014_11_06``, which is the
+ value we must send in the corresponding HTTP request.
+
+ """
+ self._operation_model = operation_model
+ self._service_model = service_model
+ self._api_name = name
+ # Clients can access '.name' to get the operation name
+ # and '.metadata' to get the top level metdata of the service.
+ self._wire_name = operation_model.get('name')
+ self.metadata = service_model.metadata
+ self.http = operation_model.get('http', {})
+
+ @CachedProperty
+ def name(self):
+ if self._api_name is not None:
+ return self._api_name
+ else:
+ return self.wire_name
+
+ @property
+ def wire_name(self):
+ """The wire name of the operation.
+
+ In many situations this is the same value as the
+ ``name``, value, but in some services, the operation name
+ exposed to the user is different from the operation name
+ we send across the wire (e.g cloudfront).
+
+ Any serialization code should use ``wire_name``.
+
+ """
+ return self._operation_model.get('name')
+
+ @property
+ def service_model(self):
+ return self._service_model
+
+ @CachedProperty
+ def documentation(self):
+ return self._operation_model.get('documentation', '')
+
+ @CachedProperty
+ def deprecated(self):
+ return self._operation_model.get('deprecated', False)
+
+ @CachedProperty
+ def endpoint_discovery(self):
+ # Explicit None default. An empty dictionary for this trait means it is
+ # enabled but not required to be used.
+ return self._operation_model.get('endpointdiscovery', None)
+
+ @CachedProperty
+ def is_endpoint_discovery_operation(self):
+ return self._operation_model.get('endpointoperation', False)
+
+ @CachedProperty
+ def input_shape(self):
+ if 'input' not in self._operation_model:
+ # Some operations do not accept any input and do not define an
+ # input shape.
+ return None
+ return self._service_model.resolve_shape_ref(
+ self._operation_model['input']
+ )
+
+ @CachedProperty
+ def output_shape(self):
+ if 'output' not in self._operation_model:
+ # Some operations do not define an output shape,
+ # in which case we return None to indicate the
+ # operation has no expected output.
+ return None
+ return self._service_model.resolve_shape_ref(
+ self._operation_model['output']
+ )
+
+ @CachedProperty
+ def idempotent_members(self):
+ input_shape = self.input_shape
+ if not input_shape:
+ return []
+
+ return [
+ name
+ for (name, shape) in input_shape.members.items()
+ if 'idempotencyToken' in shape.metadata
+ and shape.metadata['idempotencyToken']
+ ]
+
+ @CachedProperty
+ def static_context_parameters(self):
+ params = self._operation_model.get('staticContextParams', {})
+ return [
+ StaticContextParameter(name=name, value=props.get('value'))
+ for name, props in params.items()
+ ]
+
+ @CachedProperty
+ def context_parameters(self):
+ if not self.input_shape:
+ return []
+
+ return [
+ ContextParameter(
+ name=shape.metadata['contextParam']['name'],
+ member_name=name,
+ )
+ for name, shape in self.input_shape.members.items()
+ if 'contextParam' in shape.metadata
+ and 'name' in shape.metadata['contextParam']
+ ]
+
+ @CachedProperty
+ def request_compression(self):
+ return self._operation_model.get('requestcompression')
+
+ @CachedProperty
+ def auth_type(self):
+ return self._operation_model.get('authtype')
+
+ @CachedProperty
+ def error_shapes(self):
+ shapes = self._operation_model.get("errors", [])
+ return list(self._service_model.resolve_shape_ref(s) for s in shapes)
+
+ @CachedProperty
+ def endpoint(self):
+ return self._operation_model.get('endpoint')
+
+ @CachedProperty
+ def http_checksum_required(self):
+ return self._operation_model.get('httpChecksumRequired', False)
+
+ @CachedProperty
+ def http_checksum(self):
+ return self._operation_model.get('httpChecksum', {})
+
+ @CachedProperty
+ def has_event_stream_input(self):
+ return self.get_event_stream_input() is not None
+
+ @CachedProperty
+ def has_event_stream_output(self):
+ return self.get_event_stream_output() is not None
+
+ def get_event_stream_input(self):
+ return self._get_event_stream(self.input_shape)
+
+ def get_event_stream_output(self):
+ return self._get_event_stream(self.output_shape)
+
+ def _get_event_stream(self, shape):
+ """Returns the event stream member's shape if any or None otherwise."""
+ if shape is None:
+ return None
+ event_name = shape.event_stream_name
+ if event_name:
+ return shape.members[event_name]
+ return None
+
+ @CachedProperty
+ def has_streaming_input(self):
+ return self.get_streaming_input() is not None
+
+ @CachedProperty
+ def has_streaming_output(self):
+ return self.get_streaming_output() is not None
+
+ def get_streaming_input(self):
+ return self._get_streaming_body(self.input_shape)
+
+ def get_streaming_output(self):
+ return self._get_streaming_body(self.output_shape)
+
+ def _get_streaming_body(self, shape):
+ """Returns the streaming member's shape if any; or None otherwise."""
+ if shape is None:
+ return None
+ payload = shape.serialization.get('payload')
+ if payload is not None:
+ payload_shape = shape.members[payload]
+ if payload_shape.type_name == 'blob':
+ return payload_shape
+ return None
+
+ def __repr__(self):
+ return f'{self.__class__.__name__}(name={self.name})'
+
+
+class ShapeResolver:
+ """Resolves shape references."""
+
+ # Any type not in this mapping will default to the Shape class.
+ SHAPE_CLASSES = {
+ 'structure': StructureShape,
+ 'list': ListShape,
+ 'map': MapShape,
+ 'string': StringShape,
+ }
+
+ def __init__(self, shape_map):
+ self._shape_map = shape_map
+ self._shape_cache = {}
+
+ def get_shape_by_name(self, shape_name, member_traits=None):
+ try:
+ shape_model = self._shape_map[shape_name]
+ except KeyError:
+ raise NoShapeFoundError(shape_name)
+ try:
+ shape_cls = self.SHAPE_CLASSES.get(shape_model['type'], Shape)
+ except KeyError:
+ raise InvalidShapeError(
+ f"Shape is missing required key 'type': {shape_model}"
+ )
+ if member_traits:
+ shape_model = shape_model.copy()
+ shape_model.update(member_traits)
+ result = shape_cls(shape_name, shape_model, self)
+ return result
+
+ def resolve_shape_ref(self, shape_ref):
+ # A shape_ref is a dict that has a 'shape' key that
+ # refers to a shape name as well as any additional
+ # member traits that are then merged over the shape
+ # definition. For example:
+ # {"shape": "StringType", "locationName": "Foobar"}
+ if len(shape_ref) == 1 and 'shape' in shape_ref:
+ # It's just a shape ref with no member traits, we can avoid
+ # a .copy(). This is the common case so it's specifically
+ # called out here.
+ return self.get_shape_by_name(shape_ref['shape'])
+ else:
+ member_traits = shape_ref.copy()
+ try:
+ shape_name = member_traits.pop('shape')
+ except KeyError:
+ raise InvalidShapeReferenceError(
+ f"Invalid model, missing shape reference: {shape_ref}"
+ )
+ return self.get_shape_by_name(shape_name, member_traits)
+
+
+class UnresolvableShapeMap:
+ """A ShapeResolver that will throw ValueErrors when shapes are resolved."""
+
+ def get_shape_by_name(self, shape_name, member_traits=None):
+ raise ValueError(
+ f"Attempted to lookup shape '{shape_name}', but no shape map was provided."
+ )
+
+ def resolve_shape_ref(self, shape_ref):
+ raise ValueError(
+ f"Attempted to resolve shape '{shape_ref}', but no shape "
+ f"map was provided."
+ )
+
+
+class DenormalizedStructureBuilder:
+ """Build a StructureShape from a denormalized model.
+
+ This is a convenience builder class that makes it easy to construct
+ ``StructureShape``s based on a denormalized model.
+
+ It will handle the details of creating unique shape names and creating
+ the appropriate shape map needed by the ``StructureShape`` class.
+
+ Example usage::
+
+ builder = DenormalizedStructureBuilder()
+ shape = builder.with_members({
+ 'A': {
+ 'type': 'structure',
+ 'members': {
+ 'B': {
+ 'type': 'structure',
+ 'members': {
+ 'C': {
+ 'type': 'string',
+ }
+ }
+ }
+ }
+ }
+ }).build_model()
+ # ``shape`` is now an instance of botocore.model.StructureShape
+
+ :type dict_type: class
+ :param dict_type: The dictionary type to use, allowing you to opt-in
+ to using OrderedDict or another dict type. This can
+ be particularly useful for testing when order
+ matters, such as for documentation.
+
+ """
+
+ SCALAR_TYPES = (
+ 'string',
+ 'integer',
+ 'boolean',
+ 'blob',
+ 'float',
+ 'timestamp',
+ 'long',
+ 'double',
+ 'char',
+ )
+
+ def __init__(self, name=None):
+ self.members = OrderedDict()
+ self._name_generator = ShapeNameGenerator()
+ if name is None:
+ self.name = self._name_generator.new_shape_name('structure')
+
+ def with_members(self, members):
+ """
+
+ :type members: dict
+ :param members: The denormalized members.
+
+ :return: self
+
+ """
+ self._members = members
+ return self
+
+ def build_model(self):
+ """Build the model based on the provided members.
+
+ :rtype: botocore.model.StructureShape
+ :return: The built StructureShape object.
+
+ """
+ shapes = OrderedDict()
+ denormalized = {
+ 'type': 'structure',
+ 'members': self._members,
+ }
+ self._build_model(denormalized, shapes, self.name)
+ resolver = ShapeResolver(shape_map=shapes)
+ return StructureShape(
+ shape_name=self.name,
+ shape_model=shapes[self.name],
+ shape_resolver=resolver,
+ )
+
+ def _build_model(self, model, shapes, shape_name):
+ if model['type'] == 'structure':
+ shapes[shape_name] = self._build_structure(model, shapes)
+ elif model['type'] == 'list':
+ shapes[shape_name] = self._build_list(model, shapes)
+ elif model['type'] == 'map':
+ shapes[shape_name] = self._build_map(model, shapes)
+ elif model['type'] in self.SCALAR_TYPES:
+ shapes[shape_name] = self._build_scalar(model)
+ else:
+ raise InvalidShapeError(f"Unknown shape type: {model['type']}")
+
+ def _build_structure(self, model, shapes):
+ members = OrderedDict()
+ shape = self._build_initial_shape(model)
+ shape['members'] = members
+
+ for name, member_model in model.get('members', OrderedDict()).items():
+ member_shape_name = self._get_shape_name(member_model)
+ members[name] = {'shape': member_shape_name}
+ self._build_model(member_model, shapes, member_shape_name)
+ return shape
+
+ def _build_list(self, model, shapes):
+ member_shape_name = self._get_shape_name(model)
+ shape = self._build_initial_shape(model)
+ shape['member'] = {'shape': member_shape_name}
+ self._build_model(model['member'], shapes, member_shape_name)
+ return shape
+
+ def _build_map(self, model, shapes):
+ key_shape_name = self._get_shape_name(model['key'])
+ value_shape_name = self._get_shape_name(model['value'])
+ shape = self._build_initial_shape(model)
+ shape['key'] = {'shape': key_shape_name}
+ shape['value'] = {'shape': value_shape_name}
+ self._build_model(model['key'], shapes, key_shape_name)
+ self._build_model(model['value'], shapes, value_shape_name)
+ return shape
+
+ def _build_initial_shape(self, model):
+ shape = {
+ 'type': model['type'],
+ }
+ if 'documentation' in model:
+ shape['documentation'] = model['documentation']
+ for attr in Shape.METADATA_ATTRS:
+ if attr in model:
+ shape[attr] = model[attr]
+ return shape
+
+ def _build_scalar(self, model):
+ return self._build_initial_shape(model)
+
+ def _get_shape_name(self, model):
+ if 'shape_name' in model:
+ return model['shape_name']
+ else:
+ return self._name_generator.new_shape_name(model['type'])
+
+
+class ShapeNameGenerator:
+ """Generate unique shape names for a type.
+
+ This class can be used in conjunction with the DenormalizedStructureBuilder
+ to generate unique shape names for a given type.
+
+ """
+
+ def __init__(self):
+ self._name_cache = defaultdict(int)
+
+ def new_shape_name(self, type_name):
+ """Generate a unique shape name.
+
+ This method will guarantee a unique shape name each time it is
+ called with the same type.
+
+ ::
+
+ >>> s = ShapeNameGenerator()
+ >>> s.new_shape_name('structure')
+ 'StructureType1'
+ >>> s.new_shape_name('structure')
+ 'StructureType2'
+ >>> s.new_shape_name('list')
+ 'ListType1'
+ >>> s.new_shape_name('list')
+ 'ListType2'
+
+
+ :type type_name: string
+ :param type_name: The type name (structure, list, map, string, etc.)
+
+ :rtype: string
+ :return: A unique shape name for the given type
+
+ """
+ self._name_cache[type_name] += 1
+ current_index = self._name_cache[type_name]
+ return f'{type_name.capitalize()}Type{current_index}'
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/monitoring.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/monitoring.py
new file mode 100644
index 0000000000..71d7230246
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/monitoring.py
@@ -0,0 +1,586 @@
+# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import json
+import logging
+import re
+import time
+
+from botocore.compat import ensure_bytes, ensure_unicode, urlparse
+from botocore.retryhandler import EXCEPTION_MAP as RETRYABLE_EXCEPTIONS
+
+logger = logging.getLogger(__name__)
+
+
+class Monitor:
+ _EVENTS_TO_REGISTER = [
+ 'before-parameter-build',
+ 'request-created',
+ 'response-received',
+ 'after-call',
+ 'after-call-error',
+ ]
+
+ def __init__(self, adapter, publisher):
+ """Abstraction for monitoring clients API calls
+
+ :param adapter: An adapter that takes event emitter events
+ and produces monitor events
+
+ :param publisher: A publisher for generated monitor events
+ """
+ self._adapter = adapter
+ self._publisher = publisher
+
+ def register(self, event_emitter):
+ """Register an event emitter to the monitor"""
+ for event_to_register in self._EVENTS_TO_REGISTER:
+ event_emitter.register_last(event_to_register, self.capture)
+
+ def capture(self, event_name, **payload):
+ """Captures an incoming event from the event emitter
+
+ It will feed an event emitter event to the monitor's adaptor to create
+ a monitor event and then publish that event to the monitor's publisher.
+ """
+ try:
+ monitor_event = self._adapter.feed(event_name, payload)
+ if monitor_event:
+ self._publisher.publish(monitor_event)
+ except Exception as e:
+ logger.debug(
+ 'Exception %s raised by client monitor in handling event %s',
+ e,
+ event_name,
+ exc_info=True,
+ )
+
+
+class MonitorEventAdapter:
+ def __init__(self, time=time.time):
+ """Adapts event emitter events to produce monitor events
+
+ :type time: callable
+ :param time: A callable that produces the current time
+ """
+ self._time = time
+
+ def feed(self, emitter_event_name, emitter_payload):
+ """Feed an event emitter event to generate a monitor event
+
+ :type emitter_event_name: str
+ :param emitter_event_name: The name of the event emitted
+
+ :type emitter_payload: dict
+ :param emitter_payload: The payload to associated to the event
+ emitted
+
+ :rtype: BaseMonitorEvent
+ :returns: A monitor event based on the event emitter events
+ fired
+ """
+ return self._get_handler(emitter_event_name)(**emitter_payload)
+
+ def _get_handler(self, event_name):
+ return getattr(
+ self, '_handle_' + event_name.split('.')[0].replace('-', '_')
+ )
+
+ def _handle_before_parameter_build(self, model, context, **kwargs):
+ context['current_api_call_event'] = APICallEvent(
+ service=model.service_model.service_id,
+ operation=model.wire_name,
+ timestamp=self._get_current_time(),
+ )
+
+ def _handle_request_created(self, request, **kwargs):
+ context = request.context
+ new_attempt_event = context[
+ 'current_api_call_event'
+ ].new_api_call_attempt(timestamp=self._get_current_time())
+ new_attempt_event.request_headers = request.headers
+ new_attempt_event.url = request.url
+ context['current_api_call_attempt_event'] = new_attempt_event
+
+ def _handle_response_received(
+ self, parsed_response, context, exception, **kwargs
+ ):
+ attempt_event = context.pop('current_api_call_attempt_event')
+ attempt_event.latency = self._get_latency(attempt_event)
+ if parsed_response is not None:
+ attempt_event.http_status_code = parsed_response[
+ 'ResponseMetadata'
+ ]['HTTPStatusCode']
+ attempt_event.response_headers = parsed_response[
+ 'ResponseMetadata'
+ ]['HTTPHeaders']
+ attempt_event.parsed_error = parsed_response.get('Error')
+ else:
+ attempt_event.wire_exception = exception
+ return attempt_event
+
+ def _handle_after_call(self, context, parsed, **kwargs):
+ context['current_api_call_event'].retries_exceeded = parsed[
+ 'ResponseMetadata'
+ ].get('MaxAttemptsReached', False)
+ return self._complete_api_call(context)
+
+ def _handle_after_call_error(self, context, exception, **kwargs):
+ # If the after-call-error was emitted and the error being raised
+ # was a retryable connection error, then the retries must have exceeded
+ # for that exception as this event gets emitted **after** retries
+ # happen.
+ context[
+ 'current_api_call_event'
+ ].retries_exceeded = self._is_retryable_exception(exception)
+ return self._complete_api_call(context)
+
+ def _is_retryable_exception(self, exception):
+ return isinstance(
+ exception, tuple(RETRYABLE_EXCEPTIONS['GENERAL_CONNECTION_ERROR'])
+ )
+
+ def _complete_api_call(self, context):
+ call_event = context.pop('current_api_call_event')
+ call_event.latency = self._get_latency(call_event)
+ return call_event
+
+ def _get_latency(self, event):
+ return self._get_current_time() - event.timestamp
+
+ def _get_current_time(self):
+ return int(self._time() * 1000)
+
+
+class BaseMonitorEvent:
+ def __init__(self, service, operation, timestamp):
+ """Base monitor event
+
+ :type service: str
+ :param service: A string identifying the service associated to
+ the event
+
+ :type operation: str
+ :param operation: A string identifying the operation of service
+ associated to the event
+
+ :type timestamp: int
+ :param timestamp: Epoch time in milliseconds from when the event began
+ """
+ self.service = service
+ self.operation = operation
+ self.timestamp = timestamp
+
+ def __repr__(self):
+ return f'{self.__class__.__name__}({self.__dict__!r})'
+
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.__dict__ == other.__dict__
+ return False
+
+
+class APICallEvent(BaseMonitorEvent):
+ def __init__(
+ self,
+ service,
+ operation,
+ timestamp,
+ latency=None,
+ attempts=None,
+ retries_exceeded=False,
+ ):
+ """Monitor event for a single API call
+
+ This event corresponds to a single client method call, which includes
+ every HTTP requests attempt made in order to complete the client call
+
+ :type service: str
+ :param service: A string identifying the service associated to
+ the event
+
+ :type operation: str
+ :param operation: A string identifying the operation of service
+ associated to the event
+
+ :type timestamp: int
+ :param timestamp: Epoch time in milliseconds from when the event began
+
+ :type latency: int
+ :param latency: The time in milliseconds to complete the client call
+
+ :type attempts: list
+ :param attempts: The list of APICallAttempts associated to the
+ APICall
+
+ :type retries_exceeded: bool
+ :param retries_exceeded: True if API call exceeded retries. False
+ otherwise
+ """
+ super().__init__(
+ service=service, operation=operation, timestamp=timestamp
+ )
+ self.latency = latency
+ self.attempts = attempts
+ if attempts is None:
+ self.attempts = []
+ self.retries_exceeded = retries_exceeded
+
+ def new_api_call_attempt(self, timestamp):
+ """Instantiates APICallAttemptEvent associated to the APICallEvent
+
+ :type timestamp: int
+ :param timestamp: Epoch time in milliseconds to associate to the
+ APICallAttemptEvent
+ """
+ attempt_event = APICallAttemptEvent(
+ service=self.service, operation=self.operation, timestamp=timestamp
+ )
+ self.attempts.append(attempt_event)
+ return attempt_event
+
+
+class APICallAttemptEvent(BaseMonitorEvent):
+ def __init__(
+ self,
+ service,
+ operation,
+ timestamp,
+ latency=None,
+ url=None,
+ http_status_code=None,
+ request_headers=None,
+ response_headers=None,
+ parsed_error=None,
+ wire_exception=None,
+ ):
+ """Monitor event for a single API call attempt
+
+ This event corresponds to a single HTTP request attempt in completing
+ the entire client method call.
+
+ :type service: str
+ :param service: A string identifying the service associated to
+ the event
+
+ :type operation: str
+ :param operation: A string identifying the operation of service
+ associated to the event
+
+ :type timestamp: int
+ :param timestamp: Epoch time in milliseconds from when the HTTP request
+ started
+
+ :type latency: int
+ :param latency: The time in milliseconds to complete the HTTP request
+ whether it succeeded or failed
+
+ :type url: str
+ :param url: The URL the attempt was sent to
+
+ :type http_status_code: int
+ :param http_status_code: The HTTP status code of the HTTP response
+ if there was a response
+
+ :type request_headers: dict
+ :param request_headers: The HTTP headers sent in making the HTTP
+ request
+
+ :type response_headers: dict
+ :param response_headers: The HTTP headers returned in the HTTP response
+ if there was a response
+
+ :type parsed_error: dict
+ :param parsed_error: The error parsed if the service returned an
+ error back
+
+ :type wire_exception: Exception
+ :param wire_exception: The exception raised in sending the HTTP
+ request (i.e. ConnectionError)
+ """
+ super().__init__(
+ service=service, operation=operation, timestamp=timestamp
+ )
+ self.latency = latency
+ self.url = url
+ self.http_status_code = http_status_code
+ self.request_headers = request_headers
+ self.response_headers = response_headers
+ self.parsed_error = parsed_error
+ self.wire_exception = wire_exception
+
+
+class CSMSerializer:
+ _MAX_CLIENT_ID_LENGTH = 255
+ _MAX_EXCEPTION_CLASS_LENGTH = 128
+ _MAX_ERROR_CODE_LENGTH = 128
+ _MAX_USER_AGENT_LENGTH = 256
+ _MAX_MESSAGE_LENGTH = 512
+ _RESPONSE_HEADERS_TO_EVENT_ENTRIES = {
+ 'x-amzn-requestid': 'XAmznRequestId',
+ 'x-amz-request-id': 'XAmzRequestId',
+ 'x-amz-id-2': 'XAmzId2',
+ }
+ _AUTH_REGEXS = {
+ 'v4': re.compile(
+ r'AWS4-HMAC-SHA256 '
+ r'Credential=(?P\w+)/\d+/'
+ r'(?P[a-z0-9-]+)/'
+ ),
+ 's3': re.compile(r'AWS (?P\w+):'),
+ }
+ _SERIALIZEABLE_EVENT_PROPERTIES = [
+ 'service',
+ 'operation',
+ 'timestamp',
+ 'attempts',
+ 'latency',
+ 'retries_exceeded',
+ 'url',
+ 'request_headers',
+ 'http_status_code',
+ 'response_headers',
+ 'parsed_error',
+ 'wire_exception',
+ ]
+
+ def __init__(self, csm_client_id):
+ """Serializes monitor events to CSM (Client Side Monitoring) format
+
+ :type csm_client_id: str
+ :param csm_client_id: The application identifier to associate
+ to the serialized events
+ """
+ self._validate_client_id(csm_client_id)
+ self.csm_client_id = csm_client_id
+
+ def _validate_client_id(self, csm_client_id):
+ if len(csm_client_id) > self._MAX_CLIENT_ID_LENGTH:
+ raise ValueError(
+ f'The value provided for csm_client_id: {csm_client_id} exceeds '
+ f'the maximum length of {self._MAX_CLIENT_ID_LENGTH} characters'
+ )
+
+ def serialize(self, event):
+ """Serializes a monitor event to the CSM format
+
+ :type event: BaseMonitorEvent
+ :param event: The event to serialize to bytes
+
+ :rtype: bytes
+ :returns: The CSM serialized form of the event
+ """
+ event_dict = self._get_base_event_dict(event)
+ event_type = self._get_event_type(event)
+ event_dict['Type'] = event_type
+ for attr in self._SERIALIZEABLE_EVENT_PROPERTIES:
+ value = getattr(event, attr, None)
+ if value is not None:
+ getattr(self, '_serialize_' + attr)(
+ value, event_dict, event_type=event_type
+ )
+ return ensure_bytes(json.dumps(event_dict, separators=(',', ':')))
+
+ def _get_base_event_dict(self, event):
+ return {
+ 'Version': 1,
+ 'ClientId': self.csm_client_id,
+ }
+
+ def _serialize_service(self, service, event_dict, **kwargs):
+ event_dict['Service'] = service
+
+ def _serialize_operation(self, operation, event_dict, **kwargs):
+ event_dict['Api'] = operation
+
+ def _serialize_timestamp(self, timestamp, event_dict, **kwargs):
+ event_dict['Timestamp'] = timestamp
+
+ def _serialize_attempts(self, attempts, event_dict, **kwargs):
+ event_dict['AttemptCount'] = len(attempts)
+ if attempts:
+ self._add_fields_from_last_attempt(event_dict, attempts[-1])
+
+ def _add_fields_from_last_attempt(self, event_dict, last_attempt):
+ if last_attempt.request_headers:
+ # It does not matter which attempt to use to grab the region
+ # for the ApiCall event, but SDKs typically do the last one.
+ region = self._get_region(last_attempt.request_headers)
+ if region is not None:
+ event_dict['Region'] = region
+ event_dict['UserAgent'] = self._get_user_agent(
+ last_attempt.request_headers
+ )
+ if last_attempt.http_status_code is not None:
+ event_dict['FinalHttpStatusCode'] = last_attempt.http_status_code
+ if last_attempt.parsed_error is not None:
+ self._serialize_parsed_error(
+ last_attempt.parsed_error, event_dict, 'ApiCall'
+ )
+ if last_attempt.wire_exception is not None:
+ self._serialize_wire_exception(
+ last_attempt.wire_exception, event_dict, 'ApiCall'
+ )
+
+ def _serialize_latency(self, latency, event_dict, event_type):
+ if event_type == 'ApiCall':
+ event_dict['Latency'] = latency
+ elif event_type == 'ApiCallAttempt':
+ event_dict['AttemptLatency'] = latency
+
+ def _serialize_retries_exceeded(
+ self, retries_exceeded, event_dict, **kwargs
+ ):
+ event_dict['MaxRetriesExceeded'] = 1 if retries_exceeded else 0
+
+ def _serialize_url(self, url, event_dict, **kwargs):
+ event_dict['Fqdn'] = urlparse(url).netloc
+
+ def _serialize_request_headers(
+ self, request_headers, event_dict, **kwargs
+ ):
+ event_dict['UserAgent'] = self._get_user_agent(request_headers)
+ if self._is_signed(request_headers):
+ event_dict['AccessKey'] = self._get_access_key(request_headers)
+ region = self._get_region(request_headers)
+ if region is not None:
+ event_dict['Region'] = region
+ if 'X-Amz-Security-Token' in request_headers:
+ event_dict['SessionToken'] = request_headers[
+ 'X-Amz-Security-Token'
+ ]
+
+ def _serialize_http_status_code(
+ self, http_status_code, event_dict, **kwargs
+ ):
+ event_dict['HttpStatusCode'] = http_status_code
+
+ def _serialize_response_headers(
+ self, response_headers, event_dict, **kwargs
+ ):
+ for header, entry in self._RESPONSE_HEADERS_TO_EVENT_ENTRIES.items():
+ if header in response_headers:
+ event_dict[entry] = response_headers[header]
+
+ def _serialize_parsed_error(
+ self, parsed_error, event_dict, event_type, **kwargs
+ ):
+ field_prefix = 'Final' if event_type == 'ApiCall' else ''
+ event_dict[field_prefix + 'AwsException'] = self._truncate(
+ parsed_error['Code'], self._MAX_ERROR_CODE_LENGTH
+ )
+ event_dict[field_prefix + 'AwsExceptionMessage'] = self._truncate(
+ parsed_error['Message'], self._MAX_MESSAGE_LENGTH
+ )
+
+ def _serialize_wire_exception(
+ self, wire_exception, event_dict, event_type, **kwargs
+ ):
+ field_prefix = 'Final' if event_type == 'ApiCall' else ''
+ event_dict[field_prefix + 'SdkException'] = self._truncate(
+ wire_exception.__class__.__name__, self._MAX_EXCEPTION_CLASS_LENGTH
+ )
+ event_dict[field_prefix + 'SdkExceptionMessage'] = self._truncate(
+ str(wire_exception), self._MAX_MESSAGE_LENGTH
+ )
+
+ def _get_event_type(self, event):
+ if isinstance(event, APICallEvent):
+ return 'ApiCall'
+ elif isinstance(event, APICallAttemptEvent):
+ return 'ApiCallAttempt'
+
+ def _get_access_key(self, request_headers):
+ auth_val = self._get_auth_value(request_headers)
+ _, auth_match = self._get_auth_match(auth_val)
+ return auth_match.group('access_key')
+
+ def _get_region(self, request_headers):
+ if not self._is_signed(request_headers):
+ return None
+ auth_val = self._get_auth_value(request_headers)
+ signature_version, auth_match = self._get_auth_match(auth_val)
+ if signature_version != 'v4':
+ return None
+ return auth_match.group('signing_region')
+
+ def _get_user_agent(self, request_headers):
+ return self._truncate(
+ ensure_unicode(request_headers.get('User-Agent', '')),
+ self._MAX_USER_AGENT_LENGTH,
+ )
+
+ def _is_signed(self, request_headers):
+ return 'Authorization' in request_headers
+
+ def _get_auth_value(self, request_headers):
+ return ensure_unicode(request_headers['Authorization'])
+
+ def _get_auth_match(self, auth_val):
+ for signature_version, regex in self._AUTH_REGEXS.items():
+ match = regex.match(auth_val)
+ if match:
+ return signature_version, match
+ return None, None
+
+ def _truncate(self, text, max_length):
+ if len(text) > max_length:
+ logger.debug(
+ 'Truncating following value to maximum length of ' '%s: %s',
+ text,
+ max_length,
+ )
+ return text[:max_length]
+ return text
+
+
+class SocketPublisher:
+ _MAX_MONITOR_EVENT_LENGTH = 8 * 1024
+
+ def __init__(self, socket, host, port, serializer):
+ """Publishes monitor events to a socket
+
+ :type socket: socket.socket
+ :param socket: The socket object to use to publish events
+
+ :type host: string
+ :param host: The host to send events to
+
+ :type port: integer
+ :param port: The port on the host to send events to
+
+ :param serializer: The serializer to use to serialize the event
+ to a form that can be published to the socket. This must
+ have a `serialize()` method that accepts a monitor event
+ and return bytes
+ """
+ self._socket = socket
+ self._address = (host, port)
+ self._serializer = serializer
+
+ def publish(self, event):
+ """Publishes a specified monitor event
+
+ :type event: BaseMonitorEvent
+ :param event: The monitor event to be sent
+ over the publisher's socket to the desired address.
+ """
+ serialized_event = self._serializer.serialize(event)
+ if len(serialized_event) > self._MAX_MONITOR_EVENT_LENGTH:
+ logger.debug(
+ 'Serialized event of size %s exceeds the maximum length '
+ 'allowed: %s. Not sending event to socket.',
+ len(serialized_event),
+ self._MAX_MONITOR_EVENT_LENGTH,
+ )
+ return
+ self._socket.sendto(serialized_event, self._address)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/paginate.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/paginate.py
new file mode 100644
index 0000000000..42e74d0819
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/paginate.py
@@ -0,0 +1,720 @@
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+import base64
+import json
+import logging
+from itertools import tee
+
+import jmespath
+
+from botocore.exceptions import PaginationError
+from botocore.utils import merge_dicts, set_value_from_jmespath
+
+log = logging.getLogger(__name__)
+
+
+class TokenEncoder:
+ """Encodes dictionaries into opaque strings.
+
+ This for the most part json dumps + base64 encoding, but also supports
+ having bytes in the dictionary in addition to the types that json can
+ handle by default.
+
+ This is intended for use in encoding pagination tokens, which in some
+ cases can be complex structures and / or contain bytes.
+ """
+
+ def encode(self, token):
+ """Encodes a dictionary to an opaque string.
+
+ :type token: dict
+ :param token: A dictionary containing pagination information,
+ particularly the service pagination token(s) but also other boto
+ metadata.
+
+ :rtype: str
+ :returns: An opaque string
+ """
+ try:
+ # Try just using json dumps first to avoid having to traverse
+ # and encode the dict. In 99.9999% of cases this will work.
+ json_string = json.dumps(token)
+ except (TypeError, UnicodeDecodeError):
+ # If normal dumping failed, go through and base64 encode all bytes.
+ encoded_token, encoded_keys = self._encode(token, [])
+
+ # Save the list of all the encoded key paths. We can safely
+ # assume that no service will ever use this key.
+ encoded_token['boto_encoded_keys'] = encoded_keys
+
+ # Now that the bytes are all encoded, dump the json.
+ json_string = json.dumps(encoded_token)
+
+ # base64 encode the json string to produce an opaque token string.
+ return base64.b64encode(json_string.encode('utf-8')).decode('utf-8')
+
+ def _encode(self, data, path):
+ """Encode bytes in given data, keeping track of the path traversed."""
+ if isinstance(data, dict):
+ return self._encode_dict(data, path)
+ elif isinstance(data, list):
+ return self._encode_list(data, path)
+ elif isinstance(data, bytes):
+ return self._encode_bytes(data, path)
+ else:
+ return data, []
+
+ def _encode_list(self, data, path):
+ """Encode any bytes in a list, noting the index of what is encoded."""
+ new_data = []
+ encoded = []
+ for i, value in enumerate(data):
+ new_path = path + [i]
+ new_value, new_encoded = self._encode(value, new_path)
+ new_data.append(new_value)
+ encoded.extend(new_encoded)
+ return new_data, encoded
+
+ def _encode_dict(self, data, path):
+ """Encode any bytes in a dict, noting the index of what is encoded."""
+ new_data = {}
+ encoded = []
+ for key, value in data.items():
+ new_path = path + [key]
+ new_value, new_encoded = self._encode(value, new_path)
+ new_data[key] = new_value
+ encoded.extend(new_encoded)
+ return new_data, encoded
+
+ def _encode_bytes(self, data, path):
+ """Base64 encode a byte string."""
+ return base64.b64encode(data).decode('utf-8'), [path]
+
+
+class TokenDecoder:
+ """Decodes token strings back into dictionaries.
+
+ This performs the inverse operation to the TokenEncoder, accepting
+ opaque strings and decoding them into a useable form.
+ """
+
+ def decode(self, token):
+ """Decodes an opaque string to a dictionary.
+
+ :type token: str
+ :param token: A token string given by the botocore pagination
+ interface.
+
+ :rtype: dict
+ :returns: A dictionary containing pagination information,
+ particularly the service pagination token(s) but also other boto
+ metadata.
+ """
+ json_string = base64.b64decode(token.encode('utf-8')).decode('utf-8')
+ decoded_token = json.loads(json_string)
+
+ # Remove the encoding metadata as it is read since it will no longer
+ # be needed.
+ encoded_keys = decoded_token.pop('boto_encoded_keys', None)
+ if encoded_keys is None:
+ return decoded_token
+ else:
+ return self._decode(decoded_token, encoded_keys)
+
+ def _decode(self, token, encoded_keys):
+ """Find each encoded value and decode it."""
+ for key in encoded_keys:
+ encoded = self._path_get(token, key)
+ decoded = base64.b64decode(encoded.encode('utf-8'))
+ self._path_set(token, key, decoded)
+ return token
+
+ def _path_get(self, data, path):
+ """Return the nested data at the given path.
+
+ For instance:
+ data = {'foo': ['bar', 'baz']}
+ path = ['foo', 0]
+ ==> 'bar'
+ """
+ # jmespath isn't used here because it would be difficult to actually
+ # create the jmespath query when taking all of the unknowns of key
+ # structure into account. Gross though this is, it is simple and not
+ # very error prone.
+ d = data
+ for step in path:
+ d = d[step]
+ return d
+
+ def _path_set(self, data, path, value):
+ """Set the value of a key in the given data.
+
+ Example:
+ data = {'foo': ['bar', 'baz']}
+ path = ['foo', 1]
+ value = 'bin'
+ ==> data = {'foo': ['bar', 'bin']}
+ """
+ container = self._path_get(data, path[:-1])
+ container[path[-1]] = value
+
+
+class PaginatorModel:
+ def __init__(self, paginator_config):
+ self._paginator_config = paginator_config['pagination']
+
+ def get_paginator(self, operation_name):
+ try:
+ single_paginator_config = self._paginator_config[operation_name]
+ except KeyError:
+ raise ValueError(
+ "Paginator for operation does not exist: %s" % operation_name
+ )
+ return single_paginator_config
+
+
+class PageIterator:
+ """An iterable object to paginate API results.
+ Please note it is NOT a python iterator.
+ Use ``iter`` to wrap this as a generator.
+ """
+
+ def __init__(
+ self,
+ method,
+ input_token,
+ output_token,
+ more_results,
+ result_keys,
+ non_aggregate_keys,
+ limit_key,
+ max_items,
+ starting_token,
+ page_size,
+ op_kwargs,
+ ):
+ self._method = method
+ self._input_token = input_token
+ self._output_token = output_token
+ self._more_results = more_results
+ self._result_keys = result_keys
+ self._max_items = max_items
+ self._limit_key = limit_key
+ self._starting_token = starting_token
+ self._page_size = page_size
+ self._op_kwargs = op_kwargs
+ self._resume_token = None
+ self._non_aggregate_key_exprs = non_aggregate_keys
+ self._non_aggregate_part = {}
+ self._token_encoder = TokenEncoder()
+ self._token_decoder = TokenDecoder()
+
+ @property
+ def result_keys(self):
+ return self._result_keys
+
+ @property
+ def resume_token(self):
+ """Token to specify to resume pagination."""
+ return self._resume_token
+
+ @resume_token.setter
+ def resume_token(self, value):
+ if not isinstance(value, dict):
+ raise ValueError("Bad starting token: %s" % value)
+
+ if 'boto_truncate_amount' in value:
+ token_keys = sorted(self._input_token + ['boto_truncate_amount'])
+ else:
+ token_keys = sorted(self._input_token)
+ dict_keys = sorted(value.keys())
+
+ if token_keys == dict_keys:
+ self._resume_token = self._token_encoder.encode(value)
+ else:
+ raise ValueError("Bad starting token: %s" % value)
+
+ @property
+ def non_aggregate_part(self):
+ return self._non_aggregate_part
+
+ def __iter__(self):
+ current_kwargs = self._op_kwargs
+ previous_next_token = None
+ next_token = {key: None for key in self._input_token}
+ if self._starting_token is not None:
+ # If the starting token exists, populate the next_token with the
+ # values inside it. This ensures that we have the service's
+ # pagination token on hand if we need to truncate after the
+ # first response.
+ next_token = self._parse_starting_token()[0]
+ # The number of items from result_key we've seen so far.
+ total_items = 0
+ first_request = True
+ primary_result_key = self.result_keys[0]
+ starting_truncation = 0
+ self._inject_starting_params(current_kwargs)
+ while True:
+ response = self._make_request(current_kwargs)
+ parsed = self._extract_parsed_response(response)
+ if first_request:
+ # The first request is handled differently. We could
+ # possibly have a resume/starting token that tells us where
+ # to index into the retrieved page.
+ if self._starting_token is not None:
+ starting_truncation = self._handle_first_request(
+ parsed, primary_result_key, starting_truncation
+ )
+ first_request = False
+ self._record_non_aggregate_key_values(parsed)
+ else:
+ # If this isn't the first request, we have already sliced into
+ # the first request and had to make additional requests after.
+ # We no longer need to add this to truncation.
+ starting_truncation = 0
+ current_response = primary_result_key.search(parsed)
+ if current_response is None:
+ current_response = []
+ num_current_response = len(current_response)
+ truncate_amount = 0
+ if self._max_items is not None:
+ truncate_amount = (
+ total_items + num_current_response - self._max_items
+ )
+ if truncate_amount > 0:
+ self._truncate_response(
+ parsed,
+ primary_result_key,
+ truncate_amount,
+ starting_truncation,
+ next_token,
+ )
+ yield response
+ break
+ else:
+ yield response
+ total_items += num_current_response
+ next_token = self._get_next_token(parsed)
+ if all(t is None for t in next_token.values()):
+ break
+ if (
+ self._max_items is not None
+ and total_items == self._max_items
+ ):
+ # We're on a page boundary so we can set the current
+ # next token to be the resume token.
+ self.resume_token = next_token
+ break
+ if (
+ previous_next_token is not None
+ and previous_next_token == next_token
+ ):
+ message = (
+ f"The same next token was received "
+ f"twice: {next_token}"
+ )
+ raise PaginationError(message=message)
+ self._inject_token_into_kwargs(current_kwargs, next_token)
+ previous_next_token = next_token
+
+ def search(self, expression):
+ """Applies a JMESPath expression to a paginator
+
+ Each page of results is searched using the provided JMESPath
+ expression. If the result is not a list, it is yielded
+ directly. If the result is a list, each element in the result
+ is yielded individually (essentially implementing a flatmap in
+ which the JMESPath search is the mapping function).
+
+ :type expression: str
+ :param expression: JMESPath expression to apply to each page.
+
+ :return: Returns an iterator that yields the individual
+ elements of applying a JMESPath expression to each page of
+ results.
+ """
+ compiled = jmespath.compile(expression)
+ for page in self:
+ results = compiled.search(page)
+ if isinstance(results, list):
+ yield from results
+ else:
+ # Yield result directly if it is not a list.
+ yield results
+
+ def _make_request(self, current_kwargs):
+ return self._method(**current_kwargs)
+
+ def _extract_parsed_response(self, response):
+ return response
+
+ def _record_non_aggregate_key_values(self, response):
+ non_aggregate_keys = {}
+ for expression in self._non_aggregate_key_exprs:
+ result = expression.search(response)
+ set_value_from_jmespath(
+ non_aggregate_keys, expression.expression, result
+ )
+ self._non_aggregate_part = non_aggregate_keys
+
+ def _inject_starting_params(self, op_kwargs):
+ # If the user has specified a starting token we need to
+ # inject that into the operation's kwargs.
+ if self._starting_token is not None:
+ # Don't need to do anything special if there is no starting
+ # token specified.
+ next_token = self._parse_starting_token()[0]
+ self._inject_token_into_kwargs(op_kwargs, next_token)
+ if self._page_size is not None:
+ # Pass the page size as the parameter name for limiting
+ # page size, also known as the limit_key.
+ op_kwargs[self._limit_key] = self._page_size
+
+ def _inject_token_into_kwargs(self, op_kwargs, next_token):
+ for name, token in next_token.items():
+ if (token is not None) and (token != 'None'):
+ op_kwargs[name] = token
+ elif name in op_kwargs:
+ del op_kwargs[name]
+
+ def _handle_first_request(
+ self, parsed, primary_result_key, starting_truncation
+ ):
+ # If the payload is an array or string, we need to slice into it
+ # and only return the truncated amount.
+ starting_truncation = self._parse_starting_token()[1]
+ all_data = primary_result_key.search(parsed)
+ if isinstance(all_data, (list, str)):
+ data = all_data[starting_truncation:]
+ else:
+ data = None
+ set_value_from_jmespath(parsed, primary_result_key.expression, data)
+ # We also need to truncate any secondary result keys
+ # because they were not truncated in the previous last
+ # response.
+ for token in self.result_keys:
+ if token == primary_result_key:
+ continue
+ sample = token.search(parsed)
+ if isinstance(sample, list):
+ empty_value = []
+ elif isinstance(sample, str):
+ empty_value = ''
+ elif isinstance(sample, (int, float)):
+ empty_value = 0
+ else:
+ empty_value = None
+ set_value_from_jmespath(parsed, token.expression, empty_value)
+ return starting_truncation
+
+ def _truncate_response(
+ self,
+ parsed,
+ primary_result_key,
+ truncate_amount,
+ starting_truncation,
+ next_token,
+ ):
+ original = primary_result_key.search(parsed)
+ if original is None:
+ original = []
+ amount_to_keep = len(original) - truncate_amount
+ truncated = original[:amount_to_keep]
+ set_value_from_jmespath(
+ parsed, primary_result_key.expression, truncated
+ )
+ # The issue here is that even though we know how much we've truncated
+ # we need to account for this globally including any starting
+ # left truncation. For example:
+ # Raw response: [0,1,2,3]
+ # Starting index: 1
+ # Max items: 1
+ # Starting left truncation: [1, 2, 3]
+ # End right truncation for max items: [1]
+ # However, even though we only kept 1, this is post
+ # left truncation so the next starting index should be 2, not 1
+ # (left_truncation + amount_to_keep).
+ next_token['boto_truncate_amount'] = (
+ amount_to_keep + starting_truncation
+ )
+ self.resume_token = next_token
+
+ def _get_next_token(self, parsed):
+ if self._more_results is not None:
+ if not self._more_results.search(parsed):
+ return {}
+ next_tokens = {}
+ for output_token, input_key in zip(
+ self._output_token, self._input_token
+ ):
+ next_token = output_token.search(parsed)
+ # We do not want to include any empty strings as actual tokens.
+ # Treat them as None.
+ if next_token:
+ next_tokens[input_key] = next_token
+ else:
+ next_tokens[input_key] = None
+ return next_tokens
+
+ def result_key_iters(self):
+ teed_results = tee(self, len(self.result_keys))
+ return [
+ ResultKeyIterator(i, result_key)
+ for i, result_key in zip(teed_results, self.result_keys)
+ ]
+
+ def build_full_result(self):
+ complete_result = {}
+ for response in self:
+ page = response
+ # We want to try to catch operation object pagination
+ # and format correctly for those. They come in the form
+ # of a tuple of two elements: (http_response, parsed_responsed).
+ # We want the parsed_response as that is what the page iterator
+ # uses. We can remove it though once operation objects are removed.
+ if isinstance(response, tuple) and len(response) == 2:
+ page = response[1]
+ # We're incrementally building the full response page
+ # by page. For each page in the response we need to
+ # inject the necessary components from the page
+ # into the complete_result.
+ for result_expression in self.result_keys:
+ # In order to incrementally update a result key
+ # we need to search the existing value from complete_result,
+ # then we need to search the _current_ page for the
+ # current result key value. Then we append the current
+ # value onto the existing value, and re-set that value
+ # as the new value.
+ result_value = result_expression.search(page)
+ if result_value is None:
+ continue
+ existing_value = result_expression.search(complete_result)
+ if existing_value is None:
+ # Set the initial result
+ set_value_from_jmespath(
+ complete_result,
+ result_expression.expression,
+ result_value,
+ )
+ continue
+ # Now both result_value and existing_value contain something
+ if isinstance(result_value, list):
+ existing_value.extend(result_value)
+ elif isinstance(result_value, (int, float, str)):
+ # Modify the existing result with the sum or concatenation
+ set_value_from_jmespath(
+ complete_result,
+ result_expression.expression,
+ existing_value + result_value,
+ )
+ merge_dicts(complete_result, self.non_aggregate_part)
+ if self.resume_token is not None:
+ complete_result['NextToken'] = self.resume_token
+ return complete_result
+
+ def _parse_starting_token(self):
+ if self._starting_token is None:
+ return None
+
+ # The starting token is a dict passed as a base64 encoded string.
+ next_token = self._starting_token
+ try:
+ next_token = self._token_decoder.decode(next_token)
+ index = 0
+ if 'boto_truncate_amount' in next_token:
+ index = next_token.get('boto_truncate_amount')
+ del next_token['boto_truncate_amount']
+ except (ValueError, TypeError):
+ next_token, index = self._parse_starting_token_deprecated()
+ return next_token, index
+
+ def _parse_starting_token_deprecated(self):
+ """
+ This handles parsing of old style starting tokens, and attempts to
+ coerce them into the new style.
+ """
+ log.debug(
+ "Attempting to fall back to old starting token parser. For "
+ "token: %s" % self._starting_token
+ )
+ if self._starting_token is None:
+ return None
+
+ parts = self._starting_token.split('___')
+ next_token = []
+ index = 0
+ if len(parts) == len(self._input_token) + 1:
+ try:
+ index = int(parts.pop())
+ except ValueError:
+ # This doesn't look like a valid old-style token, so we're
+ # passing it along as an opaque service token.
+ parts = [self._starting_token]
+
+ for part in parts:
+ if part == 'None':
+ next_token.append(None)
+ else:
+ next_token.append(part)
+ return self._convert_deprecated_starting_token(next_token), index
+
+ def _convert_deprecated_starting_token(self, deprecated_token):
+ """
+ This attempts to convert a deprecated starting token into the new
+ style.
+ """
+ len_deprecated_token = len(deprecated_token)
+ len_input_token = len(self._input_token)
+ if len_deprecated_token > len_input_token:
+ raise ValueError("Bad starting token: %s" % self._starting_token)
+ elif len_deprecated_token < len_input_token:
+ log.debug(
+ "Old format starting token does not contain all input "
+ "tokens. Setting the rest, in order, as None."
+ )
+ for i in range(len_input_token - len_deprecated_token):
+ deprecated_token.append(None)
+ return dict(zip(self._input_token, deprecated_token))
+
+
+class Paginator:
+ PAGE_ITERATOR_CLS = PageIterator
+
+ def __init__(self, method, pagination_config, model):
+ self._model = model
+ self._method = method
+ self._pagination_cfg = pagination_config
+ self._output_token = self._get_output_tokens(self._pagination_cfg)
+ self._input_token = self._get_input_tokens(self._pagination_cfg)
+ self._more_results = self._get_more_results_token(self._pagination_cfg)
+ self._non_aggregate_keys = self._get_non_aggregate_keys(
+ self._pagination_cfg
+ )
+ self._result_keys = self._get_result_keys(self._pagination_cfg)
+ self._limit_key = self._get_limit_key(self._pagination_cfg)
+
+ @property
+ def result_keys(self):
+ return self._result_keys
+
+ def _get_non_aggregate_keys(self, config):
+ keys = []
+ for key in config.get('non_aggregate_keys', []):
+ keys.append(jmespath.compile(key))
+ return keys
+
+ def _get_output_tokens(self, config):
+ output = []
+ output_token = config['output_token']
+ if not isinstance(output_token, list):
+ output_token = [output_token]
+ for config in output_token:
+ output.append(jmespath.compile(config))
+ return output
+
+ def _get_input_tokens(self, config):
+ input_token = self._pagination_cfg['input_token']
+ if not isinstance(input_token, list):
+ input_token = [input_token]
+ return input_token
+
+ def _get_more_results_token(self, config):
+ more_results = config.get('more_results')
+ if more_results is not None:
+ return jmespath.compile(more_results)
+
+ def _get_result_keys(self, config):
+ result_key = config.get('result_key')
+ if result_key is not None:
+ if not isinstance(result_key, list):
+ result_key = [result_key]
+ result_key = [jmespath.compile(rk) for rk in result_key]
+ return result_key
+
+ def _get_limit_key(self, config):
+ return config.get('limit_key')
+
+ def paginate(self, **kwargs):
+ """Create paginator object for an operation.
+
+ This returns an iterable object. Iterating over
+ this object will yield a single page of a response
+ at a time.
+
+ """
+ page_params = self._extract_paging_params(kwargs)
+ return self.PAGE_ITERATOR_CLS(
+ self._method,
+ self._input_token,
+ self._output_token,
+ self._more_results,
+ self._result_keys,
+ self._non_aggregate_keys,
+ self._limit_key,
+ page_params['MaxItems'],
+ page_params['StartingToken'],
+ page_params['PageSize'],
+ kwargs,
+ )
+
+ def _extract_paging_params(self, kwargs):
+ pagination_config = kwargs.pop('PaginationConfig', {})
+ max_items = pagination_config.get('MaxItems', None)
+ if max_items is not None:
+ max_items = int(max_items)
+ page_size = pagination_config.get('PageSize', None)
+ if page_size is not None:
+ if self._limit_key is None:
+ raise PaginationError(
+ message="PageSize parameter is not supported for the "
+ "pagination interface for this operation."
+ )
+ input_members = self._model.input_shape.members
+ limit_key_shape = input_members.get(self._limit_key)
+ if limit_key_shape.type_name == 'string':
+ if not isinstance(page_size, str):
+ page_size = str(page_size)
+ else:
+ page_size = int(page_size)
+ return {
+ 'MaxItems': max_items,
+ 'StartingToken': pagination_config.get('StartingToken', None),
+ 'PageSize': page_size,
+ }
+
+
+class ResultKeyIterator:
+ """Iterates over the results of paginated responses.
+
+ Each iterator is associated with a single result key.
+ Iterating over this object will give you each element in
+ the result key list.
+
+ :param pages_iterator: An iterator that will give you
+ pages of results (a ``PageIterator`` class).
+ :param result_key: The JMESPath expression representing
+ the result key.
+
+ """
+
+ def __init__(self, pages_iterator, result_key):
+ self._pages_iterator = pages_iterator
+ self.result_key = result_key
+
+ def __iter__(self):
+ for page in self._pages_iterator:
+ results = self.result_key.search(page)
+ if results is None:
+ results = []
+ yield from results
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/parsers.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/parsers.py
new file mode 100644
index 0000000000..3905757c85
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/parsers.py
@@ -0,0 +1,1122 @@
+# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""Response parsers for the various protocol types.
+
+The module contains classes that can take an HTTP response, and given
+an output shape, parse the response into a dict according to the
+rules in the output shape.
+
+There are many similarities amongst the different protocols with regard
+to response parsing, and the code is structured in a way to avoid
+code duplication when possible. The diagram below is a diagram
+showing the inheritance hierarchy of the response classes.
+
+::
+
+
+
+ +--------------+
+ |ResponseParser|
+ +--------------+
+ ^ ^ ^
+ +--------------------+ | +-------------------+
+ | | |
+ +----------+----------+ +------+-------+ +-------+------+
+ |BaseXMLResponseParser| |BaseRestParser| |BaseJSONParser|
+ +---------------------+ +--------------+ +--------------+
+ ^ ^ ^ ^ ^ ^
+ | | | | | |
+ | | | | | |
+ | ++----------+-+ +-+-----------++ |
+ | |RestXMLParser| |RestJSONParser| |
+ +-----+-----+ +-------------+ +--------------+ +----+-----+
+ |QueryParser| |JSONParser|
+ +-----------+ +----------+
+
+
+The diagram above shows that there is a base class, ``ResponseParser`` that
+contains logic that is similar amongst all the different protocols (``query``,
+``json``, ``rest-json``, ``rest-xml``). Amongst the various services there
+is shared logic that can be grouped several ways:
+
+* The ``query`` and ``rest-xml`` both have XML bodies that are parsed in the
+ same way.
+* The ``json`` and ``rest-json`` protocols both have JSON bodies that are
+ parsed in the same way.
+* The ``rest-json`` and ``rest-xml`` protocols have additional attributes
+ besides body parameters that are parsed the same (headers, query string,
+ status code).
+
+This is reflected in the class diagram above. The ``BaseXMLResponseParser``
+and the BaseJSONParser contain logic for parsing the XML/JSON body,
+and the BaseRestParser contains logic for parsing out attributes that
+come from other parts of the HTTP response. Classes like the
+``RestXMLParser`` inherit from the ``BaseXMLResponseParser`` to get the
+XML body parsing logic and the ``BaseRestParser`` to get the HTTP
+header/status code/query string parsing.
+
+Additionally, there are event stream parsers that are used by the other parsers
+to wrap streaming bodies that represent a stream of events. The
+BaseEventStreamParser extends from ResponseParser and defines the logic for
+parsing values from the headers and payload of a message from the underlying
+binary encoding protocol. Currently, event streams support parsing bodies
+encoded as JSON and XML through the following hierarchy.
+
+
+ +--------------+
+ |ResponseParser|
+ +--------------+
+ ^ ^ ^
+ +--------------------+ | +------------------+
+ | | |
+ +----------+----------+ +----------+----------+ +-------+------+
+ |BaseXMLResponseParser| |BaseEventStreamParser| |BaseJSONParser|
+ +---------------------+ +---------------------+ +--------------+
+ ^ ^ ^ ^
+ | | | |
+ | | | |
+ +-+----------------+-+ +-+-----------------+-+
+ |EventStreamXMLParser| |EventStreamJSONParser|
+ +--------------------+ +---------------------+
+
+Return Values
+=============
+
+Each call to ``parse()`` returns a dict has this form::
+
+ Standard Response
+
+ {
+ "ResponseMetadata": {"RequestId": }
+
+ }
+
+ Error response
+
+ {
+ "ResponseMetadata": {"RequestId": }
+ "Error": {
+ "Code": ,
+ "Message": ,
+ "Type": ,
+
+ }
+ }
+
+"""
+import base64
+import http.client
+import json
+import logging
+import re
+
+from botocore.compat import ETree, XMLParseError
+from botocore.eventstream import EventStream, NoInitialResponseError
+from botocore.utils import (
+ is_json_value_header,
+ lowercase_dict,
+ merge_dicts,
+ parse_timestamp,
+)
+
+LOG = logging.getLogger(__name__)
+
+DEFAULT_TIMESTAMP_PARSER = parse_timestamp
+
+
+class ResponseParserFactory:
+ def __init__(self):
+ self._defaults = {}
+
+ def set_parser_defaults(self, **kwargs):
+ """Set default arguments when a parser instance is created.
+
+ You can specify any kwargs that are allowed by a ResponseParser
+ class. There are currently two arguments:
+
+ * timestamp_parser - A callable that can parse a timestamp string
+ * blob_parser - A callable that can parse a blob type
+
+ """
+ self._defaults.update(kwargs)
+
+ def create_parser(self, protocol_name):
+ parser_cls = PROTOCOL_PARSERS[protocol_name]
+ return parser_cls(**self._defaults)
+
+
+def create_parser(protocol):
+ return ResponseParserFactory().create_parser(protocol)
+
+
+def _text_content(func):
+ # This decorator hides the difference between
+ # an XML node with text or a plain string. It's used
+ # to ensure that scalar processing operates only on text
+ # strings, which allows the same scalar handlers to be used
+ # for XML nodes from the body and HTTP headers.
+ def _get_text_content(self, shape, node_or_string):
+ if hasattr(node_or_string, 'text'):
+ text = node_or_string.text
+ if text is None:
+ # If an XML node is empty ,
+ # we want to parse that as an empty string,
+ # not as a null/None value.
+ text = ''
+ else:
+ text = node_or_string
+ return func(self, shape, text)
+
+ return _get_text_content
+
+
+class ResponseParserError(Exception):
+ pass
+
+
+class ResponseParser:
+ """Base class for response parsing.
+
+ This class represents the interface that all ResponseParsers for the
+ various protocols must implement.
+
+ This class will take an HTTP response and a model shape and parse the
+ HTTP response into a dictionary.
+
+ There is a single public method exposed: ``parse``. See the ``parse``
+ docstring for more info.
+
+ """
+
+ DEFAULT_ENCODING = 'utf-8'
+ EVENT_STREAM_PARSER_CLS = None
+
+ def __init__(self, timestamp_parser=None, blob_parser=None):
+ if timestamp_parser is None:
+ timestamp_parser = DEFAULT_TIMESTAMP_PARSER
+ self._timestamp_parser = timestamp_parser
+ if blob_parser is None:
+ blob_parser = self._default_blob_parser
+ self._blob_parser = blob_parser
+ self._event_stream_parser = None
+ if self.EVENT_STREAM_PARSER_CLS is not None:
+ self._event_stream_parser = self.EVENT_STREAM_PARSER_CLS(
+ timestamp_parser, blob_parser
+ )
+
+ def _default_blob_parser(self, value):
+ # Blobs are always returned as bytes type (this matters on python3).
+ # We don't decode this to a str because it's entirely possible that the
+ # blob contains binary data that actually can't be decoded.
+ return base64.b64decode(value)
+
+ def parse(self, response, shape):
+ """Parse the HTTP response given a shape.
+
+ :param response: The HTTP response dictionary. This is a dictionary
+ that represents the HTTP request. The dictionary must have the
+ following keys, ``body``, ``headers``, and ``status_code``.
+
+ :param shape: The model shape describing the expected output.
+ :return: Returns a dictionary representing the parsed response
+ described by the model. In addition to the shape described from
+ the model, each response will also have a ``ResponseMetadata``
+ which contains metadata about the response, which contains at least
+ two keys containing ``RequestId`` and ``HTTPStatusCode``. Some
+ responses may populate additional keys, but ``RequestId`` will
+ always be present.
+
+ """
+ LOG.debug('Response headers: %r', response['headers'])
+ LOG.debug('Response body:\n%r', response['body'])
+ if response['status_code'] >= 301:
+ if self._is_generic_error_response(response):
+ parsed = self._do_generic_error_parse(response)
+ elif self._is_modeled_error_shape(shape):
+ parsed = self._do_modeled_error_parse(response, shape)
+ # We don't want to decorate the modeled fields with metadata
+ return parsed
+ else:
+ parsed = self._do_error_parse(response, shape)
+ else:
+ parsed = self._do_parse(response, shape)
+
+ # We don't want to decorate event stream responses with metadata
+ if shape and shape.serialization.get('eventstream'):
+ return parsed
+
+ # Add ResponseMetadata if it doesn't exist and inject the HTTP
+ # status code and headers from the response.
+ if isinstance(parsed, dict):
+ response_metadata = parsed.get('ResponseMetadata', {})
+ response_metadata['HTTPStatusCode'] = response['status_code']
+ # Ensure that the http header keys are all lower cased. Older
+ # versions of urllib3 (< 1.11) would unintentionally do this for us
+ # (see urllib3#633). We need to do this conversion manually now.
+ headers = response['headers']
+ response_metadata['HTTPHeaders'] = lowercase_dict(headers)
+ parsed['ResponseMetadata'] = response_metadata
+ self._add_checksum_response_metadata(response, response_metadata)
+ return parsed
+
+ def _add_checksum_response_metadata(self, response, response_metadata):
+ checksum_context = response.get('context', {}).get('checksum', {})
+ algorithm = checksum_context.get('response_algorithm')
+ if algorithm:
+ response_metadata['ChecksumAlgorithm'] = algorithm
+
+ def _is_modeled_error_shape(self, shape):
+ return shape is not None and shape.metadata.get('exception', False)
+
+ def _is_generic_error_response(self, response):
+ # There are times when a service will respond with a generic
+ # error response such as:
+ # 'Http/1.1 Service Unavailable'
+ #
+ # This can also happen if you're going through a proxy.
+ # In this case the protocol specific _do_error_parse will either
+ # fail to parse the response (in the best case) or silently succeed
+ # and treat the HTML above as an XML response and return
+ # non sensical parsed data.
+ # To prevent this case from happening we first need to check
+ # whether or not this response looks like the generic response.
+ if response['status_code'] >= 500:
+ if 'body' not in response or response['body'] is None:
+ return True
+
+ body = response['body'].strip()
+ return body.startswith(b'') or not body
+
+ def _do_generic_error_parse(self, response):
+ # There's not really much we can do when we get a generic
+ # html response.
+ LOG.debug(
+ "Received a non protocol specific error response from the "
+ "service, unable to populate error code and message."
+ )
+ return {
+ 'Error': {
+ 'Code': str(response['status_code']),
+ 'Message': http.client.responses.get(
+ response['status_code'], ''
+ ),
+ },
+ 'ResponseMetadata': {},
+ }
+
+ def _do_parse(self, response, shape):
+ raise NotImplementedError("%s._do_parse" % self.__class__.__name__)
+
+ def _do_error_parse(self, response, shape):
+ raise NotImplementedError(f"{self.__class__.__name__}._do_error_parse")
+
+ def _do_modeled_error_parse(self, response, shape, parsed):
+ raise NotImplementedError(
+ f"{self.__class__.__name__}._do_modeled_error_parse"
+ )
+
+ def _parse_shape(self, shape, node):
+ handler = getattr(
+ self, f'_handle_{shape.type_name}', self._default_handle
+ )
+ return handler(shape, node)
+
+ def _handle_list(self, shape, node):
+ # Enough implementations share list serialization that it's moved
+ # up here in the base class.
+ parsed = []
+ member_shape = shape.member
+ for item in node:
+ parsed.append(self._parse_shape(member_shape, item))
+ return parsed
+
+ def _default_handle(self, shape, value):
+ return value
+
+ def _create_event_stream(self, response, shape):
+ parser = self._event_stream_parser
+ name = response['context'].get('operation_name')
+ return EventStream(response['body'], shape, parser, name)
+
+ def _get_first_key(self, value):
+ return list(value)[0]
+
+ def _has_unknown_tagged_union_member(self, shape, value):
+ if shape.is_tagged_union:
+ cleaned_value = value.copy()
+ cleaned_value.pop("__type", None)
+ if len(cleaned_value) != 1:
+ error_msg = (
+ "Invalid service response: %s must have one and only "
+ "one member set."
+ )
+ raise ResponseParserError(error_msg % shape.name)
+ tag = self._get_first_key(cleaned_value)
+ if tag not in shape.members:
+ msg = (
+ "Received a tagged union response with member "
+ "unknown to client: %s. Please upgrade SDK for full "
+ "response support."
+ )
+ LOG.info(msg % tag)
+ return True
+ return False
+
+ def _handle_unknown_tagged_union_member(self, tag):
+ return {'SDK_UNKNOWN_MEMBER': {'name': tag}}
+
+
+class BaseXMLResponseParser(ResponseParser):
+ def __init__(self, timestamp_parser=None, blob_parser=None):
+ super().__init__(timestamp_parser, blob_parser)
+ self._namespace_re = re.compile('{.*}')
+
+ def _handle_map(self, shape, node):
+ parsed = {}
+ key_shape = shape.key
+ value_shape = shape.value
+ key_location_name = key_shape.serialization.get('name') or 'key'
+ value_location_name = value_shape.serialization.get('name') or 'value'
+ if shape.serialization.get('flattened') and not isinstance(node, list):
+ node = [node]
+ for keyval_node in node:
+ for single_pair in keyval_node:
+ # Within each there's a and a
+ tag_name = self._node_tag(single_pair)
+ if tag_name == key_location_name:
+ key_name = self._parse_shape(key_shape, single_pair)
+ elif tag_name == value_location_name:
+ val_name = self._parse_shape(value_shape, single_pair)
+ else:
+ raise ResponseParserError("Unknown tag: %s" % tag_name)
+ parsed[key_name] = val_name
+ return parsed
+
+ def _node_tag(self, node):
+ return self._namespace_re.sub('', node.tag)
+
+ def _handle_list(self, shape, node):
+ # When we use _build_name_to_xml_node, repeated elements are aggregated
+ # into a list. However, we can't tell the difference between a scalar
+ # value and a single element flattened list. So before calling the
+ # real _handle_list, we know that "node" should actually be a list if
+ # it's flattened, and if it's not, then we make it a one element list.
+ if shape.serialization.get('flattened') and not isinstance(node, list):
+ node = [node]
+ return super()._handle_list(shape, node)
+
+ def _handle_structure(self, shape, node):
+ parsed = {}
+ members = shape.members
+ if shape.metadata.get('exception', False):
+ node = self._get_error_root(node)
+ xml_dict = self._build_name_to_xml_node(node)
+ if self._has_unknown_tagged_union_member(shape, xml_dict):
+ tag = self._get_first_key(xml_dict)
+ return self._handle_unknown_tagged_union_member(tag)
+ for member_name in members:
+ member_shape = members[member_name]
+ if (
+ 'location' in member_shape.serialization
+ or member_shape.serialization.get('eventheader')
+ ):
+ # All members with locations have already been handled,
+ # so we don't need to parse these members.
+ continue
+ xml_name = self._member_key_name(member_shape, member_name)
+ member_node = xml_dict.get(xml_name)
+ if member_node is not None:
+ parsed[member_name] = self._parse_shape(
+ member_shape, member_node
+ )
+ elif member_shape.serialization.get('xmlAttribute'):
+ attribs = {}
+ location_name = member_shape.serialization['name']
+ for key, value in node.attrib.items():
+ new_key = self._namespace_re.sub(
+ location_name.split(':')[0] + ':', key
+ )
+ attribs[new_key] = value
+ if location_name in attribs:
+ parsed[member_name] = attribs[location_name]
+ return parsed
+
+ def _get_error_root(self, original_root):
+ if self._node_tag(original_root) == 'ErrorResponse':
+ for child in original_root:
+ if self._node_tag(child) == 'Error':
+ return child
+ return original_root
+
+ def _member_key_name(self, shape, member_name):
+ # This method is needed because we have to special case flattened list
+ # with a serialization name. If this is the case we use the
+ # locationName from the list's member shape as the key name for the
+ # surrounding structure.
+ if shape.type_name == 'list' and shape.serialization.get('flattened'):
+ list_member_serialized_name = shape.member.serialization.get(
+ 'name'
+ )
+ if list_member_serialized_name is not None:
+ return list_member_serialized_name
+ serialized_name = shape.serialization.get('name')
+ if serialized_name is not None:
+ return serialized_name
+ return member_name
+
+ def _build_name_to_xml_node(self, parent_node):
+ # If the parent node is actually a list. We should not be trying
+ # to serialize it to a dictionary. Instead, return the first element
+ # in the list.
+ if isinstance(parent_node, list):
+ return self._build_name_to_xml_node(parent_node[0])
+ xml_dict = {}
+ for item in parent_node:
+ key = self._node_tag(item)
+ if key in xml_dict:
+ # If the key already exists, the most natural
+ # way to handle this is to aggregate repeated
+ # keys into a single list.
+ # 12 -> {'foo': [Node(1), Node(2)]}
+ if isinstance(xml_dict[key], list):
+ xml_dict[key].append(item)
+ else:
+ # Convert from a scalar to a list.
+ xml_dict[key] = [xml_dict[key], item]
+ else:
+ xml_dict[key] = item
+ return xml_dict
+
+ def _parse_xml_string_to_dom(self, xml_string):
+ try:
+ parser = ETree.XMLParser(
+ target=ETree.TreeBuilder(), encoding=self.DEFAULT_ENCODING
+ )
+ parser.feed(xml_string)
+ root = parser.close()
+ except XMLParseError as e:
+ raise ResponseParserError(
+ "Unable to parse response (%s), "
+ "invalid XML received. Further retries may succeed:\n%s"
+ % (e, xml_string)
+ )
+ return root
+
+ def _replace_nodes(self, parsed):
+ for key, value in parsed.items():
+ if list(value):
+ sub_dict = self._build_name_to_xml_node(value)
+ parsed[key] = self._replace_nodes(sub_dict)
+ else:
+ parsed[key] = value.text
+ return parsed
+
+ @_text_content
+ def _handle_boolean(self, shape, text):
+ if text == 'true':
+ return True
+ else:
+ return False
+
+ @_text_content
+ def _handle_float(self, shape, text):
+ return float(text)
+
+ @_text_content
+ def _handle_timestamp(self, shape, text):
+ return self._timestamp_parser(text)
+
+ @_text_content
+ def _handle_integer(self, shape, text):
+ return int(text)
+
+ @_text_content
+ def _handle_string(self, shape, text):
+ return text
+
+ @_text_content
+ def _handle_blob(self, shape, text):
+ return self._blob_parser(text)
+
+ _handle_character = _handle_string
+ _handle_double = _handle_float
+ _handle_long = _handle_integer
+
+
+class QueryParser(BaseXMLResponseParser):
+ def _do_error_parse(self, response, shape):
+ xml_contents = response['body']
+ root = self._parse_xml_string_to_dom(xml_contents)
+ parsed = self._build_name_to_xml_node(root)
+ self._replace_nodes(parsed)
+ # Once we've converted xml->dict, we need to make one or two
+ # more adjustments to extract nested errors and to be consistent
+ # with ResponseMetadata for non-error responses:
+ # 1. {"Errors": {"Error": {...}}} -> {"Error": {...}}
+ # 2. {"RequestId": "id"} -> {"ResponseMetadata": {"RequestId": "id"}}
+ if 'Errors' in parsed:
+ parsed.update(parsed.pop('Errors'))
+ if 'RequestId' in parsed:
+ parsed['ResponseMetadata'] = {'RequestId': parsed.pop('RequestId')}
+ return parsed
+
+ def _do_modeled_error_parse(self, response, shape):
+ return self._parse_body_as_xml(response, shape, inject_metadata=False)
+
+ def _do_parse(self, response, shape):
+ return self._parse_body_as_xml(response, shape, inject_metadata=True)
+
+ def _parse_body_as_xml(self, response, shape, inject_metadata=True):
+ xml_contents = response['body']
+ root = self._parse_xml_string_to_dom(xml_contents)
+ parsed = {}
+ if shape is not None:
+ start = root
+ if 'resultWrapper' in shape.serialization:
+ start = self._find_result_wrapped_shape(
+ shape.serialization['resultWrapper'], root
+ )
+ parsed = self._parse_shape(shape, start)
+ if inject_metadata:
+ self._inject_response_metadata(root, parsed)
+ return parsed
+
+ def _find_result_wrapped_shape(self, element_name, xml_root_node):
+ mapping = self._build_name_to_xml_node(xml_root_node)
+ return mapping[element_name]
+
+ def _inject_response_metadata(self, node, inject_into):
+ mapping = self._build_name_to_xml_node(node)
+ child_node = mapping.get('ResponseMetadata')
+ if child_node is not None:
+ sub_mapping = self._build_name_to_xml_node(child_node)
+ for key, value in sub_mapping.items():
+ sub_mapping[key] = value.text
+ inject_into['ResponseMetadata'] = sub_mapping
+
+
+class EC2QueryParser(QueryParser):
+ def _inject_response_metadata(self, node, inject_into):
+ mapping = self._build_name_to_xml_node(node)
+ child_node = mapping.get('requestId')
+ if child_node is not None:
+ inject_into['ResponseMetadata'] = {'RequestId': child_node.text}
+
+ def _do_error_parse(self, response, shape):
+ # EC2 errors look like:
+ #
+ #
+ #
+ # InvalidInstanceID.Malformed
+ # Invalid id: "1343124"
+ #
+ #
+ # 12345
+ #
+ # This is different from QueryParser in that it's RequestID,
+ # not RequestId
+ original = super()._do_error_parse(response, shape)
+ if 'RequestID' in original:
+ original['ResponseMetadata'] = {
+ 'RequestId': original.pop('RequestID')
+ }
+ return original
+
+ def _get_error_root(self, original_root):
+ for child in original_root:
+ if self._node_tag(child) == 'Errors':
+ for errors_child in child:
+ if self._node_tag(errors_child) == 'Error':
+ return errors_child
+ return original_root
+
+
+class BaseJSONParser(ResponseParser):
+ def _handle_structure(self, shape, value):
+ final_parsed = {}
+ if shape.is_document_type:
+ final_parsed = value
+ else:
+ member_shapes = shape.members
+ if value is None:
+ # If the comes across the wire as "null" (None in python),
+ # we should be returning this unchanged, instead of as an
+ # empty dict.
+ return None
+ final_parsed = {}
+ if self._has_unknown_tagged_union_member(shape, value):
+ tag = self._get_first_key(value)
+ return self._handle_unknown_tagged_union_member(tag)
+ for member_name in member_shapes:
+ member_shape = member_shapes[member_name]
+ json_name = member_shape.serialization.get('name', member_name)
+ raw_value = value.get(json_name)
+ if raw_value is not None:
+ final_parsed[member_name] = self._parse_shape(
+ member_shapes[member_name], raw_value
+ )
+ return final_parsed
+
+ def _handle_map(self, shape, value):
+ parsed = {}
+ key_shape = shape.key
+ value_shape = shape.value
+ for key, value in value.items():
+ actual_key = self._parse_shape(key_shape, key)
+ actual_value = self._parse_shape(value_shape, value)
+ parsed[actual_key] = actual_value
+ return parsed
+
+ def _handle_blob(self, shape, value):
+ return self._blob_parser(value)
+
+ def _handle_timestamp(self, shape, value):
+ return self._timestamp_parser(value)
+
+ def _do_error_parse(self, response, shape):
+ body = self._parse_body_as_json(response['body'])
+ error = {"Error": {"Message": '', "Code": ''}, "ResponseMetadata": {}}
+ headers = response['headers']
+ # Error responses can have slightly different structures for json.
+ # The basic structure is:
+ #
+ # {"__type":"ConnectClientException",
+ # "message":"The error message."}
+
+ # The error message can either come in the 'message' or 'Message' key
+ # so we need to check for both.
+ error['Error']['Message'] = body.get(
+ 'message', body.get('Message', '')
+ )
+ # if the message did not contain an error code
+ # include the response status code
+ response_code = response.get('status_code')
+
+ code = body.get('__type', response_code and str(response_code))
+ if code is not None:
+ # code has a couple forms as well:
+ # * "com.aws.dynamodb.vAPI#ProvisionedThroughputExceededException"
+ # * "ResourceNotFoundException"
+ if '#' in code:
+ code = code.rsplit('#', 1)[1]
+ if 'x-amzn-query-error' in headers:
+ code = self._do_query_compatible_error_parse(
+ code, headers, error
+ )
+ error['Error']['Code'] = code
+ self._inject_response_metadata(error, response['headers'])
+ return error
+
+ def _do_query_compatible_error_parse(self, code, headers, error):
+ """
+ Error response may contain an x-amzn-query-error header to translate
+ errors codes from former `query` services into `json`. We use this to
+ do our lookup in the errorfactory for modeled errors.
+ """
+ query_error = headers['x-amzn-query-error']
+ query_error_components = query_error.split(';')
+
+ if len(query_error_components) == 2 and query_error_components[0]:
+ error['Error']['QueryErrorCode'] = code
+ error['Error']['Type'] = query_error_components[1]
+ return query_error_components[0]
+ return code
+
+ def _inject_response_metadata(self, parsed, headers):
+ if 'x-amzn-requestid' in headers:
+ parsed.setdefault('ResponseMetadata', {})['RequestId'] = headers[
+ 'x-amzn-requestid'
+ ]
+
+ def _parse_body_as_json(self, body_contents):
+ if not body_contents:
+ return {}
+ body = body_contents.decode(self.DEFAULT_ENCODING)
+ try:
+ original_parsed = json.loads(body)
+ return original_parsed
+ except ValueError:
+ # if the body cannot be parsed, include
+ # the literal string as the message
+ return {'message': body}
+
+
+class BaseEventStreamParser(ResponseParser):
+ def _do_parse(self, response, shape):
+ final_parsed = {}
+ if shape.serialization.get('eventstream'):
+ event_type = response['headers'].get(':event-type')
+ event_shape = shape.members.get(event_type)
+ if event_shape:
+ final_parsed[event_type] = self._do_parse(
+ response, event_shape
+ )
+ else:
+ self._parse_non_payload_attrs(
+ response, shape, shape.members, final_parsed
+ )
+ self._parse_payload(response, shape, shape.members, final_parsed)
+ return final_parsed
+
+ def _do_error_parse(self, response, shape):
+ exception_type = response['headers'].get(':exception-type')
+ exception_shape = shape.members.get(exception_type)
+ if exception_shape is not None:
+ original_parsed = self._initial_body_parse(response['body'])
+ body = self._parse_shape(exception_shape, original_parsed)
+ error = {
+ 'Error': {
+ 'Code': exception_type,
+ 'Message': body.get('Message', body.get('message', '')),
+ }
+ }
+ else:
+ error = {
+ 'Error': {
+ 'Code': response['headers'].get(':error-code', ''),
+ 'Message': response['headers'].get(':error-message', ''),
+ }
+ }
+ return error
+
+ def _parse_payload(self, response, shape, member_shapes, final_parsed):
+ if shape.serialization.get('event'):
+ for name in member_shapes:
+ member_shape = member_shapes[name]
+ if member_shape.serialization.get('eventpayload'):
+ body = response['body']
+ if member_shape.type_name == 'blob':
+ parsed_body = body
+ elif member_shape.type_name == 'string':
+ parsed_body = body.decode(self.DEFAULT_ENCODING)
+ else:
+ raw_parse = self._initial_body_parse(body)
+ parsed_body = self._parse_shape(
+ member_shape, raw_parse
+ )
+ final_parsed[name] = parsed_body
+ return
+ # If we didn't find an explicit payload, use the current shape
+ original_parsed = self._initial_body_parse(response['body'])
+ body_parsed = self._parse_shape(shape, original_parsed)
+ final_parsed.update(body_parsed)
+
+ def _parse_non_payload_attrs(
+ self, response, shape, member_shapes, final_parsed
+ ):
+ headers = response['headers']
+ for name in member_shapes:
+ member_shape = member_shapes[name]
+ if member_shape.serialization.get('eventheader'):
+ if name in headers:
+ value = headers[name]
+ if member_shape.type_name == 'timestamp':
+ # Event stream timestamps are an in milleseconds so we
+ # divide by 1000 to convert to seconds.
+ value = self._timestamp_parser(value / 1000.0)
+ final_parsed[name] = value
+
+ def _initial_body_parse(self, body_contents):
+ # This method should do the initial xml/json parsing of the
+ # body. We we still need to walk the parsed body in order
+ # to convert types, but this method will do the first round
+ # of parsing.
+ raise NotImplementedError("_initial_body_parse")
+
+
+class EventStreamJSONParser(BaseEventStreamParser, BaseJSONParser):
+ def _initial_body_parse(self, body_contents):
+ return self._parse_body_as_json(body_contents)
+
+
+class EventStreamXMLParser(BaseEventStreamParser, BaseXMLResponseParser):
+ def _initial_body_parse(self, xml_string):
+ if not xml_string:
+ return ETree.Element('')
+ return self._parse_xml_string_to_dom(xml_string)
+
+
+class JSONParser(BaseJSONParser):
+ EVENT_STREAM_PARSER_CLS = EventStreamJSONParser
+
+ """Response parser for the "json" protocol."""
+
+ def _do_parse(self, response, shape):
+ parsed = {}
+ if shape is not None:
+ event_name = shape.event_stream_name
+ if event_name:
+ parsed = self._handle_event_stream(response, shape, event_name)
+ else:
+ parsed = self._handle_json_body(response['body'], shape)
+ self._inject_response_metadata(parsed, response['headers'])
+ return parsed
+
+ def _do_modeled_error_parse(self, response, shape):
+ return self._handle_json_body(response['body'], shape)
+
+ def _handle_event_stream(self, response, shape, event_name):
+ event_stream_shape = shape.members[event_name]
+ event_stream = self._create_event_stream(response, event_stream_shape)
+ try:
+ event = event_stream.get_initial_response()
+ except NoInitialResponseError:
+ error_msg = 'First event was not of type initial-response'
+ raise ResponseParserError(error_msg)
+ parsed = self._handle_json_body(event.payload, shape)
+ parsed[event_name] = event_stream
+ return parsed
+
+ def _handle_json_body(self, raw_body, shape):
+ # The json.loads() gives us the primitive JSON types,
+ # but we need to traverse the parsed JSON data to convert
+ # to richer types (blobs, timestamps, etc.
+ parsed_json = self._parse_body_as_json(raw_body)
+ return self._parse_shape(shape, parsed_json)
+
+
+class BaseRestParser(ResponseParser):
+ def _do_parse(self, response, shape):
+ final_parsed = {}
+ final_parsed['ResponseMetadata'] = self._populate_response_metadata(
+ response
+ )
+ self._add_modeled_parse(response, shape, final_parsed)
+ return final_parsed
+
+ def _add_modeled_parse(self, response, shape, final_parsed):
+ if shape is None:
+ return final_parsed
+ member_shapes = shape.members
+ self._parse_non_payload_attrs(
+ response, shape, member_shapes, final_parsed
+ )
+ self._parse_payload(response, shape, member_shapes, final_parsed)
+
+ def _do_modeled_error_parse(self, response, shape):
+ final_parsed = {}
+ self._add_modeled_parse(response, shape, final_parsed)
+ return final_parsed
+
+ def _populate_response_metadata(self, response):
+ metadata = {}
+ headers = response['headers']
+ if 'x-amzn-requestid' in headers:
+ metadata['RequestId'] = headers['x-amzn-requestid']
+ elif 'x-amz-request-id' in headers:
+ metadata['RequestId'] = headers['x-amz-request-id']
+ # HostId is what it's called whenever this value is returned
+ # in an XML response body, so to be consistent, we'll always
+ # call is HostId.
+ metadata['HostId'] = headers.get('x-amz-id-2', '')
+ return metadata
+
+ def _parse_payload(self, response, shape, member_shapes, final_parsed):
+ if 'payload' in shape.serialization:
+ # If a payload is specified in the output shape, then only that
+ # shape is used for the body payload.
+ payload_member_name = shape.serialization['payload']
+ body_shape = member_shapes[payload_member_name]
+ if body_shape.serialization.get('eventstream'):
+ body = self._create_event_stream(response, body_shape)
+ final_parsed[payload_member_name] = body
+ elif body_shape.type_name in ['string', 'blob']:
+ # This is a stream
+ body = response['body']
+ if isinstance(body, bytes):
+ body = body.decode(self.DEFAULT_ENCODING)
+ final_parsed[payload_member_name] = body
+ else:
+ original_parsed = self._initial_body_parse(response['body'])
+ final_parsed[payload_member_name] = self._parse_shape(
+ body_shape, original_parsed
+ )
+ else:
+ original_parsed = self._initial_body_parse(response['body'])
+ body_parsed = self._parse_shape(shape, original_parsed)
+ final_parsed.update(body_parsed)
+
+ def _parse_non_payload_attrs(
+ self, response, shape, member_shapes, final_parsed
+ ):
+ headers = response['headers']
+ for name in member_shapes:
+ member_shape = member_shapes[name]
+ location = member_shape.serialization.get('location')
+ if location is None:
+ continue
+ elif location == 'statusCode':
+ final_parsed[name] = self._parse_shape(
+ member_shape, response['status_code']
+ )
+ elif location == 'headers':
+ final_parsed[name] = self._parse_header_map(
+ member_shape, headers
+ )
+ elif location == 'header':
+ header_name = member_shape.serialization.get('name', name)
+ if header_name in headers:
+ final_parsed[name] = self._parse_shape(
+ member_shape, headers[header_name]
+ )
+
+ def _parse_header_map(self, shape, headers):
+ # Note that headers are case insensitive, so we .lower()
+ # all header names and header prefixes.
+ parsed = {}
+ prefix = shape.serialization.get('name', '').lower()
+ for header_name in headers:
+ if header_name.lower().startswith(prefix):
+ # The key name inserted into the parsed hash
+ # strips off the prefix.
+ name = header_name[len(prefix) :]
+ parsed[name] = headers[header_name]
+ return parsed
+
+ def _initial_body_parse(self, body_contents):
+ # This method should do the initial xml/json parsing of the
+ # body. We we still need to walk the parsed body in order
+ # to convert types, but this method will do the first round
+ # of parsing.
+ raise NotImplementedError("_initial_body_parse")
+
+ def _handle_string(self, shape, value):
+ parsed = value
+ if is_json_value_header(shape):
+ decoded = base64.b64decode(value).decode(self.DEFAULT_ENCODING)
+ parsed = json.loads(decoded)
+ return parsed
+
+ def _handle_list(self, shape, node):
+ location = shape.serialization.get('location')
+ if location == 'header' and not isinstance(node, list):
+ # List in headers may be a comma separated string as per RFC7230
+ node = [e.strip() for e in node.split(',')]
+ return super()._handle_list(shape, node)
+
+
+class RestJSONParser(BaseRestParser, BaseJSONParser):
+ EVENT_STREAM_PARSER_CLS = EventStreamJSONParser
+
+ def _initial_body_parse(self, body_contents):
+ return self._parse_body_as_json(body_contents)
+
+ def _do_error_parse(self, response, shape):
+ error = super()._do_error_parse(response, shape)
+ self._inject_error_code(error, response)
+ return error
+
+ def _inject_error_code(self, error, response):
+ # The "Code" value can come from either a response
+ # header or a value in the JSON body.
+ body = self._initial_body_parse(response['body'])
+ if 'x-amzn-errortype' in response['headers']:
+ code = response['headers']['x-amzn-errortype']
+ # Could be:
+ # x-amzn-errortype: ValidationException:
+ code = code.split(':')[0]
+ error['Error']['Code'] = code
+ elif 'code' in body or 'Code' in body:
+ error['Error']['Code'] = body.get('code', body.get('Code', ''))
+
+ def _handle_integer(self, shape, value):
+ return int(value)
+
+ _handle_long = _handle_integer
+
+
+class RestXMLParser(BaseRestParser, BaseXMLResponseParser):
+ EVENT_STREAM_PARSER_CLS = EventStreamXMLParser
+
+ def _initial_body_parse(self, xml_string):
+ if not xml_string:
+ return ETree.Element('')
+ return self._parse_xml_string_to_dom(xml_string)
+
+ def _do_error_parse(self, response, shape):
+ # We're trying to be service agnostic here, but S3 does have a slightly
+ # different response structure for its errors compared to other
+ # rest-xml serivces (route53/cloudfront). We handle this by just
+ # trying to parse both forms.
+ # First:
+ #
+ #
+ # Sender
+ # InvalidInput
+ # Invalid resource type: foo
+ #
+ # request-id
+ #
+ if response['body']:
+ # If the body ends up being invalid xml, the xml parser should not
+ # blow up. It should at least try to pull information about the
+ # the error response from other sources like the HTTP status code.
+ try:
+ return self._parse_error_from_body(response)
+ except ResponseParserError:
+ LOG.debug(
+ 'Exception caught when parsing error response body:',
+ exc_info=True,
+ )
+ return self._parse_error_from_http_status(response)
+
+ def _parse_error_from_http_status(self, response):
+ return {
+ 'Error': {
+ 'Code': str(response['status_code']),
+ 'Message': http.client.responses.get(
+ response['status_code'], ''
+ ),
+ },
+ 'ResponseMetadata': {
+ 'RequestId': response['headers'].get('x-amz-request-id', ''),
+ 'HostId': response['headers'].get('x-amz-id-2', ''),
+ },
+ }
+
+ def _parse_error_from_body(self, response):
+ xml_contents = response['body']
+ root = self._parse_xml_string_to_dom(xml_contents)
+ parsed = self._build_name_to_xml_node(root)
+ self._replace_nodes(parsed)
+ if root.tag == 'Error':
+ # This is an S3 error response. First we'll populate the
+ # response metadata.
+ metadata = self._populate_response_metadata(response)
+ # The RequestId and the HostId are already in the
+ # ResponseMetadata, but are also duplicated in the XML
+ # body. We don't need these values in both places,
+ # we'll just remove them from the parsed XML body.
+ parsed.pop('RequestId', '')
+ parsed.pop('HostId', '')
+ return {'Error': parsed, 'ResponseMetadata': metadata}
+ elif 'RequestId' in parsed:
+ # Other rest-xml services:
+ parsed['ResponseMetadata'] = {'RequestId': parsed.pop('RequestId')}
+ default = {'Error': {'Message': '', 'Code': ''}}
+ merge_dicts(default, parsed)
+ return default
+
+ @_text_content
+ def _handle_string(self, shape, text):
+ text = super()._handle_string(shape, text)
+ return text
+
+
+PROTOCOL_PARSERS = {
+ 'ec2': EC2QueryParser,
+ 'query': QueryParser,
+ 'json': JSONParser,
+ 'rest-json': RestJSONParser,
+ 'rest-xml': RestXMLParser,
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/regions.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/regions.py
new file mode 100644
index 0000000000..0fe8f0ee0e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/regions.py
@@ -0,0 +1,830 @@
+# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""Resolves regions and endpoints.
+
+This module implements endpoint resolution, including resolving endpoints for a
+given service and region and resolving the available endpoints for a service
+in a specific AWS partition.
+"""
+import copy
+import logging
+import re
+from enum import Enum
+
+from botocore import UNSIGNED, xform_name
+from botocore.auth import AUTH_TYPE_MAPS, HAS_CRT
+from botocore.crt import CRT_SUPPORTED_AUTH_TYPES
+from botocore.endpoint_provider import EndpointProvider
+from botocore.exceptions import (
+ EndpointProviderError,
+ EndpointVariantError,
+ InvalidEndpointConfigurationError,
+ InvalidHostLabelError,
+ MissingDependencyException,
+ NoRegionError,
+ ParamValidationError,
+ UnknownEndpointResolutionBuiltInName,
+ UnknownRegionError,
+ UnknownSignatureVersionError,
+ UnsupportedS3AccesspointConfigurationError,
+ UnsupportedS3ConfigurationError,
+ UnsupportedS3ControlArnError,
+ UnsupportedS3ControlConfigurationError,
+)
+from botocore.utils import ensure_boolean, instance_cache
+
+LOG = logging.getLogger(__name__)
+DEFAULT_URI_TEMPLATE = '{service}.{region}.{dnsSuffix}' # noqa
+DEFAULT_SERVICE_DATA = {'endpoints': {}}
+
+
+class BaseEndpointResolver:
+ """Resolves regions and endpoints. Must be subclassed."""
+
+ def construct_endpoint(self, service_name, region_name=None):
+ """Resolves an endpoint for a service and region combination.
+
+ :type service_name: string
+ :param service_name: Name of the service to resolve an endpoint for
+ (e.g., s3)
+
+ :type region_name: string
+ :param region_name: Region/endpoint name to resolve (e.g., us-east-1)
+ if no region is provided, the first found partition-wide endpoint
+ will be used if available.
+
+ :rtype: dict
+ :return: Returns a dict containing the following keys:
+ - partition: (string, required) Resolved partition name
+ - endpointName: (string, required) Resolved endpoint name
+ - hostname: (string, required) Hostname to use for this endpoint
+ - sslCommonName: (string) sslCommonName to use for this endpoint.
+ - credentialScope: (dict) Signature version 4 credential scope
+ - region: (string) region name override when signing.
+ - service: (string) service name override when signing.
+ - signatureVersions: (list) A list of possible signature
+ versions, including s3, v4, v2, and s3v4
+ - protocols: (list) A list of supported protocols
+ (e.g., http, https)
+ - ...: Other keys may be included as well based on the metadata
+ """
+ raise NotImplementedError
+
+ def get_available_partitions(self):
+ """Lists the partitions available to the endpoint resolver.
+
+ :return: Returns a list of partition names (e.g., ["aws", "aws-cn"]).
+ """
+ raise NotImplementedError
+
+ def get_available_endpoints(
+ self, service_name, partition_name='aws', allow_non_regional=False
+ ):
+ """Lists the endpoint names of a particular partition.
+
+ :type service_name: string
+ :param service_name: Name of a service to list endpoint for (e.g., s3)
+
+ :type partition_name: string
+ :param partition_name: Name of the partition to limit endpoints to.
+ (e.g., aws for the public AWS endpoints, aws-cn for AWS China
+ endpoints, aws-us-gov for AWS GovCloud (US) Endpoints, etc.
+
+ :type allow_non_regional: bool
+ :param allow_non_regional: Set to True to include endpoints that are
+ not regional endpoints (e.g., s3-external-1,
+ fips-us-gov-west-1, etc).
+ :return: Returns a list of endpoint names (e.g., ["us-east-1"]).
+ """
+ raise NotImplementedError
+
+
+class EndpointResolver(BaseEndpointResolver):
+ """Resolves endpoints based on partition endpoint metadata"""
+
+ _UNSUPPORTED_DUALSTACK_PARTITIONS = ['aws-iso', 'aws-iso-b']
+
+ def __init__(self, endpoint_data, uses_builtin_data=False):
+ """
+ :type endpoint_data: dict
+ :param endpoint_data: A dict of partition data.
+
+ :type uses_builtin_data: boolean
+ :param uses_builtin_data: Whether the endpoint data originates in the
+ package's data directory.
+ """
+ if 'partitions' not in endpoint_data:
+ raise ValueError('Missing "partitions" in endpoint data')
+ self._endpoint_data = endpoint_data
+ self.uses_builtin_data = uses_builtin_data
+
+ def get_service_endpoints_data(self, service_name, partition_name='aws'):
+ for partition in self._endpoint_data['partitions']:
+ if partition['partition'] != partition_name:
+ continue
+ services = partition['services']
+ if service_name not in services:
+ continue
+ return services[service_name]['endpoints']
+
+ def get_available_partitions(self):
+ result = []
+ for partition in self._endpoint_data['partitions']:
+ result.append(partition['partition'])
+ return result
+
+ def get_available_endpoints(
+ self,
+ service_name,
+ partition_name='aws',
+ allow_non_regional=False,
+ endpoint_variant_tags=None,
+ ):
+ result = []
+ for partition in self._endpoint_data['partitions']:
+ if partition['partition'] != partition_name:
+ continue
+ services = partition['services']
+ if service_name not in services:
+ continue
+ service_endpoints = services[service_name]['endpoints']
+ for endpoint_name in service_endpoints:
+ is_regional_endpoint = endpoint_name in partition['regions']
+ # Only regional endpoints can be modeled with variants
+ if endpoint_variant_tags and is_regional_endpoint:
+ variant_data = self._retrieve_variant_data(
+ service_endpoints[endpoint_name], endpoint_variant_tags
+ )
+ if variant_data:
+ result.append(endpoint_name)
+ elif allow_non_regional or is_regional_endpoint:
+ result.append(endpoint_name)
+ return result
+
+ def get_partition_dns_suffix(
+ self, partition_name, endpoint_variant_tags=None
+ ):
+ for partition in self._endpoint_data['partitions']:
+ if partition['partition'] == partition_name:
+ if endpoint_variant_tags:
+ variant = self._retrieve_variant_data(
+ partition.get('defaults'), endpoint_variant_tags
+ )
+ if variant and 'dnsSuffix' in variant:
+ return variant['dnsSuffix']
+ else:
+ return partition['dnsSuffix']
+ return None
+
+ def construct_endpoint(
+ self,
+ service_name,
+ region_name=None,
+ partition_name=None,
+ use_dualstack_endpoint=False,
+ use_fips_endpoint=False,
+ ):
+ if (
+ service_name == 's3'
+ and use_dualstack_endpoint
+ and region_name is None
+ ):
+ region_name = 'us-east-1'
+
+ if partition_name is not None:
+ valid_partition = None
+ for partition in self._endpoint_data['partitions']:
+ if partition['partition'] == partition_name:
+ valid_partition = partition
+
+ if valid_partition is not None:
+ result = self._endpoint_for_partition(
+ valid_partition,
+ service_name,
+ region_name,
+ use_dualstack_endpoint,
+ use_fips_endpoint,
+ True,
+ )
+ return result
+ return None
+
+ # Iterate over each partition until a match is found.
+ for partition in self._endpoint_data['partitions']:
+ if use_dualstack_endpoint and (
+ partition['partition']
+ in self._UNSUPPORTED_DUALSTACK_PARTITIONS
+ ):
+ continue
+ result = self._endpoint_for_partition(
+ partition,
+ service_name,
+ region_name,
+ use_dualstack_endpoint,
+ use_fips_endpoint,
+ )
+ if result:
+ return result
+
+ def get_partition_for_region(self, region_name):
+ for partition in self._endpoint_data['partitions']:
+ if self._region_match(partition, region_name):
+ return partition['partition']
+ raise UnknownRegionError(
+ region_name=region_name,
+ error_msg='No partition found for provided region_name.',
+ )
+
+ def _endpoint_for_partition(
+ self,
+ partition,
+ service_name,
+ region_name,
+ use_dualstack_endpoint,
+ use_fips_endpoint,
+ force_partition=False,
+ ):
+ partition_name = partition["partition"]
+ if (
+ use_dualstack_endpoint
+ and partition_name in self._UNSUPPORTED_DUALSTACK_PARTITIONS
+ ):
+ error_msg = (
+ "Dualstack endpoints are currently not supported"
+ " for %s partition" % partition_name
+ )
+ raise EndpointVariantError(tags=['dualstack'], error_msg=error_msg)
+
+ # Get the service from the partition, or an empty template.
+ service_data = partition['services'].get(
+ service_name, DEFAULT_SERVICE_DATA
+ )
+ # Use the partition endpoint if no region is supplied.
+ if region_name is None:
+ if 'partitionEndpoint' in service_data:
+ region_name = service_data['partitionEndpoint']
+ else:
+ raise NoRegionError()
+
+ resolve_kwargs = {
+ 'partition': partition,
+ 'service_name': service_name,
+ 'service_data': service_data,
+ 'endpoint_name': region_name,
+ 'use_dualstack_endpoint': use_dualstack_endpoint,
+ 'use_fips_endpoint': use_fips_endpoint,
+ }
+
+ # Attempt to resolve the exact region for this partition.
+ if region_name in service_data['endpoints']:
+ return self._resolve(**resolve_kwargs)
+
+ # Check to see if the endpoint provided is valid for the partition.
+ if self._region_match(partition, region_name) or force_partition:
+ # Use the partition endpoint if set and not regionalized.
+ partition_endpoint = service_data.get('partitionEndpoint')
+ is_regionalized = service_data.get('isRegionalized', True)
+ if partition_endpoint and not is_regionalized:
+ LOG.debug(
+ 'Using partition endpoint for %s, %s: %s',
+ service_name,
+ region_name,
+ partition_endpoint,
+ )
+ resolve_kwargs['endpoint_name'] = partition_endpoint
+ return self._resolve(**resolve_kwargs)
+ LOG.debug(
+ 'Creating a regex based endpoint for %s, %s',
+ service_name,
+ region_name,
+ )
+ return self._resolve(**resolve_kwargs)
+
+ def _region_match(self, partition, region_name):
+ if region_name in partition['regions']:
+ return True
+ if 'regionRegex' in partition:
+ return re.compile(partition['regionRegex']).match(region_name)
+ return False
+
+ def _retrieve_variant_data(self, endpoint_data, tags):
+ variants = endpoint_data.get('variants', [])
+ for variant in variants:
+ if set(variant['tags']) == set(tags):
+ result = variant.copy()
+ return result
+
+ def _create_tag_list(self, use_dualstack_endpoint, use_fips_endpoint):
+ tags = []
+ if use_dualstack_endpoint:
+ tags.append('dualstack')
+ if use_fips_endpoint:
+ tags.append('fips')
+ return tags
+
+ def _resolve_variant(
+ self, tags, endpoint_data, service_defaults, partition_defaults
+ ):
+ result = {}
+ for variants in [endpoint_data, service_defaults, partition_defaults]:
+ variant = self._retrieve_variant_data(variants, tags)
+ if variant:
+ self._merge_keys(variant, result)
+ return result
+
+ def _resolve(
+ self,
+ partition,
+ service_name,
+ service_data,
+ endpoint_name,
+ use_dualstack_endpoint,
+ use_fips_endpoint,
+ ):
+ endpoint_data = service_data.get('endpoints', {}).get(
+ endpoint_name, {}
+ )
+
+ if endpoint_data.get('deprecated'):
+ LOG.warning(
+ 'Client is configured with the deprecated endpoint: %s'
+ % (endpoint_name)
+ )
+
+ service_defaults = service_data.get('defaults', {})
+ partition_defaults = partition.get('defaults', {})
+ tags = self._create_tag_list(use_dualstack_endpoint, use_fips_endpoint)
+
+ if tags:
+ result = self._resolve_variant(
+ tags, endpoint_data, service_defaults, partition_defaults
+ )
+ if result == {}:
+ error_msg = (
+ f"Endpoint does not exist for {service_name} "
+ f"in region {endpoint_name}"
+ )
+ raise EndpointVariantError(tags=tags, error_msg=error_msg)
+ self._merge_keys(endpoint_data, result)
+ else:
+ result = endpoint_data
+
+ # If dnsSuffix has not already been consumed from a variant definition
+ if 'dnsSuffix' not in result:
+ result['dnsSuffix'] = partition['dnsSuffix']
+
+ result['partition'] = partition['partition']
+ result['endpointName'] = endpoint_name
+
+ # Merge in the service defaults then the partition defaults.
+ self._merge_keys(service_defaults, result)
+ self._merge_keys(partition_defaults, result)
+
+ result['hostname'] = self._expand_template(
+ partition,
+ result['hostname'],
+ service_name,
+ endpoint_name,
+ result['dnsSuffix'],
+ )
+ if 'sslCommonName' in result:
+ result['sslCommonName'] = self._expand_template(
+ partition,
+ result['sslCommonName'],
+ service_name,
+ endpoint_name,
+ result['dnsSuffix'],
+ )
+
+ return result
+
+ def _merge_keys(self, from_data, result):
+ for key in from_data:
+ if key not in result:
+ result[key] = from_data[key]
+
+ def _expand_template(
+ self, partition, template, service_name, endpoint_name, dnsSuffix
+ ):
+ return template.format(
+ service=service_name, region=endpoint_name, dnsSuffix=dnsSuffix
+ )
+
+
+class EndpointResolverBuiltins(str, Enum):
+ # The AWS Region configured for the SDK client (str)
+ AWS_REGION = "AWS::Region"
+ # Whether the UseFIPSEndpoint configuration option has been enabled for
+ # the SDK client (bool)
+ AWS_USE_FIPS = "AWS::UseFIPS"
+ # Whether the UseDualStackEndpoint configuration option has been enabled
+ # for the SDK client (bool)
+ AWS_USE_DUALSTACK = "AWS::UseDualStack"
+ # Whether the global endpoint should be used with STS, rather the the
+ # regional endpoint for us-east-1 (bool)
+ AWS_STS_USE_GLOBAL_ENDPOINT = "AWS::STS::UseGlobalEndpoint"
+ # Whether the global endpoint should be used with S3, rather then the
+ # regional endpoint for us-east-1 (bool)
+ AWS_S3_USE_GLOBAL_ENDPOINT = "AWS::S3::UseGlobalEndpoint"
+ # Whether S3 Transfer Acceleration has been requested (bool)
+ AWS_S3_ACCELERATE = "AWS::S3::Accelerate"
+ # Whether S3 Force Path Style has been enabled (bool)
+ AWS_S3_FORCE_PATH_STYLE = "AWS::S3::ForcePathStyle"
+ # Whether to use the ARN region or raise an error when ARN and client
+ # region differ (for s3 service only, bool)
+ AWS_S3_USE_ARN_REGION = "AWS::S3::UseArnRegion"
+ # Whether to use the ARN region or raise an error when ARN and client
+ # region differ (for s3-control service only, bool)
+ AWS_S3CONTROL_USE_ARN_REGION = 'AWS::S3Control::UseArnRegion'
+ # Whether multi-region access points (MRAP) should be disabled (bool)
+ AWS_S3_DISABLE_MRAP = "AWS::S3::DisableMultiRegionAccessPoints"
+ # Whether a custom endpoint has been configured (str)
+ SDK_ENDPOINT = "SDK::Endpoint"
+
+
+class EndpointRulesetResolver:
+ """Resolves endpoints using a service's endpoint ruleset"""
+
+ def __init__(
+ self,
+ endpoint_ruleset_data,
+ partition_data,
+ service_model,
+ builtins,
+ client_context,
+ event_emitter,
+ use_ssl=True,
+ requested_auth_scheme=None,
+ ):
+ self._provider = EndpointProvider(
+ ruleset_data=endpoint_ruleset_data,
+ partition_data=partition_data,
+ )
+ self._param_definitions = self._provider.ruleset.parameters
+ self._service_model = service_model
+ self._builtins = builtins
+ self._client_context = client_context
+ self._event_emitter = event_emitter
+ self._use_ssl = use_ssl
+ self._requested_auth_scheme = requested_auth_scheme
+ self._instance_cache = {}
+
+ def construct_endpoint(
+ self,
+ operation_model,
+ call_args,
+ request_context,
+ ):
+ """Invokes the provider with params defined in the service's ruleset"""
+ if call_args is None:
+ call_args = {}
+
+ if request_context is None:
+ request_context = {}
+
+ provider_params = self._get_provider_params(
+ operation_model, call_args, request_context
+ )
+ LOG.debug(
+ 'Calling endpoint provider with parameters: %s' % provider_params
+ )
+ try:
+ provider_result = self._provider.resolve_endpoint(
+ **provider_params
+ )
+ except EndpointProviderError as ex:
+ botocore_exception = self.ruleset_error_to_botocore_exception(
+ ex, provider_params
+ )
+ if botocore_exception is None:
+ raise
+ else:
+ raise botocore_exception from ex
+ LOG.debug('Endpoint provider result: %s' % provider_result.url)
+
+ # The endpoint provider does not support non-secure transport.
+ if not self._use_ssl and provider_result.url.startswith('https://'):
+ provider_result = provider_result._replace(
+ url=f'http://{provider_result.url[8:]}'
+ )
+
+ # Multi-valued headers are not supported in botocore. Replace the list
+ # of values returned for each header with just its first entry,
+ # dropping any additionally entries.
+ provider_result = provider_result._replace(
+ headers={
+ key: val[0] for key, val in provider_result.headers.items()
+ }
+ )
+
+ return provider_result
+
+ def _get_provider_params(
+ self, operation_model, call_args, request_context
+ ):
+ """Resolve a value for each parameter defined in the service's ruleset
+
+ The resolution order for parameter values is:
+ 1. Operation-specific static context values from the service definition
+ 2. Operation-specific dynamic context values from API parameters
+ 3. Client-specific context parameters
+ 4. Built-in values such as region, FIPS usage, ...
+ """
+ provider_params = {}
+ # Builtin values can be customized for each operation by hooks
+ # subscribing to the ``before-endpoint-resolution.*`` event.
+ customized_builtins = self._get_customized_builtins(
+ operation_model, call_args, request_context
+ )
+ for param_name, param_def in self._param_definitions.items():
+ param_val = self._resolve_param_from_context(
+ param_name=param_name,
+ operation_model=operation_model,
+ call_args=call_args,
+ )
+ if param_val is None and param_def.builtin is not None:
+ param_val = self._resolve_param_as_builtin(
+ builtin_name=param_def.builtin,
+ builtins=customized_builtins,
+ )
+ if param_val is not None:
+ provider_params[param_name] = param_val
+
+ return provider_params
+
+ def _resolve_param_from_context(
+ self, param_name, operation_model, call_args
+ ):
+ static = self._resolve_param_as_static_context_param(
+ param_name, operation_model
+ )
+ if static is not None:
+ return static
+ dynamic = self._resolve_param_as_dynamic_context_param(
+ param_name, operation_model, call_args
+ )
+ if dynamic is not None:
+ return dynamic
+ return self._resolve_param_as_client_context_param(param_name)
+
+ def _resolve_param_as_static_context_param(
+ self, param_name, operation_model
+ ):
+ static_ctx_params = self._get_static_context_params(operation_model)
+ return static_ctx_params.get(param_name)
+
+ def _resolve_param_as_dynamic_context_param(
+ self, param_name, operation_model, call_args
+ ):
+ dynamic_ctx_params = self._get_dynamic_context_params(operation_model)
+ if param_name in dynamic_ctx_params:
+ member_name = dynamic_ctx_params[param_name]
+ return call_args.get(member_name)
+
+ def _resolve_param_as_client_context_param(self, param_name):
+ client_ctx_params = self._get_client_context_params()
+ if param_name in client_ctx_params:
+ client_ctx_varname = client_ctx_params[param_name]
+ return self._client_context.get(client_ctx_varname)
+
+ def _resolve_param_as_builtin(self, builtin_name, builtins):
+ if builtin_name not in EndpointResolverBuiltins.__members__.values():
+ raise UnknownEndpointResolutionBuiltInName(name=builtin_name)
+ return builtins.get(builtin_name)
+
+ @instance_cache
+ def _get_static_context_params(self, operation_model):
+ """Mapping of param names to static param value for an operation"""
+ return {
+ param.name: param.value
+ for param in operation_model.static_context_parameters
+ }
+
+ @instance_cache
+ def _get_dynamic_context_params(self, operation_model):
+ """Mapping of param names to member names for an operation"""
+ return {
+ param.name: param.member_name
+ for param in operation_model.context_parameters
+ }
+
+ @instance_cache
+ def _get_client_context_params(self):
+ """Mapping of param names to client configuration variable"""
+ return {
+ param.name: xform_name(param.name)
+ for param in self._service_model.client_context_parameters
+ }
+
+ def _get_customized_builtins(
+ self, operation_model, call_args, request_context
+ ):
+ service_id = self._service_model.service_id.hyphenize()
+ customized_builtins = copy.copy(self._builtins)
+ # Handlers are expected to modify the builtins dict in place.
+ self._event_emitter.emit(
+ 'before-endpoint-resolution.%s' % service_id,
+ builtins=customized_builtins,
+ model=operation_model,
+ params=call_args,
+ context=request_context,
+ )
+ return customized_builtins
+
+ def auth_schemes_to_signing_ctx(self, auth_schemes):
+ """Convert an Endpoint's authSchemes property to a signing_context dict
+
+ :type auth_schemes: list
+ :param auth_schemes: A list of dictionaries taken from the
+ ``authSchemes`` property of an Endpoint object returned by
+ ``EndpointProvider``.
+
+ :rtype: str, dict
+ :return: Tuple of auth type string (to be used in
+ ``request_context['auth_type']``) and signing context dict (for use
+ in ``request_context['signing']``).
+ """
+ if not isinstance(auth_schemes, list) or len(auth_schemes) == 0:
+ raise TypeError("auth_schemes must be a non-empty list.")
+
+ LOG.debug(
+ 'Selecting from endpoint provider\'s list of auth schemes: %s. '
+ 'User selected auth scheme is: "%s"',
+ ', '.join([f'"{s.get("name")}"' for s in auth_schemes]),
+ self._requested_auth_scheme,
+ )
+
+ if self._requested_auth_scheme == UNSIGNED:
+ return 'none', {}
+
+ auth_schemes = [
+ {**scheme, 'name': self._strip_sig_prefix(scheme['name'])}
+ for scheme in auth_schemes
+ ]
+ if self._requested_auth_scheme is not None:
+ try:
+ # Use the first scheme that matches the requested scheme,
+ # after accounting for naming differences between botocore and
+ # endpoint rulesets. Keep the requested name.
+ name, scheme = next(
+ (self._requested_auth_scheme, s)
+ for s in auth_schemes
+ if self._does_botocore_authname_match_ruleset_authname(
+ self._requested_auth_scheme, s['name']
+ )
+ )
+ except StopIteration:
+ # For legacy signers, no match will be found. Do not raise an
+ # exception, instead default to the logic in botocore
+ # customizations.
+ return None, {}
+ else:
+ try:
+ name, scheme = next(
+ (s['name'], s)
+ for s in auth_schemes
+ if s['name'] in AUTH_TYPE_MAPS
+ )
+ except StopIteration:
+ # If no auth scheme was specifically requested and an
+ # authSchemes list is present in the Endpoint object but none
+ # of the entries are supported, raise an exception.
+ fixable_with_crt = False
+ auth_type_options = [s['name'] for s in auth_schemes]
+ if not HAS_CRT:
+ fixable_with_crt = any(
+ scheme in CRT_SUPPORTED_AUTH_TYPES
+ for scheme in auth_type_options
+ )
+
+ if fixable_with_crt:
+ raise MissingDependencyException(
+ msg='This operation requires an additional dependency.'
+ ' Use pip install botocore[crt] before proceeding.'
+ )
+ else:
+ raise UnknownSignatureVersionError(
+ signature_version=', '.join(auth_type_options)
+ )
+
+ signing_context = {}
+ if 'signingRegion' in scheme:
+ signing_context['region'] = scheme['signingRegion']
+ elif 'signingRegionSet' in scheme:
+ if len(scheme['signingRegionSet']) > 0:
+ signing_context['region'] = scheme['signingRegionSet'][0]
+ if 'signingName' in scheme:
+ signing_context.update(signing_name=scheme['signingName'])
+ if 'disableDoubleEncoding' in scheme:
+ signing_context['disableDoubleEncoding'] = ensure_boolean(
+ scheme['disableDoubleEncoding']
+ )
+
+ LOG.debug(
+ 'Selected auth type "%s" as "%s" with signing context params: %s',
+ scheme['name'], # original name without "sig"
+ name, # chosen name can differ when `signature_version` is set
+ signing_context,
+ )
+ return name, signing_context
+
+ def _strip_sig_prefix(self, auth_name):
+ """Normalize auth type names by removing any "sig" prefix"""
+ return auth_name[3:] if auth_name.startswith('sig') else auth_name
+
+ def _does_botocore_authname_match_ruleset_authname(self, botoname, rsname):
+ """
+ Whether a valid string provided as signature_version parameter for
+ client construction refers to the same auth methods as a string
+ returned by the endpoint ruleset provider. This accounts for:
+
+ * The ruleset prefixes auth names with "sig"
+ * The s3 and s3control rulesets don't distinguish between v4[a] and
+ s3v4[a] signers
+ * The v2, v3, and HMAC v1 based signers (s3, s3-*) are botocore legacy
+ features and do not exist in the rulesets
+ * Only characters up to the first dash are considered
+
+ Example matches:
+ * v4, sigv4
+ * v4, v4
+ * s3v4, sigv4
+ * s3v7, sigv7 (hypothetical example)
+ * s3v4a, sigv4a
+ * s3v4-query, sigv4
+
+ Example mismatches:
+ * v4a, sigv4
+ * s3, sigv4
+ * s3-presign-post, sigv4
+ """
+ rsname = self._strip_sig_prefix(rsname)
+ botoname = botoname.split('-')[0]
+ if botoname != 's3' and botoname.startswith('s3'):
+ botoname = botoname[2:]
+ return rsname == botoname
+
+ def ruleset_error_to_botocore_exception(self, ruleset_exception, params):
+ """Attempts to translate ruleset errors to pre-existing botocore
+ exception types by string matching exception strings.
+ """
+ msg = ruleset_exception.kwargs.get('msg')
+ if msg is None:
+ return
+
+ if msg.startswith('Invalid region in ARN: '):
+ # Example message:
+ # "Invalid region in ARN: `us-we$t-2` (invalid DNS name)"
+ try:
+ label = msg.split('`')[1]
+ except IndexError:
+ label = msg
+ return InvalidHostLabelError(label=label)
+
+ service_name = self._service_model.service_name
+ if service_name == 's3':
+ if (
+ msg == 'S3 Object Lambda does not support S3 Accelerate'
+ or msg == 'Accelerate cannot be used with FIPS'
+ ):
+ return UnsupportedS3ConfigurationError(msg=msg)
+ if (
+ msg.startswith('S3 Outposts does not support')
+ or msg.startswith('S3 MRAP does not support')
+ or msg.startswith('S3 Object Lambda does not support')
+ or msg.startswith('Access Points do not support')
+ or msg.startswith('Invalid configuration:')
+ or msg.startswith('Client was configured for partition')
+ ):
+ return UnsupportedS3AccesspointConfigurationError(msg=msg)
+ if msg.lower().startswith('invalid arn:'):
+ return ParamValidationError(report=msg)
+ if service_name == 's3control':
+ if msg.startswith('Invalid ARN:'):
+ arn = params.get('Bucket')
+ return UnsupportedS3ControlArnError(arn=arn, msg=msg)
+ if msg.startswith('Invalid configuration:') or msg.startswith(
+ 'Client was configured for partition'
+ ):
+ return UnsupportedS3ControlConfigurationError(msg=msg)
+ if msg == "AccountId is required but not set":
+ return ParamValidationError(report=msg)
+ if service_name == 'events':
+ if msg.startswith(
+ 'Invalid Configuration: FIPS is not supported with '
+ 'EventBridge multi-region endpoints.'
+ ):
+ return InvalidEndpointConfigurationError(msg=msg)
+ if msg == 'EndpointId must be a valid host label.':
+ return InvalidEndpointConfigurationError(msg=msg)
+ return None
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/response.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/response.py
new file mode 100644
index 0000000000..ba3fac9bab
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/response.py
@@ -0,0 +1,201 @@
+# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+import logging
+from io import IOBase
+
+from urllib3.exceptions import ProtocolError as URLLib3ProtocolError
+from urllib3.exceptions import ReadTimeoutError as URLLib3ReadTimeoutError
+
+from botocore import parsers
+from botocore.compat import set_socket_timeout
+from botocore.exceptions import (
+ IncompleteReadError,
+ ReadTimeoutError,
+ ResponseStreamingError,
+)
+
+# Keep these imported. There's pre-existing code that uses them.
+from botocore import ScalarTypes # noqa
+from botocore.compat import XMLParseError # noqa
+from botocore.hooks import first_non_none_response # noqa
+
+
+logger = logging.getLogger(__name__)
+
+
+class StreamingBody(IOBase):
+ """Wrapper class for an http response body.
+
+ This provides a few additional conveniences that do not exist
+ in the urllib3 model:
+
+ * Set the timeout on the socket (i.e read() timeouts)
+ * Auto validation of content length, if the amount of bytes
+ we read does not match the content length, an exception
+ is raised.
+
+ """
+
+ _DEFAULT_CHUNK_SIZE = 1024
+
+ def __init__(self, raw_stream, content_length):
+ self._raw_stream = raw_stream
+ self._content_length = content_length
+ self._amount_read = 0
+
+ def __del__(self):
+ # Extending destructor in order to preserve the underlying raw_stream.
+ # The ability to add custom cleanup logic introduced in Python3.4+.
+ # https://www.python.org/dev/peps/pep-0442/
+ pass
+
+ def set_socket_timeout(self, timeout):
+ """Set the timeout seconds on the socket."""
+ # The problem we're trying to solve is to prevent .read() calls from
+ # hanging. This can happen in rare cases. What we'd like to ideally
+ # do is set a timeout on the .read() call so that callers can retry
+ # the request.
+ # Unfortunately, this isn't currently possible in requests.
+ # See: https://github.com/kennethreitz/requests/issues/1803
+ # So what we're going to do is reach into the guts of the stream and
+ # grab the socket object, which we can set the timeout on. We're
+ # putting in a check here so in case this interface goes away, we'll
+ # know.
+ try:
+ set_socket_timeout(self._raw_stream, timeout)
+ except AttributeError:
+ logger.error(
+ "Cannot access the socket object of "
+ "a streaming response. It's possible "
+ "the interface has changed.",
+ exc_info=True,
+ )
+ raise
+
+ def readable(self):
+ try:
+ return self._raw_stream.readable()
+ except AttributeError:
+ return False
+
+ def read(self, amt=None):
+ """Read at most amt bytes from the stream.
+
+ If the amt argument is omitted, read all data.
+ """
+ try:
+ chunk = self._raw_stream.read(amt)
+ except URLLib3ReadTimeoutError as e:
+ # TODO: the url will be None as urllib3 isn't setting it yet
+ raise ReadTimeoutError(endpoint_url=e.url, error=e)
+ except URLLib3ProtocolError as e:
+ raise ResponseStreamingError(error=e)
+ self._amount_read += len(chunk)
+ if amt is None or (not chunk and amt > 0):
+ # If the server sends empty contents or
+ # we ask to read all of the contents, then we know
+ # we need to verify the content length.
+ self._verify_content_length()
+ return chunk
+
+ def readlines(self):
+ return self._raw_stream.readlines()
+
+ def __iter__(self):
+ """Return an iterator to yield 1k chunks from the raw stream."""
+ return self.iter_chunks(self._DEFAULT_CHUNK_SIZE)
+
+ def __next__(self):
+ """Return the next 1k chunk from the raw stream."""
+ current_chunk = self.read(self._DEFAULT_CHUNK_SIZE)
+ if current_chunk:
+ return current_chunk
+ raise StopIteration()
+
+ def __enter__(self):
+ return self._raw_stream
+
+ def __exit__(self, type, value, traceback):
+ self._raw_stream.close()
+
+ next = __next__
+
+ def iter_lines(self, chunk_size=_DEFAULT_CHUNK_SIZE, keepends=False):
+ """Return an iterator to yield lines from the raw stream.
+
+ This is achieved by reading chunk of bytes (of size chunk_size) at a
+ time from the raw stream, and then yielding lines from there.
+ """
+ pending = b''
+ for chunk in self.iter_chunks(chunk_size):
+ lines = (pending + chunk).splitlines(True)
+ for line in lines[:-1]:
+ yield line.splitlines(keepends)[0]
+ pending = lines[-1]
+ if pending:
+ yield pending.splitlines(keepends)[0]
+
+ def iter_chunks(self, chunk_size=_DEFAULT_CHUNK_SIZE):
+ """Return an iterator to yield chunks of chunk_size bytes from the raw
+ stream.
+ """
+ while True:
+ current_chunk = self.read(chunk_size)
+ if current_chunk == b"":
+ break
+ yield current_chunk
+
+ def _verify_content_length(self):
+ # See: https://github.com/kennethreitz/requests/issues/1855
+ # Basically, our http library doesn't do this for us, so we have
+ # to do this ourself.
+ if self._content_length is not None and self._amount_read != int(
+ self._content_length
+ ):
+ raise IncompleteReadError(
+ actual_bytes=self._amount_read,
+ expected_bytes=int(self._content_length),
+ )
+
+ def tell(self):
+ return self._raw_stream.tell()
+
+ def close(self):
+ """Close the underlying http response stream."""
+ self._raw_stream.close()
+
+
+def get_response(operation_model, http_response):
+ protocol = operation_model.metadata['protocol']
+ response_dict = {
+ 'headers': http_response.headers,
+ 'status_code': http_response.status_code,
+ }
+ # TODO: Unfortunately, we have to have error logic here.
+ # If it looks like an error, in the streaming response case we
+ # need to actually grab the contents.
+ if response_dict['status_code'] >= 300:
+ response_dict['body'] = http_response.content
+ elif operation_model.has_streaming_output:
+ response_dict['body'] = StreamingBody(
+ http_response.raw, response_dict['headers'].get('content-length')
+ )
+ else:
+ response_dict['body'] = http_response.content
+
+ parser = parsers.create_parser(protocol)
+ return http_response, parser.parse(
+ response_dict, operation_model.output_shape
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__init__.py
new file mode 100644
index 0000000000..a6d6b377df
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__init__.py
@@ -0,0 +1,6 @@
+"""New retry v2 handlers.
+
+This package obsoletes the botocore/retryhandler.py module and contains
+new retry logic.
+
+"""
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..e060e7ea66
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/adaptive.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/adaptive.cpython-311.pyc
new file mode 100644
index 0000000000..4ce88fa917
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/adaptive.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/base.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/base.cpython-311.pyc
new file mode 100644
index 0000000000..b724074464
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/base.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/bucket.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/bucket.cpython-311.pyc
new file mode 100644
index 0000000000..3bc7f00bec
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/bucket.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/quota.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/quota.cpython-311.pyc
new file mode 100644
index 0000000000..adf306867f
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/quota.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/special.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/special.cpython-311.pyc
new file mode 100644
index 0000000000..6da9203c7b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/special.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/standard.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/standard.cpython-311.pyc
new file mode 100644
index 0000000000..5e441c59b9
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/standard.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/throttling.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/throttling.cpython-311.pyc
new file mode 100644
index 0000000000..b28c477d2d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/__pycache__/throttling.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/adaptive.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/adaptive.py
new file mode 100644
index 0000000000..5e638ddb7b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/adaptive.py
@@ -0,0 +1,132 @@
+import logging
+import math
+import threading
+
+from botocore.retries import bucket, standard, throttling
+
+logger = logging.getLogger(__name__)
+
+
+def register_retry_handler(client):
+ clock = bucket.Clock()
+ rate_adjustor = throttling.CubicCalculator(
+ starting_max_rate=0, start_time=clock.current_time()
+ )
+ token_bucket = bucket.TokenBucket(max_rate=1, clock=clock)
+ rate_clocker = RateClocker(clock)
+ throttling_detector = standard.ThrottlingErrorDetector(
+ retry_event_adapter=standard.RetryEventAdapter(),
+ )
+ limiter = ClientRateLimiter(
+ rate_adjustor=rate_adjustor,
+ rate_clocker=rate_clocker,
+ token_bucket=token_bucket,
+ throttling_detector=throttling_detector,
+ clock=clock,
+ )
+ client.meta.events.register(
+ 'before-send',
+ limiter.on_sending_request,
+ )
+ client.meta.events.register(
+ 'needs-retry',
+ limiter.on_receiving_response,
+ )
+ return limiter
+
+
+class ClientRateLimiter:
+ _MAX_RATE_ADJUST_SCALE = 2.0
+
+ def __init__(
+ self,
+ rate_adjustor,
+ rate_clocker,
+ token_bucket,
+ throttling_detector,
+ clock,
+ ):
+ self._rate_adjustor = rate_adjustor
+ self._rate_clocker = rate_clocker
+ self._token_bucket = token_bucket
+ self._throttling_detector = throttling_detector
+ self._clock = clock
+ self._enabled = False
+ self._lock = threading.Lock()
+
+ def on_sending_request(self, request, **kwargs):
+ if self._enabled:
+ self._token_bucket.acquire()
+
+ # Hooked up to needs-retry.
+ def on_receiving_response(self, **kwargs):
+ measured_rate = self._rate_clocker.record()
+ timestamp = self._clock.current_time()
+ with self._lock:
+ if not self._throttling_detector.is_throttling_error(**kwargs):
+ new_rate = self._rate_adjustor.success_received(timestamp)
+ else:
+ if not self._enabled:
+ rate_to_use = measured_rate
+ else:
+ rate_to_use = min(
+ measured_rate, self._token_bucket.max_rate
+ )
+ new_rate = self._rate_adjustor.error_received(
+ rate_to_use, timestamp
+ )
+ logger.debug(
+ "Throttling response received, new send rate: %s "
+ "measured rate: %s, token bucket capacity "
+ "available: %s",
+ new_rate,
+ measured_rate,
+ self._token_bucket.available_capacity,
+ )
+ self._enabled = True
+ self._token_bucket.max_rate = min(
+ new_rate, self._MAX_RATE_ADJUST_SCALE * measured_rate
+ )
+
+
+class RateClocker:
+ """Tracks the rate at which a client is sending a request."""
+
+ _DEFAULT_SMOOTHING = 0.8
+ # Update the rate every _TIME_BUCKET_RANGE seconds.
+ _TIME_BUCKET_RANGE = 0.5
+
+ def __init__(
+ self,
+ clock,
+ smoothing=_DEFAULT_SMOOTHING,
+ time_bucket_range=_TIME_BUCKET_RANGE,
+ ):
+ self._clock = clock
+ self._measured_rate = 0
+ self._smoothing = smoothing
+ self._last_bucket = math.floor(self._clock.current_time())
+ self._time_bucket_scale = 1 / self._TIME_BUCKET_RANGE
+ self._count = 0
+ self._lock = threading.Lock()
+
+ def record(self, amount=1):
+ with self._lock:
+ t = self._clock.current_time()
+ bucket = (
+ math.floor(t * self._time_bucket_scale)
+ / self._time_bucket_scale
+ )
+ self._count += amount
+ if bucket > self._last_bucket:
+ current_rate = self._count / float(bucket - self._last_bucket)
+ self._measured_rate = (current_rate * self._smoothing) + (
+ self._measured_rate * (1 - self._smoothing)
+ )
+ self._count = 0
+ self._last_bucket = bucket
+ return self._measured_rate
+
+ @property
+ def measured_rate(self):
+ return self._measured_rate
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/base.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/base.py
new file mode 100644
index 0000000000..108bfed690
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/base.py
@@ -0,0 +1,26 @@
+class BaseRetryBackoff:
+ def delay_amount(self, context):
+ """Calculate how long we should delay before retrying.
+
+ :type context: RetryContext
+
+ """
+ raise NotImplementedError("delay_amount")
+
+
+class BaseRetryableChecker:
+ """Base class for determining if a retry should happen.
+
+ This base class checks for specific retryable conditions.
+ A single retryable checker doesn't necessarily indicate a retry
+ will happen. It's up to the ``RetryPolicy`` to use its
+ ``BaseRetryableCheckers`` to make the final decision on whether a retry
+ should happen.
+ """
+
+ def is_retryable(self, context):
+ """Returns True if retryable, False if not.
+
+ :type context: RetryContext
+ """
+ raise NotImplementedError("is_retryable")
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/bucket.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/bucket.py
new file mode 100644
index 0000000000..1818e5d57b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/bucket.py
@@ -0,0 +1,114 @@
+"""This module implements token buckets used for client side throttling."""
+import threading
+import time
+
+from botocore.exceptions import CapacityNotAvailableError
+
+
+class Clock:
+ def __init__(self):
+ pass
+
+ def sleep(self, amount):
+ time.sleep(amount)
+
+ def current_time(self):
+ return time.time()
+
+
+class TokenBucket:
+ _MIN_RATE = 0.5
+
+ def __init__(self, max_rate, clock, min_rate=_MIN_RATE):
+ self._fill_rate = None
+ self._max_capacity = None
+ self._current_capacity = 0
+ self._clock = clock
+ self._last_timestamp = None
+ self._min_rate = min_rate
+ self._lock = threading.Lock()
+ self._new_fill_rate_condition = threading.Condition(self._lock)
+ self.max_rate = max_rate
+
+ @property
+ def max_rate(self):
+ return self._fill_rate
+
+ @max_rate.setter
+ def max_rate(self, value):
+ with self._new_fill_rate_condition:
+ # Before we can change the rate we need to fill any pending
+ # tokens we might have based on the current rate. If we don't
+ # do this it means everything since the last recorded timestamp
+ # will accumulate at the rate we're about to set which isn't
+ # correct.
+ self._refill()
+ self._fill_rate = max(value, self._min_rate)
+ if value >= 1:
+ self._max_capacity = value
+ else:
+ self._max_capacity = 1
+ # If we're scaling down, we also can't have a capacity that's
+ # more than our max_capacity.
+ self._current_capacity = min(
+ self._current_capacity, self._max_capacity
+ )
+ self._new_fill_rate_condition.notify()
+
+ @property
+ def max_capacity(self):
+ return self._max_capacity
+
+ @property
+ def available_capacity(self):
+ return self._current_capacity
+
+ def acquire(self, amount=1, block=True):
+ """Acquire token or return amount of time until next token available.
+
+ If block is True, then this method will block until there's sufficient
+ capacity to acquire the desired amount.
+
+ If block is False, then this method will return True is capacity
+ was successfully acquired, False otherwise.
+
+ """
+ with self._new_fill_rate_condition:
+ return self._acquire(amount=amount, block=block)
+
+ def _acquire(self, amount, block):
+ self._refill()
+ if amount <= self._current_capacity:
+ self._current_capacity -= amount
+ return True
+ else:
+ if not block:
+ raise CapacityNotAvailableError()
+ # Not enough capacity.
+ sleep_amount = self._sleep_amount(amount)
+ while sleep_amount > 0:
+ # Until python3.2, wait() always returned None so we can't
+ # tell if a timeout occurred waiting on the cond var.
+ # Because of this we'll unconditionally call _refill().
+ # The downside to this is that we were waken up via
+ # a notify(), we're calling unnecessarily calling _refill() an
+ # extra time.
+ self._new_fill_rate_condition.wait(sleep_amount)
+ self._refill()
+ sleep_amount = self._sleep_amount(amount)
+ self._current_capacity -= amount
+ return True
+
+ def _sleep_amount(self, amount):
+ return (amount - self._current_capacity) / self._fill_rate
+
+ def _refill(self):
+ timestamp = self._clock.current_time()
+ if self._last_timestamp is None:
+ self._last_timestamp = timestamp
+ return
+ current_capacity = self._current_capacity
+ fill_amount = (timestamp - self._last_timestamp) * self._fill_rate
+ new_capacity = min(self._max_capacity, current_capacity + fill_amount)
+ self._current_capacity = new_capacity
+ self._last_timestamp = timestamp
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/quota.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/quota.py
new file mode 100644
index 0000000000..c3e91ae367
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/quota.py
@@ -0,0 +1,56 @@
+"""Retry quota implementation.
+
+
+"""
+import threading
+
+
+class RetryQuota:
+ INITIAL_CAPACITY = 500
+
+ def __init__(self, initial_capacity=INITIAL_CAPACITY, lock=None):
+ self._max_capacity = initial_capacity
+ self._available_capacity = initial_capacity
+ if lock is None:
+ lock = threading.Lock()
+ self._lock = lock
+
+ def acquire(self, capacity_amount):
+ """Attempt to aquire a certain amount of capacity.
+
+ If there's not sufficient amount of capacity available, ``False``
+ is returned. Otherwise, ``True`` is returned, which indicates that
+ capacity was successfully allocated.
+
+ """
+ # The acquire() is only called when we encounter a retryable
+ # response so we aren't worried about locking the entire method.
+ with self._lock:
+ if capacity_amount > self._available_capacity:
+ return False
+ self._available_capacity -= capacity_amount
+ return True
+
+ def release(self, capacity_amount):
+ """Release capacity back to the retry quota.
+
+ The capacity being released will be truncated if necessary
+ to ensure the max capacity is never exceeded.
+
+ """
+ # Implementation note: The release() method is called as part
+ # of the "after-call" event, which means it gets invoked for
+ # every API call. In the common case where the request is
+ # successful and we're at full capacity, we can avoid locking.
+ # We can't exceed max capacity so there's no work we have to do.
+ if self._max_capacity == self._available_capacity:
+ return
+ with self._lock:
+ amount = min(
+ self._max_capacity - self._available_capacity, capacity_amount
+ )
+ self._available_capacity += amount
+
+ @property
+ def available_capacity(self):
+ return self._available_capacity
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/special.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/special.py
new file mode 100644
index 0000000000..9ce18b1fa3
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/special.py
@@ -0,0 +1,50 @@
+"""Special cased retries.
+
+These are additional retry cases we still have to handle from the legacy
+retry handler. They don't make sense as part of the standard mode retry
+module. Ideally we should be able to remove this module.
+
+"""
+import logging
+from binascii import crc32
+
+from botocore.retries.base import BaseRetryableChecker
+
+logger = logging.getLogger(__name__)
+
+
+# TODO: This is an ideal candidate for the retryable trait once that's
+# available.
+class RetryIDPCommunicationError(BaseRetryableChecker):
+ _SERVICE_NAME = 'sts'
+
+ def is_retryable(self, context):
+ service_name = context.operation_model.service_model.service_name
+ if service_name != self._SERVICE_NAME:
+ return False
+ error_code = context.get_error_code()
+ return error_code == 'IDPCommunicationError'
+
+
+class RetryDDBChecksumError(BaseRetryableChecker):
+ _CHECKSUM_HEADER = 'x-amz-crc32'
+ _SERVICE_NAME = 'dynamodb'
+
+ def is_retryable(self, context):
+ service_name = context.operation_model.service_model.service_name
+ if service_name != self._SERVICE_NAME:
+ return False
+ if context.http_response is None:
+ return False
+ checksum = context.http_response.headers.get(self._CHECKSUM_HEADER)
+ if checksum is None:
+ return False
+ actual_crc32 = crc32(context.http_response.content) & 0xFFFFFFFF
+ if actual_crc32 != int(checksum):
+ logger.debug(
+ "DynamoDB crc32 checksum does not match, "
+ "expected: %s, actual: %s",
+ checksum,
+ actual_crc32,
+ )
+ return True
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/standard.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/standard.py
new file mode 100644
index 0000000000..00927d6769
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/standard.py
@@ -0,0 +1,531 @@
+"""Standard retry behavior.
+
+This contains the default standard retry behavior.
+It provides consistent behavior with other AWS SDKs.
+
+The key base classes uses for retries:
+
+ * ``BaseRetryableChecker`` - Use to check a specific condition that
+ indicates a retry should happen. This can include things like
+ max attempts, HTTP status code checks, error code checks etc.
+ * ``RetryBackoff`` - Use to determine how long we should backoff until
+ we retry a request. This is the class that will implement delay such
+ as exponential backoff.
+ * ``RetryPolicy`` - Main class that determines if a retry should
+ happen. It can combine data from a various BaseRetryableCheckers
+ to make a final call as to whether or not a retry should happen.
+ It then uses a ``BaseRetryBackoff`` to determine how long to delay.
+ * ``RetryHandler`` - The bridge between botocore's event system
+ used by endpoint.py to manage retries and the interfaces defined
+ in this module.
+
+This allows us to define an API that has minimal coupling to the event
+based API used by botocore.
+
+"""
+import logging
+import random
+
+from botocore.exceptions import (
+ ConnectionError,
+ ConnectTimeoutError,
+ HTTPClientError,
+ ReadTimeoutError,
+)
+from botocore.retries import quota, special
+from botocore.retries.base import BaseRetryableChecker, BaseRetryBackoff
+
+DEFAULT_MAX_ATTEMPTS = 3
+logger = logging.getLogger(__name__)
+
+
+def register_retry_handler(client, max_attempts=DEFAULT_MAX_ATTEMPTS):
+ retry_quota = RetryQuotaChecker(quota.RetryQuota())
+
+ service_id = client.meta.service_model.service_id
+ service_event_name = service_id.hyphenize()
+ client.meta.events.register(
+ f'after-call.{service_event_name}', retry_quota.release_retry_quota
+ )
+
+ handler = RetryHandler(
+ retry_policy=RetryPolicy(
+ retry_checker=StandardRetryConditions(max_attempts=max_attempts),
+ retry_backoff=ExponentialBackoff(),
+ ),
+ retry_event_adapter=RetryEventAdapter(),
+ retry_quota=retry_quota,
+ )
+
+ unique_id = 'retry-config-%s' % service_event_name
+ client.meta.events.register(
+ 'needs-retry.%s' % service_event_name,
+ handler.needs_retry,
+ unique_id=unique_id,
+ )
+ return handler
+
+
+class RetryHandler:
+ """Bridge between botocore's event system and this module.
+
+ This class is intended to be hooked to botocore's event system
+ as an event handler.
+ """
+
+ def __init__(self, retry_policy, retry_event_adapter, retry_quota):
+ self._retry_policy = retry_policy
+ self._retry_event_adapter = retry_event_adapter
+ self._retry_quota = retry_quota
+
+ def needs_retry(self, **kwargs):
+ """Connect as a handler to the needs-retry event."""
+ retry_delay = None
+ context = self._retry_event_adapter.create_retry_context(**kwargs)
+ if self._retry_policy.should_retry(context):
+ # Before we can retry we need to ensure we have sufficient
+ # capacity in our retry quota.
+ if self._retry_quota.acquire_retry_quota(context):
+ retry_delay = self._retry_policy.compute_retry_delay(context)
+ logger.debug(
+ "Retry needed, retrying request after delay of: %s",
+ retry_delay,
+ )
+ else:
+ logger.debug(
+ "Retry needed but retry quota reached, "
+ "not retrying request."
+ )
+ else:
+ logger.debug("Not retrying request.")
+ self._retry_event_adapter.adapt_retry_response_from_context(context)
+ return retry_delay
+
+
+class RetryEventAdapter:
+ """Adapter to existing retry interface used in the endpoints layer.
+
+ This existing interface for determining if a retry needs to happen
+ is event based and used in ``botocore.endpoint``. The interface has
+ grown organically over the years and could use some cleanup. This
+ adapter converts that interface into the interface used by the
+ new retry strategies.
+
+ """
+
+ def create_retry_context(self, **kwargs):
+ """Create context based on needs-retry kwargs."""
+ response = kwargs['response']
+ if response is None:
+ # If response is None it means that an exception was raised
+ # because we never received a response from the service. This
+ # could be something like a ConnectionError we get from our
+ # http layer.
+ http_response = None
+ parsed_response = None
+ else:
+ http_response, parsed_response = response
+ # This provides isolation between the kwargs emitted in the
+ # needs-retry event, and what this module uses to check for
+ # retries.
+ context = RetryContext(
+ attempt_number=kwargs['attempts'],
+ operation_model=kwargs['operation'],
+ http_response=http_response,
+ parsed_response=parsed_response,
+ caught_exception=kwargs['caught_exception'],
+ request_context=kwargs['request_dict']['context'],
+ )
+ return context
+
+ def adapt_retry_response_from_context(self, context):
+ """Modify response back to user back from context."""
+ # This will mutate attributes that are returned back to the end
+ # user. We do it this way so that all the various retry classes
+ # don't mutate any input parameters from the needs-retry event.
+ metadata = context.get_retry_metadata()
+ if context.parsed_response is not None:
+ context.parsed_response.setdefault('ResponseMetadata', {}).update(
+ metadata
+ )
+
+
+# Implementation note: this is meant to encapsulate all the misc stuff
+# that gets sent in the needs-retry event. This is mapped so that params
+# are more clear and explicit.
+class RetryContext:
+ """Normalize a response that we use to check if a retry should occur.
+
+ This class smoothes over the different types of responses we may get
+ from a service including:
+
+ * A modeled error response from the service that contains a service
+ code and error message.
+ * A raw HTTP response that doesn't contain service protocol specific
+ error keys.
+ * An exception received while attempting to retrieve a response.
+ This could be a ConnectionError we receive from our HTTP layer which
+ could represent that we weren't able to receive a response from
+ the service.
+
+ This class guarantees that at least one of the above attributes will be
+ non None.
+
+ This class is meant to provide a read-only view into the properties
+ associated with a possible retryable response. None of the properties
+ are meant to be modified directly.
+
+ """
+
+ def __init__(
+ self,
+ attempt_number,
+ operation_model=None,
+ parsed_response=None,
+ http_response=None,
+ caught_exception=None,
+ request_context=None,
+ ):
+ # 1-based attempt number.
+ self.attempt_number = attempt_number
+ self.operation_model = operation_model
+ # This is the parsed response dictionary we get from parsing
+ # the HTTP response from the service.
+ self.parsed_response = parsed_response
+ # This is an instance of botocore.awsrequest.AWSResponse.
+ self.http_response = http_response
+ # This is a subclass of Exception that will be non None if
+ # an exception was raised when retrying to retrieve a response.
+ self.caught_exception = caught_exception
+ # This is the request context dictionary that's added to the
+ # request dict. This is used to story any additional state
+ # about the request. We use this for storing retry quota
+ # capacity.
+ if request_context is None:
+ request_context = {}
+ self.request_context = request_context
+ self._retry_metadata = {}
+
+ # These are misc helper methods to avoid duplication in the various
+ # checkers.
+ def get_error_code(self):
+ """Check if there was a parsed response with an error code.
+
+ If we could not find any error codes, ``None`` is returned.
+
+ """
+ if self.parsed_response is None:
+ return
+ error = self.parsed_response.get('Error', {})
+ if not isinstance(error, dict):
+ return
+ return error.get('Code')
+
+ def add_retry_metadata(self, **kwargs):
+ """Add key/value pairs to the retry metadata.
+
+ This allows any objects during the retry process to add
+ metadata about any checks/validations that happened.
+
+ This gets added to the response metadata in the retry handler.
+
+ """
+ self._retry_metadata.update(**kwargs)
+
+ def get_retry_metadata(self):
+ return self._retry_metadata.copy()
+
+
+class RetryPolicy:
+ def __init__(self, retry_checker, retry_backoff):
+ self._retry_checker = retry_checker
+ self._retry_backoff = retry_backoff
+
+ def should_retry(self, context):
+ return self._retry_checker.is_retryable(context)
+
+ def compute_retry_delay(self, context):
+ return self._retry_backoff.delay_amount(context)
+
+
+class ExponentialBackoff(BaseRetryBackoff):
+ _BASE = 2
+ _MAX_BACKOFF = 20
+
+ def __init__(self, max_backoff=20, random=random.random):
+ self._base = self._BASE
+ self._max_backoff = max_backoff
+ self._random = random
+
+ def delay_amount(self, context):
+ """Calculates delay based on exponential backoff.
+
+ This class implements truncated binary exponential backoff
+ with jitter::
+
+ t_i = min(rand(0, 1) * 2 ** attempt, MAX_BACKOFF)
+
+ where ``i`` is the request attempt (0 based).
+
+ """
+ # The context.attempt_number is a 1-based value, but we have
+ # to calculate the delay based on i based a 0-based value. We
+ # want the first delay to just be ``rand(0, 1)``.
+ return min(
+ self._random() * (self._base ** (context.attempt_number - 1)),
+ self._max_backoff,
+ )
+
+
+class MaxAttemptsChecker(BaseRetryableChecker):
+ def __init__(self, max_attempts):
+ self._max_attempts = max_attempts
+
+ def is_retryable(self, context):
+ under_max_attempts = context.attempt_number < self._max_attempts
+ retries_context = context.request_context.get('retries')
+ if retries_context:
+ retries_context['max'] = max(
+ retries_context.get('max', 0), self._max_attempts
+ )
+ if not under_max_attempts:
+ logger.debug("Max attempts of %s reached.", self._max_attempts)
+ context.add_retry_metadata(MaxAttemptsReached=True)
+ return under_max_attempts
+
+
+class TransientRetryableChecker(BaseRetryableChecker):
+ _TRANSIENT_ERROR_CODES = [
+ 'RequestTimeout',
+ 'RequestTimeoutException',
+ 'PriorRequestNotComplete',
+ ]
+ _TRANSIENT_STATUS_CODES = [500, 502, 503, 504]
+ _TRANSIENT_EXCEPTION_CLS = (
+ ConnectionError,
+ HTTPClientError,
+ )
+
+ def __init__(
+ self,
+ transient_error_codes=None,
+ transient_status_codes=None,
+ transient_exception_cls=None,
+ ):
+ if transient_error_codes is None:
+ transient_error_codes = self._TRANSIENT_ERROR_CODES[:]
+ if transient_status_codes is None:
+ transient_status_codes = self._TRANSIENT_STATUS_CODES[:]
+ if transient_exception_cls is None:
+ transient_exception_cls = self._TRANSIENT_EXCEPTION_CLS
+ self._transient_error_codes = transient_error_codes
+ self._transient_status_codes = transient_status_codes
+ self._transient_exception_cls = transient_exception_cls
+
+ def is_retryable(self, context):
+ if context.get_error_code() in self._transient_error_codes:
+ return True
+ if context.http_response is not None:
+ if (
+ context.http_response.status_code
+ in self._transient_status_codes
+ ):
+ return True
+ if context.caught_exception is not None:
+ return isinstance(
+ context.caught_exception, self._transient_exception_cls
+ )
+ return False
+
+
+class ThrottledRetryableChecker(BaseRetryableChecker):
+ # This is the union of all error codes we've seen that represent
+ # a throttled error.
+ _THROTTLED_ERROR_CODES = [
+ 'Throttling',
+ 'ThrottlingException',
+ 'ThrottledException',
+ 'RequestThrottledException',
+ 'TooManyRequestsException',
+ 'ProvisionedThroughputExceededException',
+ 'TransactionInProgressException',
+ 'RequestLimitExceeded',
+ 'BandwidthLimitExceeded',
+ 'LimitExceededException',
+ 'RequestThrottled',
+ 'SlowDown',
+ 'PriorRequestNotComplete',
+ 'EC2ThrottledException',
+ ]
+
+ def __init__(self, throttled_error_codes=None):
+ if throttled_error_codes is None:
+ throttled_error_codes = self._THROTTLED_ERROR_CODES[:]
+ self._throttled_error_codes = throttled_error_codes
+
+ def is_retryable(self, context):
+ # Only the error code from a parsed service response is used
+ # to determine if the response is a throttled response.
+ return context.get_error_code() in self._throttled_error_codes
+
+
+class ModeledRetryableChecker(BaseRetryableChecker):
+ """Check if an error has been modeled as retryable."""
+
+ def __init__(self):
+ self._error_detector = ModeledRetryErrorDetector()
+
+ def is_retryable(self, context):
+ error_code = context.get_error_code()
+ if error_code is None:
+ return False
+ return self._error_detector.detect_error_type(context) is not None
+
+
+class ModeledRetryErrorDetector:
+ """Checks whether or not an error is a modeled retryable error."""
+
+ # There are return values from the detect_error_type() method.
+ TRANSIENT_ERROR = 'TRANSIENT_ERROR'
+ THROTTLING_ERROR = 'THROTTLING_ERROR'
+ # This class is lower level than ModeledRetryableChecker, which
+ # implements BaseRetryableChecker. This object allows you to distinguish
+ # between the various types of retryable errors.
+
+ def detect_error_type(self, context):
+ """Detect the error type associated with an error code and model.
+
+ This will either return:
+
+ * ``self.TRANSIENT_ERROR`` - If the error is a transient error
+ * ``self.THROTTLING_ERROR`` - If the error is a throttling error
+ * ``None`` - If the error is neither type of error.
+
+ """
+ error_code = context.get_error_code()
+ op_model = context.operation_model
+ if op_model is None or not op_model.error_shapes:
+ return
+ for shape in op_model.error_shapes:
+ if shape.metadata.get('retryable') is not None:
+ # Check if this error code matches the shape. This can
+ # be either by name or by a modeled error code.
+ error_code_to_check = (
+ shape.metadata.get('error', {}).get('code') or shape.name
+ )
+ if error_code == error_code_to_check:
+ if shape.metadata['retryable'].get('throttling'):
+ return self.THROTTLING_ERROR
+ return self.TRANSIENT_ERROR
+
+
+class ThrottlingErrorDetector:
+ def __init__(self, retry_event_adapter):
+ self._modeled_error_detector = ModeledRetryErrorDetector()
+ self._fixed_error_code_detector = ThrottledRetryableChecker()
+ self._retry_event_adapter = retry_event_adapter
+
+ # This expects the kwargs from needs-retry to be passed through.
+ def is_throttling_error(self, **kwargs):
+ context = self._retry_event_adapter.create_retry_context(**kwargs)
+ if self._fixed_error_code_detector.is_retryable(context):
+ return True
+ error_type = self._modeled_error_detector.detect_error_type(context)
+ return error_type == self._modeled_error_detector.THROTTLING_ERROR
+
+
+class StandardRetryConditions(BaseRetryableChecker):
+ """Concrete class that implements the standard retry policy checks.
+
+ Specifically:
+
+ not max_attempts and (transient or throttled or modeled_retry)
+
+ """
+
+ def __init__(self, max_attempts=DEFAULT_MAX_ATTEMPTS):
+ # Note: This class is for convenience so you can have the
+ # standard retry condition in a single class.
+ self._max_attempts_checker = MaxAttemptsChecker(max_attempts)
+ self._additional_checkers = OrRetryChecker(
+ [
+ TransientRetryableChecker(),
+ ThrottledRetryableChecker(),
+ ModeledRetryableChecker(),
+ OrRetryChecker(
+ [
+ special.RetryIDPCommunicationError(),
+ special.RetryDDBChecksumError(),
+ ]
+ ),
+ ]
+ )
+
+ def is_retryable(self, context):
+ return self._max_attempts_checker.is_retryable(
+ context
+ ) and self._additional_checkers.is_retryable(context)
+
+
+class OrRetryChecker(BaseRetryableChecker):
+ def __init__(self, checkers):
+ self._checkers = checkers
+
+ def is_retryable(self, context):
+ return any(checker.is_retryable(context) for checker in self._checkers)
+
+
+class RetryQuotaChecker:
+ _RETRY_COST = 5
+ _NO_RETRY_INCREMENT = 1
+ _TIMEOUT_RETRY_REQUEST = 10
+ _TIMEOUT_EXCEPTIONS = (ConnectTimeoutError, ReadTimeoutError)
+
+ # Implementation note: We're not making this a BaseRetryableChecker
+ # because this isn't just a check if we can retry. This also changes
+ # state so we have to careful when/how we call this. Making it
+ # a BaseRetryableChecker implies you can call .is_retryable(context)
+ # as many times as you want and not affect anything.
+
+ def __init__(self, quota):
+ self._quota = quota
+ # This tracks the last amount
+ self._last_amount_acquired = None
+
+ def acquire_retry_quota(self, context):
+ if self._is_timeout_error(context):
+ capacity_amount = self._TIMEOUT_RETRY_REQUEST
+ else:
+ capacity_amount = self._RETRY_COST
+ success = self._quota.acquire(capacity_amount)
+ if success:
+ # We add the capacity amount to the request context so we know
+ # how much to release later. The capacity amount can vary based
+ # on the error.
+ context.request_context['retry_quota_capacity'] = capacity_amount
+ return True
+ context.add_retry_metadata(RetryQuotaReached=True)
+ return False
+
+ def _is_timeout_error(self, context):
+ return isinstance(context.caught_exception, self._TIMEOUT_EXCEPTIONS)
+
+ # This is intended to be hooked up to ``after-call``.
+ def release_retry_quota(self, context, http_response, **kwargs):
+ # There's three possible options.
+ # 1. The HTTP response did not have a 2xx response. In that case we
+ # give no quota back.
+ # 2. The HTTP request was successful and was never retried. In
+ # that case we give _NO_RETRY_INCREMENT back.
+ # 3. The API call had retries, and we eventually receive an HTTP
+ # response with a 2xx status code. In that case we give back
+ # whatever quota was associated with the last acquisition.
+ if http_response is None:
+ return
+ status_code = http_response.status_code
+ if 200 <= status_code < 300:
+ if 'retry_quota_capacity' not in context:
+ self._quota.release(self._NO_RETRY_INCREMENT)
+ else:
+ capacity_amount = context['retry_quota_capacity']
+ self._quota.release(capacity_amount)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/throttling.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/throttling.py
new file mode 100644
index 0000000000..34ab417299
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retries/throttling.py
@@ -0,0 +1,55 @@
+from collections import namedtuple
+
+CubicParams = namedtuple('CubicParams', ['w_max', 'k', 'last_fail'])
+
+
+class CubicCalculator:
+ _SCALE_CONSTANT = 0.4
+ _BETA = 0.7
+
+ def __init__(
+ self,
+ starting_max_rate,
+ start_time,
+ scale_constant=_SCALE_CONSTANT,
+ beta=_BETA,
+ ):
+ self._w_max = starting_max_rate
+ self._scale_constant = scale_constant
+ self._beta = beta
+ self._k = self._calculate_zero_point()
+ self._last_fail = start_time
+
+ def _calculate_zero_point(self):
+ scaled_value = (self._w_max * (1 - self._beta)) / self._scale_constant
+ k = scaled_value ** (1 / 3.0)
+ return k
+
+ def success_received(self, timestamp):
+ dt = timestamp - self._last_fail
+ new_rate = self._scale_constant * (dt - self._k) ** 3 + self._w_max
+ return new_rate
+
+ def error_received(self, current_rate, timestamp):
+ # Consider not having this be the current measured rate.
+
+ # We have a new max rate, which is the current rate we were sending
+ # at when we received an error response.
+ self._w_max = current_rate
+ self._k = self._calculate_zero_point()
+ self._last_fail = timestamp
+ return current_rate * self._beta
+
+ def get_params_snapshot(self):
+ """Return a read-only object of the current cubic parameters.
+
+ These parameters are intended to be used for debug/troubleshooting
+ purposes. These object is a read-only snapshot and cannot be used
+ to modify the behavior of the CUBIC calculations.
+
+ New parameters may be added to this object in the future.
+
+ """
+ return CubicParams(
+ w_max=self._w_max, k=self._k, last_fail=self._last_fail
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retryhandler.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retryhandler.py
new file mode 100644
index 0000000000..deef1bfe9e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/retryhandler.py
@@ -0,0 +1,416 @@
+# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+import functools
+import logging
+import random
+from binascii import crc32
+
+from botocore.exceptions import (
+ ChecksumError,
+ ConnectionClosedError,
+ ConnectionError,
+ EndpointConnectionError,
+ ReadTimeoutError,
+)
+
+logger = logging.getLogger(__name__)
+# The only supported error for now is GENERAL_CONNECTION_ERROR
+# which maps to requests generic ConnectionError. If we're able
+# to get more specific exceptions from requests we can update
+# this mapping with more specific exceptions.
+EXCEPTION_MAP = {
+ 'GENERAL_CONNECTION_ERROR': [
+ ConnectionError,
+ ConnectionClosedError,
+ ReadTimeoutError,
+ EndpointConnectionError,
+ ],
+}
+
+
+def delay_exponential(base, growth_factor, attempts):
+ """Calculate time to sleep based on exponential function.
+
+ The format is::
+
+ base * growth_factor ^ (attempts - 1)
+
+ If ``base`` is set to 'rand' then a random number between
+ 0 and 1 will be used as the base.
+ Base must be greater than 0, otherwise a ValueError will be
+ raised.
+
+ """
+ if base == 'rand':
+ base = random.random()
+ elif base <= 0:
+ raise ValueError(
+ f"The 'base' param must be greater than 0, got: {base}"
+ )
+ time_to_sleep = base * (growth_factor ** (attempts - 1))
+ return time_to_sleep
+
+
+def create_exponential_delay_function(base, growth_factor):
+ """Create an exponential delay function based on the attempts.
+
+ This is used so that you only have to pass it the attempts
+ parameter to calculate the delay.
+
+ """
+ return functools.partial(
+ delay_exponential, base=base, growth_factor=growth_factor
+ )
+
+
+def create_retry_handler(config, operation_name=None):
+ checker = create_checker_from_retry_config(
+ config, operation_name=operation_name
+ )
+ action = create_retry_action_from_config(
+ config, operation_name=operation_name
+ )
+ return RetryHandler(checker=checker, action=action)
+
+
+def create_retry_action_from_config(config, operation_name=None):
+ # The spec has the possibility of supporting per policy
+ # actions, but right now, we assume this comes from the
+ # default section, which means that delay functions apply
+ # for every policy in the retry config (per service).
+ delay_config = config['__default__']['delay']
+ if delay_config['type'] == 'exponential':
+ return create_exponential_delay_function(
+ base=delay_config['base'],
+ growth_factor=delay_config['growth_factor'],
+ )
+
+
+def create_checker_from_retry_config(config, operation_name=None):
+ checkers = []
+ max_attempts = None
+ retryable_exceptions = []
+ if '__default__' in config:
+ policies = config['__default__'].get('policies', [])
+ max_attempts = config['__default__']['max_attempts']
+ for key in policies:
+ current_config = policies[key]
+ checkers.append(_create_single_checker(current_config))
+ retry_exception = _extract_retryable_exception(current_config)
+ if retry_exception is not None:
+ retryable_exceptions.extend(retry_exception)
+ if operation_name is not None and config.get(operation_name) is not None:
+ operation_policies = config[operation_name]['policies']
+ for key in operation_policies:
+ checkers.append(_create_single_checker(operation_policies[key]))
+ retry_exception = _extract_retryable_exception(
+ operation_policies[key]
+ )
+ if retry_exception is not None:
+ retryable_exceptions.extend(retry_exception)
+ if len(checkers) == 1:
+ # Don't need to use a MultiChecker
+ return MaxAttemptsDecorator(checkers[0], max_attempts=max_attempts)
+ else:
+ multi_checker = MultiChecker(checkers)
+ return MaxAttemptsDecorator(
+ multi_checker,
+ max_attempts=max_attempts,
+ retryable_exceptions=tuple(retryable_exceptions),
+ )
+
+
+def _create_single_checker(config):
+ if 'response' in config['applies_when']:
+ return _create_single_response_checker(
+ config['applies_when']['response']
+ )
+ elif 'socket_errors' in config['applies_when']:
+ return ExceptionRaiser()
+
+
+def _create_single_response_checker(response):
+ if 'service_error_code' in response:
+ checker = ServiceErrorCodeChecker(
+ status_code=response['http_status_code'],
+ error_code=response['service_error_code'],
+ )
+ elif 'http_status_code' in response:
+ checker = HTTPStatusCodeChecker(
+ status_code=response['http_status_code']
+ )
+ elif 'crc32body' in response:
+ checker = CRC32Checker(header=response['crc32body'])
+ else:
+ # TODO: send a signal.
+ raise ValueError("Unknown retry policy")
+ return checker
+
+
+def _extract_retryable_exception(config):
+ applies_when = config['applies_when']
+ if 'crc32body' in applies_when.get('response', {}):
+ return [ChecksumError]
+ elif 'socket_errors' in applies_when:
+ exceptions = []
+ for name in applies_when['socket_errors']:
+ exceptions.extend(EXCEPTION_MAP[name])
+ return exceptions
+
+
+class RetryHandler:
+ """Retry handler.
+
+ The retry handler takes two params, ``checker`` object
+ and an ``action`` object.
+
+ The ``checker`` object must be a callable object and based on a response
+ and an attempt number, determines whether or not sufficient criteria for
+ a retry has been met. If this is the case then the ``action`` object
+ (which also is a callable) determines what needs to happen in the event
+ of a retry.
+
+ """
+
+ def __init__(self, checker, action):
+ self._checker = checker
+ self._action = action
+
+ def __call__(self, attempts, response, caught_exception, **kwargs):
+ """Handler for a retry.
+
+ Intended to be hooked up to an event handler (hence the **kwargs),
+ this will process retries appropriately.
+
+ """
+ checker_kwargs = {
+ 'attempt_number': attempts,
+ 'response': response,
+ 'caught_exception': caught_exception,
+ }
+ if isinstance(self._checker, MaxAttemptsDecorator):
+ retries_context = kwargs['request_dict']['context'].get('retries')
+ checker_kwargs.update({'retries_context': retries_context})
+
+ if self._checker(**checker_kwargs):
+ result = self._action(attempts=attempts)
+ logger.debug("Retry needed, action of: %s", result)
+ return result
+ logger.debug("No retry needed.")
+
+
+class BaseChecker:
+ """Base class for retry checkers.
+
+ Each class is responsible for checking a single criteria that determines
+ whether or not a retry should not happen.
+
+ """
+
+ def __call__(self, attempt_number, response, caught_exception):
+ """Determine if retry criteria matches.
+
+ Note that either ``response`` is not None and ``caught_exception`` is
+ None or ``response`` is None and ``caught_exception`` is not None.
+
+ :type attempt_number: int
+ :param attempt_number: The total number of times we've attempted
+ to send the request.
+
+ :param response: The HTTP response (if one was received).
+
+ :type caught_exception: Exception
+ :param caught_exception: Any exception that was caught while trying to
+ send the HTTP response.
+
+ :return: True, if the retry criteria matches (and therefore a retry
+ should occur. False if the criteria does not match.
+
+ """
+ # The default implementation allows subclasses to not have to check
+ # whether or not response is None or not.
+ if response is not None:
+ return self._check_response(attempt_number, response)
+ elif caught_exception is not None:
+ return self._check_caught_exception(
+ attempt_number, caught_exception
+ )
+ else:
+ raise ValueError("Both response and caught_exception are None.")
+
+ def _check_response(self, attempt_number, response):
+ pass
+
+ def _check_caught_exception(self, attempt_number, caught_exception):
+ pass
+
+
+class MaxAttemptsDecorator(BaseChecker):
+ """Allow retries up to a maximum number of attempts.
+
+ This will pass through calls to the decorated retry checker, provided
+ that the number of attempts does not exceed max_attempts. It will
+ also catch any retryable_exceptions passed in. Once max_attempts has
+ been exceeded, then False will be returned or the retryable_exceptions
+ that was previously being caught will be raised.
+
+ """
+
+ def __init__(self, checker, max_attempts, retryable_exceptions=None):
+ self._checker = checker
+ self._max_attempts = max_attempts
+ self._retryable_exceptions = retryable_exceptions
+
+ def __call__(
+ self, attempt_number, response, caught_exception, retries_context
+ ):
+ if retries_context:
+ retries_context['max'] = max(
+ retries_context.get('max', 0), self._max_attempts
+ )
+
+ should_retry = self._should_retry(
+ attempt_number, response, caught_exception
+ )
+ if should_retry:
+ if attempt_number >= self._max_attempts:
+ # explicitly set MaxAttemptsReached
+ if response is not None and 'ResponseMetadata' in response[1]:
+ response[1]['ResponseMetadata'][
+ 'MaxAttemptsReached'
+ ] = True
+ logger.debug(
+ "Reached the maximum number of retry attempts: %s",
+ attempt_number,
+ )
+ return False
+ else:
+ return should_retry
+ else:
+ return False
+
+ def _should_retry(self, attempt_number, response, caught_exception):
+ if self._retryable_exceptions and attempt_number < self._max_attempts:
+ try:
+ return self._checker(
+ attempt_number, response, caught_exception
+ )
+ except self._retryable_exceptions as e:
+ logger.debug(
+ "retry needed, retryable exception caught: %s",
+ e,
+ exc_info=True,
+ )
+ return True
+ else:
+ # If we've exceeded the max attempts we just let the exception
+ # propagate if one has occurred.
+ return self._checker(attempt_number, response, caught_exception)
+
+
+class HTTPStatusCodeChecker(BaseChecker):
+ def __init__(self, status_code):
+ self._status_code = status_code
+
+ def _check_response(self, attempt_number, response):
+ if response[0].status_code == self._status_code:
+ logger.debug(
+ "retry needed: retryable HTTP status code received: %s",
+ self._status_code,
+ )
+ return True
+ else:
+ return False
+
+
+class ServiceErrorCodeChecker(BaseChecker):
+ def __init__(self, status_code, error_code):
+ self._status_code = status_code
+ self._error_code = error_code
+
+ def _check_response(self, attempt_number, response):
+ if response[0].status_code == self._status_code:
+ actual_error_code = response[1].get('Error', {}).get('Code')
+ if actual_error_code == self._error_code:
+ logger.debug(
+ "retry needed: matching HTTP status and error code seen: "
+ "%s, %s",
+ self._status_code,
+ self._error_code,
+ )
+ return True
+ return False
+
+
+class MultiChecker(BaseChecker):
+ def __init__(self, checkers):
+ self._checkers = checkers
+
+ def __call__(self, attempt_number, response, caught_exception):
+ for checker in self._checkers:
+ checker_response = checker(
+ attempt_number, response, caught_exception
+ )
+ if checker_response:
+ return checker_response
+ return False
+
+
+class CRC32Checker(BaseChecker):
+ def __init__(self, header):
+ # The header where the expected crc32 is located.
+ self._header_name = header
+
+ def _check_response(self, attempt_number, response):
+ http_response = response[0]
+ expected_crc = http_response.headers.get(self._header_name)
+ if expected_crc is None:
+ logger.debug(
+ "crc32 check skipped, the %s header is not "
+ "in the http response.",
+ self._header_name,
+ )
+ else:
+ actual_crc32 = crc32(response[0].content) & 0xFFFFFFFF
+ if not actual_crc32 == int(expected_crc):
+ logger.debug(
+ "retry needed: crc32 check failed, expected != actual: "
+ "%s != %s",
+ int(expected_crc),
+ actual_crc32,
+ )
+ raise ChecksumError(
+ checksum_type='crc32',
+ expected_checksum=int(expected_crc),
+ actual_checksum=actual_crc32,
+ )
+
+
+class ExceptionRaiser(BaseChecker):
+ """Raise any caught exceptions.
+
+ This class will raise any non None ``caught_exception``.
+
+ """
+
+ def _check_caught_exception(self, attempt_number, caught_exception):
+ # This is implementation specific, but this class is useful by
+ # coordinating with the MaxAttemptsDecorator.
+ # The MaxAttemptsDecorator has a list of exceptions it should catch
+ # and retry, but something needs to come along and actually raise the
+ # caught_exception. That's what this class is being used for. If
+ # the MaxAttemptsDecorator is not interested in retrying the exception
+ # then this exception just propagates out past the retry code.
+ raise caught_exception
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/serialize.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/serialize.py
new file mode 100644
index 0000000000..306441e060
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/serialize.py
@@ -0,0 +1,810 @@
+# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""Protocol input serializes.
+
+This module contains classes that implement input serialization
+for the various AWS protocol types.
+
+These classes essentially take user input, a model object that
+represents what the expected input should look like, and it returns
+a dictionary that contains the various parts of a request. A few
+high level design decisions:
+
+
+* Each protocol type maps to a separate class, all inherit from
+ ``Serializer``.
+* The return value for ``serialize_to_request`` (the main entry
+ point) returns a dictionary that represents a request. This
+ will have keys like ``url_path``, ``query_string``, etc. This
+ is done so that it's a) easy to test and b) not tied to a
+ particular HTTP library. See the ``serialize_to_request`` docstring
+ for more details.
+
+Unicode
+-------
+
+The input to the serializers should be text (str/unicode), not bytes,
+with the exception of blob types. Those are assumed to be binary,
+and if a str/unicode type is passed in, it will be encoded as utf-8.
+"""
+import base64
+import calendar
+import datetime
+import json
+import re
+from xml.etree import ElementTree
+
+from botocore import validate
+from botocore.compat import formatdate
+from botocore.exceptions import ParamValidationError
+from botocore.utils import (
+ has_header,
+ is_json_value_header,
+ parse_to_aware_datetime,
+ percent_encode,
+)
+
+# From the spec, the default timestamp format if not specified is iso8601.
+DEFAULT_TIMESTAMP_FORMAT = 'iso8601'
+ISO8601 = '%Y-%m-%dT%H:%M:%SZ'
+# Same as ISO8601, but with microsecond precision.
+ISO8601_MICRO = '%Y-%m-%dT%H:%M:%S.%fZ'
+HOST_PREFIX_RE = re.compile(r"^[A-Za-z0-9\.\-]+$")
+
+
+def create_serializer(protocol_name, include_validation=True):
+ # TODO: Unknown protocols.
+ serializer = SERIALIZERS[protocol_name]()
+ if include_validation:
+ validator = validate.ParamValidator()
+ serializer = validate.ParamValidationDecorator(validator, serializer)
+ return serializer
+
+
+class Serializer:
+ DEFAULT_METHOD = 'POST'
+ # Clients can change this to a different MutableMapping
+ # (i.e OrderedDict) if they want. This is used in the
+ # compliance test to match the hash ordering used in the
+ # tests.
+ MAP_TYPE = dict
+ DEFAULT_ENCODING = 'utf-8'
+
+ def serialize_to_request(self, parameters, operation_model):
+ """Serialize parameters into an HTTP request.
+
+ This method takes user provided parameters and a shape
+ model and serializes the parameters to an HTTP request.
+ More specifically, this method returns information about
+ parts of the HTTP request, it does not enforce a particular
+ interface or standard for an HTTP request. It instead returns
+ a dictionary of:
+
+ * 'url_path'
+ * 'host_prefix'
+ * 'query_string'
+ * 'headers'
+ * 'body'
+ * 'method'
+
+ It is then up to consumers to decide how to map this to a Request
+ object of their HTTP library of choice. Below is an example
+ return value::
+
+ {'body': {'Action': 'OperationName',
+ 'Bar': 'val2',
+ 'Foo': 'val1',
+ 'Version': '2014-01-01'},
+ 'headers': {},
+ 'method': 'POST',
+ 'query_string': '',
+ 'host_prefix': 'value.',
+ 'url_path': '/'}
+
+ :param parameters: The dictionary input parameters for the
+ operation (i.e the user input).
+ :param operation_model: The OperationModel object that describes
+ the operation.
+ """
+ raise NotImplementedError("serialize_to_request")
+
+ def _create_default_request(self):
+ # Creates a boilerplate default request dict that subclasses
+ # can use as a starting point.
+ serialized = {
+ 'url_path': '/',
+ 'query_string': '',
+ 'method': self.DEFAULT_METHOD,
+ 'headers': {},
+ # An empty body is represented as an empty byte string.
+ 'body': b'',
+ }
+ return serialized
+
+ # Some extra utility methods subclasses can use.
+
+ def _timestamp_iso8601(self, value):
+ if value.microsecond > 0:
+ timestamp_format = ISO8601_MICRO
+ else:
+ timestamp_format = ISO8601
+ return value.strftime(timestamp_format)
+
+ def _timestamp_unixtimestamp(self, value):
+ return int(calendar.timegm(value.timetuple()))
+
+ def _timestamp_rfc822(self, value):
+ if isinstance(value, datetime.datetime):
+ value = self._timestamp_unixtimestamp(value)
+ return formatdate(value, usegmt=True)
+
+ def _convert_timestamp_to_str(self, value, timestamp_format=None):
+ if timestamp_format is None:
+ timestamp_format = self.TIMESTAMP_FORMAT
+ timestamp_format = timestamp_format.lower()
+ datetime_obj = parse_to_aware_datetime(value)
+ converter = getattr(self, f'_timestamp_{timestamp_format}')
+ final_value = converter(datetime_obj)
+ return final_value
+
+ def _get_serialized_name(self, shape, default_name):
+ # Returns the serialized name for the shape if it exists.
+ # Otherwise it will return the passed in default_name.
+ return shape.serialization.get('name', default_name)
+
+ def _get_base64(self, value):
+ # Returns the base64-encoded version of value, handling
+ # both strings and bytes. The returned value is a string
+ # via the default encoding.
+ if isinstance(value, str):
+ value = value.encode(self.DEFAULT_ENCODING)
+ return base64.b64encode(value).strip().decode(self.DEFAULT_ENCODING)
+
+ def _expand_host_prefix(self, parameters, operation_model):
+ operation_endpoint = operation_model.endpoint
+ if (
+ operation_endpoint is None
+ or 'hostPrefix' not in operation_endpoint
+ ):
+ return None
+
+ host_prefix_expression = operation_endpoint['hostPrefix']
+ input_members = operation_model.input_shape.members
+ host_labels = [
+ member
+ for member, shape in input_members.items()
+ if shape.serialization.get('hostLabel')
+ ]
+ format_kwargs = {}
+ bad_labels = []
+ for name in host_labels:
+ param = parameters[name]
+ if not HOST_PREFIX_RE.match(param):
+ bad_labels.append(name)
+ format_kwargs[name] = param
+ if bad_labels:
+ raise ParamValidationError(
+ report=(
+ f"Invalid value for parameter(s): {', '.join(bad_labels)}. "
+ "Must contain only alphanumeric characters, hyphen, "
+ "or period."
+ )
+ )
+ return host_prefix_expression.format(**format_kwargs)
+
+
+class QuerySerializer(Serializer):
+ TIMESTAMP_FORMAT = 'iso8601'
+
+ def serialize_to_request(self, parameters, operation_model):
+ shape = operation_model.input_shape
+ serialized = self._create_default_request()
+ serialized['method'] = operation_model.http.get(
+ 'method', self.DEFAULT_METHOD
+ )
+ serialized['headers'] = {
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
+ }
+ # The query serializer only deals with body params so
+ # that's what we hand off the _serialize_* methods.
+ body_params = self.MAP_TYPE()
+ body_params['Action'] = operation_model.name
+ body_params['Version'] = operation_model.metadata['apiVersion']
+ if shape is not None:
+ self._serialize(body_params, parameters, shape)
+ serialized['body'] = body_params
+
+ host_prefix = self._expand_host_prefix(parameters, operation_model)
+ if host_prefix is not None:
+ serialized['host_prefix'] = host_prefix
+
+ return serialized
+
+ def _serialize(self, serialized, value, shape, prefix=''):
+ # serialized: The dict that is incrementally added to with the
+ # final serialized parameters.
+ # value: The current user input value.
+ # shape: The shape object that describes the structure of the
+ # input.
+ # prefix: The incrementally built up prefix for the serialized
+ # key (i.e Foo.bar.members.1).
+ method = getattr(
+ self,
+ f'_serialize_type_{shape.type_name}',
+ self._default_serialize,
+ )
+ method(serialized, value, shape, prefix=prefix)
+
+ def _serialize_type_structure(self, serialized, value, shape, prefix=''):
+ members = shape.members
+ for key, value in value.items():
+ member_shape = members[key]
+ member_prefix = self._get_serialized_name(member_shape, key)
+ if prefix:
+ member_prefix = f'{prefix}.{member_prefix}'
+ self._serialize(serialized, value, member_shape, member_prefix)
+
+ def _serialize_type_list(self, serialized, value, shape, prefix=''):
+ if not value:
+ # The query protocol serializes empty lists.
+ serialized[prefix] = ''
+ return
+ if self._is_shape_flattened(shape):
+ list_prefix = prefix
+ if shape.member.serialization.get('name'):
+ name = self._get_serialized_name(shape.member, default_name='')
+ # Replace '.Original' with '.{name}'.
+ list_prefix = '.'.join(prefix.split('.')[:-1] + [name])
+ else:
+ list_name = shape.member.serialization.get('name', 'member')
+ list_prefix = f'{prefix}.{list_name}'
+ for i, element in enumerate(value, 1):
+ element_prefix = f'{list_prefix}.{i}'
+ element_shape = shape.member
+ self._serialize(serialized, element, element_shape, element_prefix)
+
+ def _serialize_type_map(self, serialized, value, shape, prefix=''):
+ if self._is_shape_flattened(shape):
+ full_prefix = prefix
+ else:
+ full_prefix = '%s.entry' % prefix
+ template = full_prefix + '.{i}.{suffix}'
+ key_shape = shape.key
+ value_shape = shape.value
+ key_suffix = self._get_serialized_name(key_shape, default_name='key')
+ value_suffix = self._get_serialized_name(value_shape, 'value')
+ for i, key in enumerate(value, 1):
+ key_prefix = template.format(i=i, suffix=key_suffix)
+ value_prefix = template.format(i=i, suffix=value_suffix)
+ self._serialize(serialized, key, key_shape, key_prefix)
+ self._serialize(serialized, value[key], value_shape, value_prefix)
+
+ def _serialize_type_blob(self, serialized, value, shape, prefix=''):
+ # Blob args must be base64 encoded.
+ serialized[prefix] = self._get_base64(value)
+
+ def _serialize_type_timestamp(self, serialized, value, shape, prefix=''):
+ serialized[prefix] = self._convert_timestamp_to_str(
+ value, shape.serialization.get('timestampFormat')
+ )
+
+ def _serialize_type_boolean(self, serialized, value, shape, prefix=''):
+ if value:
+ serialized[prefix] = 'true'
+ else:
+ serialized[prefix] = 'false'
+
+ def _default_serialize(self, serialized, value, shape, prefix=''):
+ serialized[prefix] = value
+
+ def _is_shape_flattened(self, shape):
+ return shape.serialization.get('flattened')
+
+
+class EC2Serializer(QuerySerializer):
+ """EC2 specific customizations to the query protocol serializers.
+
+ The EC2 model is almost, but not exactly, similar to the query protocol
+ serializer. This class encapsulates those differences. The model
+ will have be marked with a ``protocol`` of ``ec2``, so you don't need
+ to worry about wiring this class up correctly.
+
+ """
+
+ def _get_serialized_name(self, shape, default_name):
+ # Returns the serialized name for the shape if it exists.
+ # Otherwise it will return the passed in default_name.
+ if 'queryName' in shape.serialization:
+ return shape.serialization['queryName']
+ elif 'name' in shape.serialization:
+ # A locationName is always capitalized
+ # on input for the ec2 protocol.
+ name = shape.serialization['name']
+ return name[0].upper() + name[1:]
+ else:
+ return default_name
+
+ def _serialize_type_list(self, serialized, value, shape, prefix=''):
+ for i, element in enumerate(value, 1):
+ element_prefix = f'{prefix}.{i}'
+ element_shape = shape.member
+ self._serialize(serialized, element, element_shape, element_prefix)
+
+
+class JSONSerializer(Serializer):
+ TIMESTAMP_FORMAT = 'unixtimestamp'
+
+ def serialize_to_request(self, parameters, operation_model):
+ target = '{}.{}'.format(
+ operation_model.metadata['targetPrefix'],
+ operation_model.name,
+ )
+ json_version = operation_model.metadata['jsonVersion']
+ serialized = self._create_default_request()
+ serialized['method'] = operation_model.http.get(
+ 'method', self.DEFAULT_METHOD
+ )
+ serialized['headers'] = {
+ 'X-Amz-Target': target,
+ 'Content-Type': 'application/x-amz-json-%s' % json_version,
+ }
+ body = self.MAP_TYPE()
+ input_shape = operation_model.input_shape
+ if input_shape is not None:
+ self._serialize(body, parameters, input_shape)
+ serialized['body'] = json.dumps(body).encode(self.DEFAULT_ENCODING)
+
+ host_prefix = self._expand_host_prefix(parameters, operation_model)
+ if host_prefix is not None:
+ serialized['host_prefix'] = host_prefix
+
+ return serialized
+
+ def _serialize(self, serialized, value, shape, key=None):
+ method = getattr(
+ self,
+ '_serialize_type_%s' % shape.type_name,
+ self._default_serialize,
+ )
+ method(serialized, value, shape, key)
+
+ def _serialize_type_structure(self, serialized, value, shape, key):
+ if shape.is_document_type:
+ serialized[key] = value
+ else:
+ if key is not None:
+ # If a key is provided, this is a result of a recursive
+ # call so we need to add a new child dict as the value
+ # of the passed in serialized dict. We'll then add
+ # all the structure members as key/vals in the new serialized
+ # dictionary we just created.
+ new_serialized = self.MAP_TYPE()
+ serialized[key] = new_serialized
+ serialized = new_serialized
+ members = shape.members
+ for member_key, member_value in value.items():
+ member_shape = members[member_key]
+ if 'name' in member_shape.serialization:
+ member_key = member_shape.serialization['name']
+ self._serialize(
+ serialized, member_value, member_shape, member_key
+ )
+
+ def _serialize_type_map(self, serialized, value, shape, key):
+ map_obj = self.MAP_TYPE()
+ serialized[key] = map_obj
+ for sub_key, sub_value in value.items():
+ self._serialize(map_obj, sub_value, shape.value, sub_key)
+
+ def _serialize_type_list(self, serialized, value, shape, key):
+ list_obj = []
+ serialized[key] = list_obj
+ for list_item in value:
+ wrapper = {}
+ # The JSON list serialization is the only case where we aren't
+ # setting a key on a dict. We handle this by using
+ # a __current__ key on a wrapper dict to serialize each
+ # list item before appending it to the serialized list.
+ self._serialize(wrapper, list_item, shape.member, "__current__")
+ list_obj.append(wrapper["__current__"])
+
+ def _default_serialize(self, serialized, value, shape, key):
+ serialized[key] = value
+
+ def _serialize_type_timestamp(self, serialized, value, shape, key):
+ serialized[key] = self._convert_timestamp_to_str(
+ value, shape.serialization.get('timestampFormat')
+ )
+
+ def _serialize_type_blob(self, serialized, value, shape, key):
+ serialized[key] = self._get_base64(value)
+
+
+class BaseRestSerializer(Serializer):
+ """Base class for rest protocols.
+
+ The only variance between the various rest protocols is the
+ way that the body is serialized. All other aspects (headers, uri, etc.)
+ are the same and logic for serializing those aspects lives here.
+
+ Subclasses must implement the ``_serialize_body_params`` method.
+
+ """
+
+ QUERY_STRING_TIMESTAMP_FORMAT = 'iso8601'
+ HEADER_TIMESTAMP_FORMAT = 'rfc822'
+ # This is a list of known values for the "location" key in the
+ # serialization dict. The location key tells us where on the request
+ # to put the serialized value.
+ KNOWN_LOCATIONS = ['uri', 'querystring', 'header', 'headers']
+
+ def serialize_to_request(self, parameters, operation_model):
+ serialized = self._create_default_request()
+ serialized['method'] = operation_model.http.get(
+ 'method', self.DEFAULT_METHOD
+ )
+ shape = operation_model.input_shape
+ if shape is None:
+ serialized['url_path'] = operation_model.http['requestUri']
+ return serialized
+ shape_members = shape.members
+ # While the ``serialized`` key holds the final serialized request
+ # data, we need interim dicts for the various locations of the
+ # request. We need this for the uri_path_kwargs and the
+ # query_string_kwargs because they are templated, so we need
+ # to gather all the needed data for the string template,
+ # then we render the template. The body_kwargs is needed
+ # because once we've collected them all, we run them through
+ # _serialize_body_params, which for rest-json, creates JSON,
+ # and for rest-xml, will create XML. This is what the
+ # ``partitioned`` dict below is for.
+ partitioned = {
+ 'uri_path_kwargs': self.MAP_TYPE(),
+ 'query_string_kwargs': self.MAP_TYPE(),
+ 'body_kwargs': self.MAP_TYPE(),
+ 'headers': self.MAP_TYPE(),
+ }
+ for param_name, param_value in parameters.items():
+ if param_value is None:
+ # Don't serialize any parameter with a None value.
+ continue
+ self._partition_parameters(
+ partitioned, param_name, param_value, shape_members
+ )
+ serialized['url_path'] = self._render_uri_template(
+ operation_model.http['requestUri'], partitioned['uri_path_kwargs']
+ )
+
+ if 'authPath' in operation_model.http:
+ serialized['auth_path'] = self._render_uri_template(
+ operation_model.http['authPath'],
+ partitioned['uri_path_kwargs'],
+ )
+ # Note that we lean on the http implementation to handle the case
+ # where the requestUri path already has query parameters.
+ # The bundled http client, requests, already supports this.
+ serialized['query_string'] = partitioned['query_string_kwargs']
+ if partitioned['headers']:
+ serialized['headers'] = partitioned['headers']
+ self._serialize_payload(
+ partitioned, parameters, serialized, shape, shape_members
+ )
+ self._serialize_content_type(serialized, shape, shape_members)
+
+ host_prefix = self._expand_host_prefix(parameters, operation_model)
+ if host_prefix is not None:
+ serialized['host_prefix'] = host_prefix
+
+ return serialized
+
+ def _render_uri_template(self, uri_template, params):
+ # We need to handle two cases::
+ #
+ # /{Bucket}/foo
+ # /{Key+}/bar
+ # A label ending with '+' is greedy. There can only
+ # be one greedy key.
+ encoded_params = {}
+ for template_param in re.findall(r'{(.*?)}', uri_template):
+ if template_param.endswith('+'):
+ encoded_params[template_param] = percent_encode(
+ params[template_param[:-1]], safe='/~'
+ )
+ else:
+ encoded_params[template_param] = percent_encode(
+ params[template_param]
+ )
+ return uri_template.format(**encoded_params)
+
+ def _serialize_payload(
+ self, partitioned, parameters, serialized, shape, shape_members
+ ):
+ # partitioned - The user input params partitioned by location.
+ # parameters - The user input params.
+ # serialized - The final serialized request dict.
+ # shape - Describes the expected input shape
+ # shape_members - The members of the input struct shape
+ payload_member = shape.serialization.get('payload')
+ if self._has_streaming_payload(payload_member, shape_members):
+ # If it's streaming, then the body is just the
+ # value of the payload.
+ body_payload = parameters.get(payload_member, b'')
+ body_payload = self._encode_payload(body_payload)
+ serialized['body'] = body_payload
+ elif payload_member is not None:
+ # If there's a payload member, we serialized that
+ # member to they body.
+ body_params = parameters.get(payload_member)
+ if body_params is not None:
+ serialized['body'] = self._serialize_body_params(
+ body_params, shape_members[payload_member]
+ )
+ else:
+ serialized['body'] = self._serialize_empty_body()
+ elif partitioned['body_kwargs']:
+ serialized['body'] = self._serialize_body_params(
+ partitioned['body_kwargs'], shape
+ )
+ elif self._requires_empty_body(shape):
+ serialized['body'] = self._serialize_empty_body()
+
+ def _serialize_empty_body(self):
+ return b''
+
+ def _serialize_content_type(self, serialized, shape, shape_members):
+ """
+ Some protocols require varied Content-Type headers
+ depending on user input. This allows subclasses to apply
+ this conditionally.
+ """
+ pass
+
+ def _requires_empty_body(self, shape):
+ """
+ Some protocols require a specific body to represent an empty
+ payload. This allows subclasses to apply this conditionally.
+ """
+ return False
+
+ def _has_streaming_payload(self, payload, shape_members):
+ """Determine if payload is streaming (a blob or string)."""
+ return payload is not None and shape_members[payload].type_name in (
+ 'blob',
+ 'string',
+ )
+
+ def _encode_payload(self, body):
+ if isinstance(body, str):
+ return body.encode(self.DEFAULT_ENCODING)
+ return body
+
+ def _partition_parameters(
+ self, partitioned, param_name, param_value, shape_members
+ ):
+ # This takes the user provided input parameter (``param``)
+ # and figures out where they go in the request dict.
+ # Some params are HTTP headers, some are used in the URI, some
+ # are in the request body. This method deals with this.
+ member = shape_members[param_name]
+ location = member.serialization.get('location')
+ key_name = member.serialization.get('name', param_name)
+ if location == 'uri':
+ partitioned['uri_path_kwargs'][key_name] = param_value
+ elif location == 'querystring':
+ if isinstance(param_value, dict):
+ partitioned['query_string_kwargs'].update(param_value)
+ elif isinstance(param_value, bool):
+ bool_str = str(param_value).lower()
+ partitioned['query_string_kwargs'][key_name] = bool_str
+ elif member.type_name == 'timestamp':
+ timestamp_format = member.serialization.get(
+ 'timestampFormat', self.QUERY_STRING_TIMESTAMP_FORMAT
+ )
+ timestamp = self._convert_timestamp_to_str(
+ param_value, timestamp_format
+ )
+ partitioned['query_string_kwargs'][key_name] = timestamp
+ else:
+ partitioned['query_string_kwargs'][key_name] = param_value
+ elif location == 'header':
+ shape = shape_members[param_name]
+ if not param_value and shape.type_name == 'list':
+ # Empty lists should not be set on the headers
+ return
+ value = self._convert_header_value(shape, param_value)
+ partitioned['headers'][key_name] = str(value)
+ elif location == 'headers':
+ # 'headers' is a bit of an oddball. The ``key_name``
+ # is actually really a prefix for the header names:
+ header_prefix = key_name
+ # The value provided by the user is a dict so we'll be
+ # creating multiple header key/val pairs. The key
+ # name to use for each header is the header_prefix (``key_name``)
+ # plus the key provided by the user.
+ self._do_serialize_header_map(
+ header_prefix, partitioned['headers'], param_value
+ )
+ else:
+ partitioned['body_kwargs'][param_name] = param_value
+
+ def _do_serialize_header_map(self, header_prefix, headers, user_input):
+ for key, val in user_input.items():
+ full_key = header_prefix + key
+ headers[full_key] = val
+
+ def _serialize_body_params(self, params, shape):
+ raise NotImplementedError('_serialize_body_params')
+
+ def _convert_header_value(self, shape, value):
+ if shape.type_name == 'timestamp':
+ datetime_obj = parse_to_aware_datetime(value)
+ timestamp = calendar.timegm(datetime_obj.utctimetuple())
+ timestamp_format = shape.serialization.get(
+ 'timestampFormat', self.HEADER_TIMESTAMP_FORMAT
+ )
+ return self._convert_timestamp_to_str(timestamp, timestamp_format)
+ elif shape.type_name == 'list':
+ converted_value = [
+ self._convert_header_value(shape.member, v)
+ for v in value
+ if v is not None
+ ]
+ return ",".join(converted_value)
+ elif is_json_value_header(shape):
+ # Serialize with no spaces after separators to save space in
+ # the header.
+ return self._get_base64(json.dumps(value, separators=(',', ':')))
+ else:
+ return value
+
+
+class RestJSONSerializer(BaseRestSerializer, JSONSerializer):
+ def _serialize_empty_body(self):
+ return b'{}'
+
+ def _requires_empty_body(self, shape):
+ """
+ Serialize an empty JSON object whenever the shape has
+ members not targeting a location.
+ """
+ for member, val in shape.members.items():
+ if 'location' not in val.serialization:
+ return True
+ return False
+
+ def _serialize_content_type(self, serialized, shape, shape_members):
+ """Set Content-Type to application/json for all structured bodies."""
+ payload = shape.serialization.get('payload')
+ if self._has_streaming_payload(payload, shape_members):
+ # Don't apply content-type to streaming bodies
+ return
+
+ has_body = serialized['body'] != b''
+ has_content_type = has_header('Content-Type', serialized['headers'])
+ if has_body and not has_content_type:
+ serialized['headers']['Content-Type'] = 'application/json'
+
+ def _serialize_body_params(self, params, shape):
+ serialized_body = self.MAP_TYPE()
+ self._serialize(serialized_body, params, shape)
+ return json.dumps(serialized_body).encode(self.DEFAULT_ENCODING)
+
+
+class RestXMLSerializer(BaseRestSerializer):
+ TIMESTAMP_FORMAT = 'iso8601'
+
+ def _serialize_body_params(self, params, shape):
+ root_name = shape.serialization['name']
+ pseudo_root = ElementTree.Element('')
+ self._serialize(shape, params, pseudo_root, root_name)
+ real_root = list(pseudo_root)[0]
+ return ElementTree.tostring(real_root, encoding=self.DEFAULT_ENCODING)
+
+ def _serialize(self, shape, params, xmlnode, name):
+ method = getattr(
+ self,
+ '_serialize_type_%s' % shape.type_name,
+ self._default_serialize,
+ )
+ method(xmlnode, params, shape, name)
+
+ def _serialize_type_structure(self, xmlnode, params, shape, name):
+ structure_node = ElementTree.SubElement(xmlnode, name)
+
+ if 'xmlNamespace' in shape.serialization:
+ namespace_metadata = shape.serialization['xmlNamespace']
+ attribute_name = 'xmlns'
+ if namespace_metadata.get('prefix'):
+ attribute_name += ':%s' % namespace_metadata['prefix']
+ structure_node.attrib[attribute_name] = namespace_metadata['uri']
+ for key, value in params.items():
+ member_shape = shape.members[key]
+ member_name = member_shape.serialization.get('name', key)
+ # We need to special case member shapes that are marked as an
+ # xmlAttribute. Rather than serializing into an XML child node,
+ # we instead serialize the shape to an XML attribute of the
+ # *current* node.
+ if value is None:
+ # Don't serialize any param whose value is None.
+ return
+ if member_shape.serialization.get('xmlAttribute'):
+ # xmlAttributes must have a serialization name.
+ xml_attribute_name = member_shape.serialization['name']
+ structure_node.attrib[xml_attribute_name] = value
+ continue
+ self._serialize(member_shape, value, structure_node, member_name)
+
+ def _serialize_type_list(self, xmlnode, params, shape, name):
+ member_shape = shape.member
+ if shape.serialization.get('flattened'):
+ element_name = name
+ list_node = xmlnode
+ else:
+ element_name = member_shape.serialization.get('name', 'member')
+ list_node = ElementTree.SubElement(xmlnode, name)
+ for item in params:
+ self._serialize(member_shape, item, list_node, element_name)
+
+ def _serialize_type_map(self, xmlnode, params, shape, name):
+ # Given the ``name`` of MyMap, and input of {"key1": "val1"}
+ # we serialize this as:
+ #
+ #
+ # key1
+ # val1
+ #
+ #
+ node = ElementTree.SubElement(xmlnode, name)
+ # TODO: handle flattened maps.
+ for key, value in params.items():
+ entry_node = ElementTree.SubElement(node, 'entry')
+ key_name = self._get_serialized_name(shape.key, default_name='key')
+ val_name = self._get_serialized_name(
+ shape.value, default_name='value'
+ )
+ self._serialize(shape.key, key, entry_node, key_name)
+ self._serialize(shape.value, value, entry_node, val_name)
+
+ def _serialize_type_boolean(self, xmlnode, params, shape, name):
+ # For scalar types, the 'params' attr is actually just a scalar
+ # value representing the data we need to serialize as a boolean.
+ # It will either be 'true' or 'false'
+ node = ElementTree.SubElement(xmlnode, name)
+ if params:
+ str_value = 'true'
+ else:
+ str_value = 'false'
+ node.text = str_value
+
+ def _serialize_type_blob(self, xmlnode, params, shape, name):
+ node = ElementTree.SubElement(xmlnode, name)
+ node.text = self._get_base64(params)
+
+ def _serialize_type_timestamp(self, xmlnode, params, shape, name):
+ node = ElementTree.SubElement(xmlnode, name)
+ node.text = self._convert_timestamp_to_str(
+ params, shape.serialization.get('timestampFormat')
+ )
+
+ def _default_serialize(self, xmlnode, params, shape, name):
+ node = ElementTree.SubElement(xmlnode, name)
+ node.text = str(params)
+
+
+SERIALIZERS = {
+ 'ec2': EC2Serializer,
+ 'query': QuerySerializer,
+ 'json': JSONSerializer,
+ 'rest-json': RestJSONSerializer,
+ 'rest-xml': RestXMLSerializer,
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/session.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/session.py
new file mode 100644
index 0000000000..0739286ec6
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/session.py
@@ -0,0 +1,1269 @@
+# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""
+This module contains the main interface to the botocore package, the
+Session object.
+"""
+
+import copy
+import logging
+import os
+import platform
+import socket
+import warnings
+
+import botocore.client
+import botocore.configloader
+import botocore.credentials
+import botocore.tokens
+from botocore import (
+ UNSIGNED,
+ __version__,
+ handlers,
+ invoke_initializers,
+ monitoring,
+ paginate,
+ retryhandler,
+ translate,
+ waiter,
+)
+from botocore.compat import HAS_CRT, MutableMapping
+from botocore.configprovider import (
+ BOTOCORE_DEFAUT_SESSION_VARIABLES,
+ ConfigChainFactory,
+ ConfiguredEndpointProvider,
+ ConfigValueStore,
+ DefaultConfigResolver,
+ SmartDefaultsConfigStoreFactory,
+ create_botocore_default_config_mapping,
+)
+from botocore.errorfactory import ClientExceptionsFactory
+from botocore.exceptions import (
+ ConfigNotFound,
+ InvalidDefaultsMode,
+ PartialCredentialsError,
+ ProfileNotFound,
+ UnknownServiceError,
+)
+from botocore.hooks import (
+ EventAliaser,
+ HierarchicalEmitter,
+ first_non_none_response,
+)
+from botocore.loaders import create_loader
+from botocore.model import ServiceModel
+from botocore.parsers import ResponseParserFactory
+from botocore.regions import EndpointResolver
+from botocore.useragent import UserAgentString
+from botocore.utils import (
+ EVENT_ALIASES,
+ IMDSRegionProvider,
+ validate_region_name,
+)
+
+from botocore.compat import HAS_CRT # noqa
+
+
+logger = logging.getLogger(__name__)
+
+
+class Session:
+ """
+ The Session object collects together useful functionality
+ from `botocore` as well as important data such as configuration
+ information and credentials into a single, easy-to-use object.
+
+ :ivar available_profiles: A list of profiles defined in the config
+ file associated with this session.
+ :ivar profile: The current profile.
+ """
+
+ SESSION_VARIABLES = copy.copy(BOTOCORE_DEFAUT_SESSION_VARIABLES)
+
+ #: The default format string to use when configuring the botocore logger.
+ LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
+
+ def __init__(
+ self,
+ session_vars=None,
+ event_hooks=None,
+ include_builtin_handlers=True,
+ profile=None,
+ ):
+ """
+ Create a new Session object.
+
+ :type session_vars: dict
+ :param session_vars: A dictionary that is used to override some or all
+ of the environment variables associated with this session. The
+ key/value pairs defined in this dictionary will override the
+ corresponding variables defined in ``SESSION_VARIABLES``.
+
+ :type event_hooks: BaseEventHooks
+ :param event_hooks: The event hooks object to use. If one is not
+ provided, an event hooks object will be automatically created
+ for you.
+
+ :type include_builtin_handlers: bool
+ :param include_builtin_handlers: Indicates whether or not to
+ automatically register builtin handlers.
+
+ :type profile: str
+ :param profile: The name of the profile to use for this
+ session. Note that the profile can only be set when
+ the session is created.
+
+ """
+ if event_hooks is None:
+ self._original_handler = HierarchicalEmitter()
+ else:
+ self._original_handler = event_hooks
+ self._events = EventAliaser(self._original_handler)
+ if include_builtin_handlers:
+ self._register_builtin_handlers(self._events)
+ self.user_agent_name = 'Botocore'
+ self.user_agent_version = __version__
+ self.user_agent_extra = ''
+ # The _profile attribute is just used to cache the value
+ # of the current profile to avoid going through the normal
+ # config lookup process each access time.
+ self._profile = None
+ self._config = None
+ self._credentials = None
+ self._auth_token = None
+ self._profile_map = None
+ # This is a dict that stores per session specific config variable
+ # overrides via set_config_variable().
+ self._session_instance_vars = {}
+ if profile is not None:
+ self._session_instance_vars['profile'] = profile
+ self._client_config = None
+ self._last_client_region_used = None
+ self._components = ComponentLocator()
+ self._internal_components = ComponentLocator()
+ self._register_components()
+ self.session_var_map = SessionVarDict(self, self.SESSION_VARIABLES)
+ if session_vars is not None:
+ self.session_var_map.update(session_vars)
+ invoke_initializers(self)
+
+ def _register_components(self):
+ self._register_credential_provider()
+ self._register_token_provider()
+ self._register_data_loader()
+ self._register_endpoint_resolver()
+ self._register_event_emitter()
+ self._register_response_parser_factory()
+ self._register_exceptions_factory()
+ self._register_config_store()
+ self._register_monitor()
+ self._register_default_config_resolver()
+ self._register_smart_defaults_factory()
+ self._register_user_agent_creator()
+
+ def _register_event_emitter(self):
+ self._components.register_component('event_emitter', self._events)
+
+ def _register_token_provider(self):
+ self._components.lazy_register_component(
+ 'token_provider', self._create_token_resolver
+ )
+
+ def _create_token_resolver(self):
+ return botocore.tokens.create_token_resolver(self)
+
+ def _register_credential_provider(self):
+ self._components.lazy_register_component(
+ 'credential_provider', self._create_credential_resolver
+ )
+
+ def _create_credential_resolver(self):
+ return botocore.credentials.create_credential_resolver(
+ self, region_name=self._last_client_region_used
+ )
+
+ def _register_data_loader(self):
+ self._components.lazy_register_component(
+ 'data_loader',
+ lambda: create_loader(self.get_config_variable('data_path')),
+ )
+
+ def _register_endpoint_resolver(self):
+ def create_default_resolver():
+ loader = self.get_component('data_loader')
+ endpoints, path = loader.load_data_with_path('endpoints')
+ uses_builtin = loader.is_builtin_path(path)
+ return EndpointResolver(endpoints, uses_builtin_data=uses_builtin)
+
+ self._internal_components.lazy_register_component(
+ 'endpoint_resolver', create_default_resolver
+ )
+
+ def _register_default_config_resolver(self):
+ def create_default_config_resolver():
+ loader = self.get_component('data_loader')
+ defaults = loader.load_data('sdk-default-configuration')
+ return DefaultConfigResolver(defaults)
+
+ self._internal_components.lazy_register_component(
+ 'default_config_resolver', create_default_config_resolver
+ )
+
+ def _register_smart_defaults_factory(self):
+ def create_smart_defaults_factory():
+ default_config_resolver = self._get_internal_component(
+ 'default_config_resolver'
+ )
+ imds_region_provider = IMDSRegionProvider(session=self)
+ return SmartDefaultsConfigStoreFactory(
+ default_config_resolver, imds_region_provider
+ )
+
+ self._internal_components.lazy_register_component(
+ 'smart_defaults_factory', create_smart_defaults_factory
+ )
+
+ def _register_response_parser_factory(self):
+ self._components.register_component(
+ 'response_parser_factory', ResponseParserFactory()
+ )
+
+ def _register_exceptions_factory(self):
+ self._internal_components.register_component(
+ 'exceptions_factory', ClientExceptionsFactory()
+ )
+
+ def _register_builtin_handlers(self, events):
+ for spec in handlers.BUILTIN_HANDLERS:
+ if len(spec) == 2:
+ event_name, handler = spec
+ self.register(event_name, handler)
+ else:
+ event_name, handler, register_type = spec
+ if register_type is handlers.REGISTER_FIRST:
+ self._events.register_first(event_name, handler)
+ elif register_type is handlers.REGISTER_LAST:
+ self._events.register_last(event_name, handler)
+
+ def _register_config_store(self):
+ config_store_component = ConfigValueStore(
+ mapping=create_botocore_default_config_mapping(self)
+ )
+ self._components.register_component(
+ 'config_store', config_store_component
+ )
+
+ def _register_monitor(self):
+ self._internal_components.lazy_register_component(
+ 'monitor', self._create_csm_monitor
+ )
+
+ def _register_user_agent_creator(self):
+ uas = UserAgentString.from_environment()
+ self._components.register_component('user_agent_creator', uas)
+
+ def _create_csm_monitor(self):
+ if self.get_config_variable('csm_enabled'):
+ client_id = self.get_config_variable('csm_client_id')
+ host = self.get_config_variable('csm_host')
+ port = self.get_config_variable('csm_port')
+ handler = monitoring.Monitor(
+ adapter=monitoring.MonitorEventAdapter(),
+ publisher=monitoring.SocketPublisher(
+ socket=socket.socket(socket.AF_INET, socket.SOCK_DGRAM),
+ host=host,
+ port=port,
+ serializer=monitoring.CSMSerializer(
+ csm_client_id=client_id
+ ),
+ ),
+ )
+ return handler
+ return None
+
+ def _get_crt_version(self):
+ user_agent_creator = self.get_component('user_agent_creator')
+ return user_agent_creator._crt_version or 'Unknown'
+
+ @property
+ def available_profiles(self):
+ return list(self._build_profile_map().keys())
+
+ def _build_profile_map(self):
+ # This will build the profile map if it has not been created,
+ # otherwise it will return the cached value. The profile map
+ # is a list of profile names, to the config values for the profile.
+ if self._profile_map is None:
+ self._profile_map = self.full_config['profiles']
+ return self._profile_map
+
+ @property
+ def profile(self):
+ if self._profile is None:
+ profile = self.get_config_variable('profile')
+ self._profile = profile
+ return self._profile
+
+ def get_config_variable(self, logical_name, methods=None):
+ if methods is not None:
+ return self._get_config_variable_with_custom_methods(
+ logical_name, methods
+ )
+ return self.get_component('config_store').get_config_variable(
+ logical_name
+ )
+
+ def _get_config_variable_with_custom_methods(self, logical_name, methods):
+ # If a custom list of methods was supplied we need to perserve the
+ # behavior with the new system. To do so a new chain that is a copy of
+ # the old one will be constructed, but only with the supplied methods
+ # being added to the chain. This chain will be consulted for a value
+ # and then thrown out. This is not efficient, nor is the methods arg
+ # used in botocore, this is just for backwards compatibility.
+ chain_builder = SubsetChainConfigFactory(session=self, methods=methods)
+ mapping = create_botocore_default_config_mapping(self)
+ for name, config_options in self.session_var_map.items():
+ config_name, env_vars, default, typecast = config_options
+ build_chain_config_args = {
+ 'conversion_func': typecast,
+ 'default': default,
+ }
+ if 'instance' in methods:
+ build_chain_config_args['instance_name'] = name
+ if 'env' in methods:
+ build_chain_config_args['env_var_names'] = env_vars
+ if 'config' in methods:
+ build_chain_config_args['config_property_name'] = config_name
+ mapping[name] = chain_builder.create_config_chain(
+ **build_chain_config_args
+ )
+ config_store_component = ConfigValueStore(mapping=mapping)
+ value = config_store_component.get_config_variable(logical_name)
+ return value
+
+ def set_config_variable(self, logical_name, value):
+ """Set a configuration variable to a specific value.
+
+ By using this method, you can override the normal lookup
+ process used in ``get_config_variable`` by explicitly setting
+ a value. Subsequent calls to ``get_config_variable`` will
+ use the ``value``. This gives you per-session specific
+ configuration values.
+
+ ::
+ >>> # Assume logical name 'foo' maps to env var 'FOO'
+ >>> os.environ['FOO'] = 'myvalue'
+ >>> s.get_config_variable('foo')
+ 'myvalue'
+ >>> s.set_config_variable('foo', 'othervalue')
+ >>> s.get_config_variable('foo')
+ 'othervalue'
+
+ :type logical_name: str
+ :param logical_name: The logical name of the session variable
+ you want to set. These are the keys in ``SESSION_VARIABLES``.
+ :param value: The value to associate with the config variable.
+
+ """
+ logger.debug(
+ "Setting config variable for %s to %r",
+ logical_name,
+ value,
+ )
+ self._session_instance_vars[logical_name] = value
+
+ def instance_variables(self):
+ return copy.copy(self._session_instance_vars)
+
+ def get_scoped_config(self):
+ """
+ Returns the config values from the config file scoped to the current
+ profile.
+
+ The configuration data is loaded **only** from the config file.
+ It does not resolve variables based on different locations
+ (e.g. first from the session instance, then from environment
+ variables, then from the config file). If you want this lookup
+ behavior, use the ``get_config_variable`` method instead.
+
+ Note that this configuration is specific to a single profile (the
+ ``profile`` session variable).
+
+ If the ``profile`` session variable is set and the profile does
+ not exist in the config file, a ``ProfileNotFound`` exception
+ will be raised.
+
+ :raises: ConfigNotFound, ConfigParseError, ProfileNotFound
+ :rtype: dict
+
+ """
+ profile_name = self.get_config_variable('profile')
+ profile_map = self._build_profile_map()
+ # If a profile is not explicitly set return the default
+ # profile config or an empty config dict if we don't have
+ # a default profile.
+ if profile_name is None:
+ return profile_map.get('default', {})
+ elif profile_name not in profile_map:
+ # Otherwise if they specified a profile, it has to
+ # exist (even if it's the default profile) otherwise
+ # we complain.
+ raise ProfileNotFound(profile=profile_name)
+ else:
+ return profile_map[profile_name]
+
+ @property
+ def full_config(self):
+ """Return the parsed config file.
+
+ The ``get_config`` method returns the config associated with the
+ specified profile. This property returns the contents of the
+ **entire** config file.
+
+ :rtype: dict
+ """
+ if self._config is None:
+ try:
+ config_file = self.get_config_variable('config_file')
+ self._config = botocore.configloader.load_config(config_file)
+ except ConfigNotFound:
+ self._config = {'profiles': {}}
+ try:
+ # Now we need to inject the profiles from the
+ # credentials file. We don't actually need the values
+ # in the creds file, only the profile names so that we
+ # can validate the user is not referring to a nonexistent
+ # profile.
+ cred_file = self.get_config_variable('credentials_file')
+ cred_profiles = botocore.configloader.raw_config_parse(
+ cred_file
+ )
+ for profile in cred_profiles:
+ cred_vars = cred_profiles[profile]
+ if profile not in self._config['profiles']:
+ self._config['profiles'][profile] = cred_vars
+ else:
+ self._config['profiles'][profile].update(cred_vars)
+ except ConfigNotFound:
+ pass
+ return self._config
+
+ def get_default_client_config(self):
+ """Retrieves the default config for creating clients
+
+ :rtype: botocore.client.Config
+ :returns: The default client config object when creating clients. If
+ the value is ``None`` then there is no default config object
+ attached to the session.
+ """
+ return self._client_config
+
+ def set_default_client_config(self, client_config):
+ """Sets the default config for creating clients
+
+ :type client_config: botocore.client.Config
+ :param client_config: The default client config object when creating
+ clients. If the value is ``None`` then there is no default config
+ object attached to the session.
+ """
+ self._client_config = client_config
+
+ def set_credentials(self, access_key, secret_key, token=None):
+ """
+ Manually create credentials for this session. If you would
+ prefer to use botocore without a config file, environment variables,
+ or IAM roles, you can pass explicit credentials into this
+ method to establish credentials for this session.
+
+ :type access_key: str
+ :param access_key: The access key part of the credentials.
+
+ :type secret_key: str
+ :param secret_key: The secret key part of the credentials.
+
+ :type token: str
+ :param token: An option session token used by STS session
+ credentials.
+ """
+ self._credentials = botocore.credentials.Credentials(
+ access_key, secret_key, token
+ )
+
+ def get_credentials(self):
+ """
+ Return the :class:`botocore.credential.Credential` object
+ associated with this session. If the credentials have not
+ yet been loaded, this will attempt to load them. If they
+ have already been loaded, this will return the cached
+ credentials.
+
+ """
+ if self._credentials is None:
+ self._credentials = self._components.get_component(
+ 'credential_provider'
+ ).load_credentials()
+ return self._credentials
+
+ def get_auth_token(self):
+ """
+ Return the :class:`botocore.tokens.AuthToken` object associated with
+ this session. If the authorization token has not yet been loaded, this
+ will attempt to load it. If it has already been loaded, this will
+ return the cached authorization token.
+
+ """
+ if self._auth_token is None:
+ provider = self._components.get_component('token_provider')
+ self._auth_token = provider.load_token()
+ return self._auth_token
+
+ def user_agent(self):
+ """
+ Return a string suitable for use as a User-Agent header.
+ The string will be of the form:
+
+ / Python/ /
+
+ Where:
+
+ - agent_name is the value of the `user_agent_name` attribute
+ of the session object (`Botocore` by default).
+ - agent_version is the value of the `user_agent_version`
+ attribute of the session object (the botocore version by default).
+ by default.
+ - py_ver is the version of the Python interpreter beng used.
+ - plat_name is the name of the platform (e.g. Darwin)
+ - plat_ver is the version of the platform
+ - exec_env is exec-env/$AWS_EXECUTION_ENV
+
+ If ``user_agent_extra`` is not empty, then this value will be
+ appended to the end of the user agent string.
+
+ """
+ base = (
+ f'{self.user_agent_name}/{self.user_agent_version} '
+ f'Python/{platform.python_version()} '
+ f'{platform.system()}/{platform.release()}'
+ )
+ if HAS_CRT:
+ base += ' awscrt/%s' % self._get_crt_version()
+ if os.environ.get('AWS_EXECUTION_ENV') is not None:
+ base += ' exec-env/%s' % os.environ.get('AWS_EXECUTION_ENV')
+ if self.user_agent_extra:
+ base += ' %s' % self.user_agent_extra
+
+ return base
+
+ def get_data(self, data_path):
+ """
+ Retrieve the data associated with `data_path`.
+
+ :type data_path: str
+ :param data_path: The path to the data you wish to retrieve.
+ """
+ return self.get_component('data_loader').load_data(data_path)
+
+ def get_service_model(self, service_name, api_version=None):
+ """Get the service model object.
+
+ :type service_name: string
+ :param service_name: The service name
+
+ :type api_version: string
+ :param api_version: The API version of the service. If none is
+ provided, then the latest API version will be used.
+
+ :rtype: L{botocore.model.ServiceModel}
+ :return: The botocore service model for the service.
+
+ """
+ service_description = self.get_service_data(service_name, api_version)
+ return ServiceModel(service_description, service_name=service_name)
+
+ def get_waiter_model(self, service_name, api_version=None):
+ loader = self.get_component('data_loader')
+ waiter_config = loader.load_service_model(
+ service_name, 'waiters-2', api_version
+ )
+ return waiter.WaiterModel(waiter_config)
+
+ def get_paginator_model(self, service_name, api_version=None):
+ loader = self.get_component('data_loader')
+ paginator_config = loader.load_service_model(
+ service_name, 'paginators-1', api_version
+ )
+ return paginate.PaginatorModel(paginator_config)
+
+ def get_service_data(self, service_name, api_version=None):
+ """
+ Retrieve the fully merged data associated with a service.
+ """
+ data_path = service_name
+ service_data = self.get_component('data_loader').load_service_model(
+ data_path, type_name='service-2', api_version=api_version
+ )
+ service_id = EVENT_ALIASES.get(service_name, service_name)
+ self._events.emit(
+ 'service-data-loaded.%s' % service_id,
+ service_data=service_data,
+ service_name=service_name,
+ session=self,
+ )
+ return service_data
+
+ def get_available_services(self):
+ """
+ Return a list of names of available services.
+ """
+ return self.get_component('data_loader').list_available_services(
+ type_name='service-2'
+ )
+
+ def set_debug_logger(self, logger_name='botocore'):
+ """
+ Convenience function to quickly configure full debug output
+ to go to the console.
+ """
+ self.set_stream_logger(logger_name, logging.DEBUG)
+
+ def set_stream_logger(
+ self, logger_name, log_level, stream=None, format_string=None
+ ):
+ """
+ Convenience method to configure a stream logger.
+
+ :type logger_name: str
+ :param logger_name: The name of the logger to configure
+
+ :type log_level: str
+ :param log_level: The log level to set for the logger. This
+ is any param supported by the ``.setLevel()`` method of
+ a ``Log`` object.
+
+ :type stream: file
+ :param stream: A file like object to log to. If none is provided
+ then sys.stderr will be used.
+
+ :type format_string: str
+ :param format_string: The format string to use for the log
+ formatter. If none is provided this will default to
+ ``self.LOG_FORMAT``.
+
+ """
+ log = logging.getLogger(logger_name)
+ log.setLevel(logging.DEBUG)
+
+ ch = logging.StreamHandler(stream)
+ ch.setLevel(log_level)
+
+ # create formatter
+ if format_string is None:
+ format_string = self.LOG_FORMAT
+ formatter = logging.Formatter(format_string)
+
+ # add formatter to ch
+ ch.setFormatter(formatter)
+
+ # add ch to logger
+ log.addHandler(ch)
+
+ def set_file_logger(self, log_level, path, logger_name='botocore'):
+ """
+ Convenience function to quickly configure any level of logging
+ to a file.
+
+ :type log_level: int
+ :param log_level: A log level as specified in the `logging` module
+
+ :type path: string
+ :param path: Path to the log file. The file will be created
+ if it doesn't already exist.
+ """
+ log = logging.getLogger(logger_name)
+ log.setLevel(logging.DEBUG)
+
+ # create console handler and set level to debug
+ ch = logging.FileHandler(path)
+ ch.setLevel(log_level)
+
+ # create formatter
+ formatter = logging.Formatter(self.LOG_FORMAT)
+
+ # add formatter to ch
+ ch.setFormatter(formatter)
+
+ # add ch to logger
+ log.addHandler(ch)
+
+ def register(
+ self, event_name, handler, unique_id=None, unique_id_uses_count=False
+ ):
+ """Register a handler with an event.
+
+ :type event_name: str
+ :param event_name: The name of the event.
+
+ :type handler: callable
+ :param handler: The callback to invoke when the event
+ is emitted. This object must be callable, and must
+ accept ``**kwargs``. If either of these preconditions are
+ not met, a ``ValueError`` will be raised.
+
+ :type unique_id: str
+ :param unique_id: An optional identifier to associate with the
+ registration. A unique_id can only be used once for
+ the entire session registration (unless it is unregistered).
+ This can be used to prevent an event handler from being
+ registered twice.
+
+ :param unique_id_uses_count: boolean
+ :param unique_id_uses_count: Specifies if the event should maintain
+ a count when a ``unique_id`` is registered and unregisted. The
+ event can only be completely unregistered once every register call
+ using the unique id has been matched by an ``unregister`` call.
+ If ``unique_id`` is specified, subsequent ``register``
+ calls must use the same value for ``unique_id_uses_count``
+ as the ``register`` call that first registered the event.
+
+ :raises ValueError: If the call to ``register`` uses ``unique_id``
+ but the value for ``unique_id_uses_count`` differs from the
+ ``unique_id_uses_count`` value declared by the very first
+ ``register`` call for that ``unique_id``.
+ """
+ self._events.register(
+ event_name,
+ handler,
+ unique_id,
+ unique_id_uses_count=unique_id_uses_count,
+ )
+
+ def unregister(
+ self,
+ event_name,
+ handler=None,
+ unique_id=None,
+ unique_id_uses_count=False,
+ ):
+ """Unregister a handler with an event.
+
+ :type event_name: str
+ :param event_name: The name of the event.
+
+ :type handler: callable
+ :param handler: The callback to unregister.
+
+ :type unique_id: str
+ :param unique_id: A unique identifier identifying the callback
+ to unregister. You can provide either the handler or the
+ unique_id, you do not have to provide both.
+
+ :param unique_id_uses_count: boolean
+ :param unique_id_uses_count: Specifies if the event should maintain
+ a count when a ``unique_id`` is registered and unregisted. The
+ event can only be completely unregistered once every ``register``
+ call using the ``unique_id`` has been matched by an ``unregister``
+ call. If the ``unique_id`` is specified, subsequent
+ ``unregister`` calls must use the same value for
+ ``unique_id_uses_count`` as the ``register`` call that first
+ registered the event.
+
+ :raises ValueError: If the call to ``unregister`` uses ``unique_id``
+ but the value for ``unique_id_uses_count`` differs from the
+ ``unique_id_uses_count`` value declared by the very first
+ ``register`` call for that ``unique_id``.
+ """
+ self._events.unregister(
+ event_name,
+ handler=handler,
+ unique_id=unique_id,
+ unique_id_uses_count=unique_id_uses_count,
+ )
+
+ def emit(self, event_name, **kwargs):
+ return self._events.emit(event_name, **kwargs)
+
+ def emit_first_non_none_response(self, event_name, **kwargs):
+ responses = self._events.emit(event_name, **kwargs)
+ return first_non_none_response(responses)
+
+ def get_component(self, name):
+ try:
+ return self._components.get_component(name)
+ except ValueError:
+ if name in ['endpoint_resolver', 'exceptions_factory']:
+ warnings.warn(
+ 'Fetching the %s component with the get_component() '
+ 'method is deprecated as the component has always been '
+ 'considered an internal interface of botocore' % name,
+ DeprecationWarning,
+ )
+ return self._internal_components.get_component(name)
+ raise
+
+ def _get_internal_component(self, name):
+ # While this method may be called by botocore classes outside of the
+ # Session, this method should **never** be used by a class that lives
+ # outside of botocore.
+ return self._internal_components.get_component(name)
+
+ def _register_internal_component(self, name, component):
+ # While this method may be called by botocore classes outside of the
+ # Session, this method should **never** be used by a class that lives
+ # outside of botocore.
+ return self._internal_components.register_component(name, component)
+
+ def register_component(self, name, component):
+ self._components.register_component(name, component)
+
+ def lazy_register_component(self, name, component):
+ self._components.lazy_register_component(name, component)
+
+ def create_client(
+ self,
+ service_name,
+ region_name=None,
+ api_version=None,
+ use_ssl=True,
+ verify=None,
+ endpoint_url=None,
+ aws_access_key_id=None,
+ aws_secret_access_key=None,
+ aws_session_token=None,
+ config=None,
+ ):
+ """Create a botocore client.
+
+ :type service_name: string
+ :param service_name: The name of the service for which a client will
+ be created. You can use the ``Session.get_available_services()``
+ method to get a list of all available service names.
+
+ :type region_name: string
+ :param region_name: The name of the region associated with the client.
+ A client is associated with a single region.
+
+ :type api_version: string
+ :param api_version: The API version to use. By default, botocore will
+ use the latest API version when creating a client. You only need
+ to specify this parameter if you want to use a previous API version
+ of the client.
+
+ :type use_ssl: boolean
+ :param use_ssl: Whether or not to use SSL. By default, SSL is used.
+ Note that not all services support non-ssl connections.
+
+ :type verify: boolean/string
+ :param verify: Whether or not to verify SSL certificates.
+ By default SSL certificates are verified. You can provide the
+ following values:
+
+ * False - do not validate SSL certificates. SSL will still be
+ used (unless use_ssl is False), but SSL certificates
+ will not be verified.
+ * path/to/cert/bundle.pem - A filename of the CA cert bundle to
+ uses. You can specify this argument if you want to use a
+ different CA cert bundle than the one used by botocore.
+
+ :type endpoint_url: string
+ :param endpoint_url: The complete URL to use for the constructed
+ client. Normally, botocore will automatically construct the
+ appropriate URL to use when communicating with a service. You can
+ specify a complete URL (including the "http/https" scheme) to
+ override this behavior. If this value is provided, then
+ ``use_ssl`` is ignored.
+
+ :type aws_access_key_id: string
+ :param aws_access_key_id: The access key to use when creating
+ the client. This is entirely optional, and if not provided,
+ the credentials configured for the session will automatically
+ be used. You only need to provide this argument if you want
+ to override the credentials used for this specific client.
+
+ :type aws_secret_access_key: string
+ :param aws_secret_access_key: The secret key to use when creating
+ the client. Same semantics as aws_access_key_id above.
+
+ :type aws_session_token: string
+ :param aws_session_token: The session token to use when creating
+ the client. Same semantics as aws_access_key_id above.
+
+ :type config: botocore.client.Config
+ :param config: Advanced client configuration options. If a value
+ is specified in the client config, its value will take precedence
+ over environment variables and configuration values, but not over
+ a value passed explicitly to the method. If a default config
+ object is set on the session, the config object used when creating
+ the client will be the result of calling ``merge()`` on the
+ default config with the config provided to this call.
+
+ :rtype: botocore.client.BaseClient
+ :return: A botocore client instance
+
+ """
+ default_client_config = self.get_default_client_config()
+ # If a config is provided and a default config is set, then
+ # use the config resulting from merging the two.
+ if config is not None and default_client_config is not None:
+ config = default_client_config.merge(config)
+ # If a config was not provided then use the default
+ # client config from the session
+ elif default_client_config is not None:
+ config = default_client_config
+
+ region_name = self._resolve_region_name(region_name, config)
+
+ # Figure out the verify value base on the various
+ # configuration options.
+ if verify is None:
+ verify = self.get_config_variable('ca_bundle')
+
+ if api_version is None:
+ api_version = self.get_config_variable('api_versions').get(
+ service_name, None
+ )
+
+ loader = self.get_component('data_loader')
+ event_emitter = self.get_component('event_emitter')
+ response_parser_factory = self.get_component('response_parser_factory')
+ if config is not None and config.signature_version is UNSIGNED:
+ credentials = None
+ elif (
+ aws_access_key_id is not None and aws_secret_access_key is not None
+ ):
+ credentials = botocore.credentials.Credentials(
+ access_key=aws_access_key_id,
+ secret_key=aws_secret_access_key,
+ token=aws_session_token,
+ )
+ elif self._missing_cred_vars(aws_access_key_id, aws_secret_access_key):
+ raise PartialCredentialsError(
+ provider='explicit',
+ cred_var=self._missing_cred_vars(
+ aws_access_key_id, aws_secret_access_key
+ ),
+ )
+ else:
+ credentials = self.get_credentials()
+ auth_token = self.get_auth_token()
+ endpoint_resolver = self._get_internal_component('endpoint_resolver')
+ exceptions_factory = self._get_internal_component('exceptions_factory')
+ config_store = copy.copy(self.get_component('config_store'))
+ user_agent_creator = self.get_component('user_agent_creator')
+ # Session configuration values for the user agent string are applied
+ # just before each client creation because they may have been modified
+ # at any time between session creation and client creation.
+ user_agent_creator.set_session_config(
+ session_user_agent_name=self.user_agent_name,
+ session_user_agent_version=self.user_agent_version,
+ session_user_agent_extra=self.user_agent_extra,
+ )
+ defaults_mode = self._resolve_defaults_mode(config, config_store)
+ if defaults_mode != 'legacy':
+ smart_defaults_factory = self._get_internal_component(
+ 'smart_defaults_factory'
+ )
+ smart_defaults_factory.merge_smart_defaults(
+ config_store, defaults_mode, region_name
+ )
+
+ self._add_configured_endpoint_provider(
+ client_name=service_name,
+ config_store=config_store,
+ )
+
+ client_creator = botocore.client.ClientCreator(
+ loader,
+ endpoint_resolver,
+ self.user_agent(),
+ event_emitter,
+ retryhandler,
+ translate,
+ response_parser_factory,
+ exceptions_factory,
+ config_store,
+ user_agent_creator=user_agent_creator,
+ )
+ client = client_creator.create_client(
+ service_name=service_name,
+ region_name=region_name,
+ is_secure=use_ssl,
+ endpoint_url=endpoint_url,
+ verify=verify,
+ credentials=credentials,
+ scoped_config=self.get_scoped_config(),
+ client_config=config,
+ api_version=api_version,
+ auth_token=auth_token,
+ )
+ monitor = self._get_internal_component('monitor')
+ if monitor is not None:
+ monitor.register(client.meta.events)
+ return client
+
+ def _resolve_region_name(self, region_name, config):
+ # Figure out the user-provided region based on the various
+ # configuration options.
+ if region_name is None:
+ if config and config.region_name is not None:
+ region_name = config.region_name
+ else:
+ region_name = self.get_config_variable('region')
+
+ validate_region_name(region_name)
+ # For any client that we create in retrieving credentials
+ # we want to create it using the same region as specified in
+ # creating this client. It is important to note though that the
+ # credentials client is only created once per session. So if a new
+ # client is created with a different region, its credential resolver
+ # will use the region of the first client. However, that is not an
+ # issue as of now because the credential resolver uses only STS and
+ # the credentials returned at regional endpoints are valid across
+ # all regions in the partition.
+ self._last_client_region_used = region_name
+ return region_name
+
+ def _resolve_defaults_mode(self, client_config, config_store):
+ mode = config_store.get_config_variable('defaults_mode')
+
+ if client_config and client_config.defaults_mode:
+ mode = client_config.defaults_mode
+
+ default_config_resolver = self._get_internal_component(
+ 'default_config_resolver'
+ )
+ default_modes = default_config_resolver.get_default_modes()
+ lmode = mode.lower()
+ if lmode not in default_modes:
+ raise InvalidDefaultsMode(
+ mode=mode, valid_modes=', '.join(default_modes)
+ )
+
+ return lmode
+
+ def _add_configured_endpoint_provider(self, client_name, config_store):
+ chain = ConfiguredEndpointProvider(
+ full_config=self.full_config,
+ scoped_config=self.get_scoped_config(),
+ client_name=client_name,
+ )
+ config_store.set_config_provider(
+ logical_name='endpoint_url',
+ provider=chain,
+ )
+
+ def _missing_cred_vars(self, access_key, secret_key):
+ if access_key is not None and secret_key is None:
+ return 'aws_secret_access_key'
+ if secret_key is not None and access_key is None:
+ return 'aws_access_key_id'
+ return None
+
+ def get_available_partitions(self):
+ """Lists the available partitions found on disk
+
+ :rtype: list
+ :return: Returns a list of partition names (e.g., ["aws", "aws-cn"])
+ """
+ resolver = self._get_internal_component('endpoint_resolver')
+ return resolver.get_available_partitions()
+
+ def get_partition_for_region(self, region_name):
+ """Lists the partition name of a particular region.
+
+ :type region_name: string
+ :param region_name: Name of the region to list partition for (e.g.,
+ us-east-1).
+
+ :rtype: string
+ :return: Returns the respective partition name (e.g., aws).
+ """
+ resolver = self._get_internal_component('endpoint_resolver')
+ return resolver.get_partition_for_region(region_name)
+
+ def get_available_regions(
+ self, service_name, partition_name='aws', allow_non_regional=False
+ ):
+ """Lists the region and endpoint names of a particular partition.
+
+ :type service_name: string
+ :param service_name: Name of a service to list endpoint for (e.g., s3).
+ This parameter accepts a service name (e.g., "elb") or endpoint
+ prefix (e.g., "elasticloadbalancing").
+
+ :type partition_name: string
+ :param partition_name: Name of the partition to limit endpoints to.
+ (e.g., aws for the public AWS endpoints, aws-cn for AWS China
+ endpoints, aws-us-gov for AWS GovCloud (US) Endpoints, etc.
+
+ :type allow_non_regional: bool
+ :param allow_non_regional: Set to True to include endpoints that are
+ not regional endpoints (e.g., s3-external-1,
+ fips-us-gov-west-1, etc).
+ :return: Returns a list of endpoint names (e.g., ["us-east-1"]).
+ """
+ resolver = self._get_internal_component('endpoint_resolver')
+ results = []
+ try:
+ service_data = self.get_service_data(service_name)
+ endpoint_prefix = service_data['metadata'].get(
+ 'endpointPrefix', service_name
+ )
+ results = resolver.get_available_endpoints(
+ endpoint_prefix, partition_name, allow_non_regional
+ )
+ except UnknownServiceError:
+ pass
+ return results
+
+
+class ComponentLocator:
+ """Service locator for session components."""
+
+ def __init__(self):
+ self._components = {}
+ self._deferred = {}
+
+ def get_component(self, name):
+ if name in self._deferred:
+ factory = self._deferred[name]
+ self._components[name] = factory()
+ # Only delete the component from the deferred dict after
+ # successfully creating the object from the factory as well as
+ # injecting the instantiated value into the _components dict.
+ try:
+ del self._deferred[name]
+ except KeyError:
+ # If we get here, it's likely that get_component was called
+ # concurrently from multiple threads, and another thread
+ # already deleted the entry. This means the factory was
+ # probably called twice, but cleaning up the deferred entry
+ # should not crash outright.
+ pass
+ try:
+ return self._components[name]
+ except KeyError:
+ raise ValueError("Unknown component: %s" % name)
+
+ def register_component(self, name, component):
+ self._components[name] = component
+ try:
+ del self._deferred[name]
+ except KeyError:
+ pass
+
+ def lazy_register_component(self, name, no_arg_factory):
+ self._deferred[name] = no_arg_factory
+ try:
+ del self._components[name]
+ except KeyError:
+ pass
+
+
+class SessionVarDict(MutableMapping):
+ def __init__(self, session, session_vars):
+ self._session = session
+ self._store = copy.copy(session_vars)
+
+ def __getitem__(self, key):
+ return self._store[key]
+
+ def __setitem__(self, key, value):
+ self._store[key] = value
+ self._update_config_store_from_session_vars(key, value)
+
+ def __delitem__(self, key):
+ del self._store[key]
+
+ def __iter__(self):
+ return iter(self._store)
+
+ def __len__(self):
+ return len(self._store)
+
+ def _update_config_store_from_session_vars(
+ self, logical_name, config_options
+ ):
+ # This is for backwards compatibility. The new preferred way to
+ # modify configuration logic is to use the component system to get
+ # the config_store component from the session, and then update
+ # a key with a custom config provider(s).
+ # This backwards compatibility method takes the old session_vars
+ # list of tuples and and transforms that into a set of updates to
+ # the config_store component.
+ config_chain_builder = ConfigChainFactory(session=self._session)
+ config_name, env_vars, default, typecast = config_options
+ config_store = self._session.get_component('config_store')
+ config_store.set_config_provider(
+ logical_name,
+ config_chain_builder.create_config_chain(
+ instance_name=logical_name,
+ env_var_names=env_vars,
+ config_property_names=config_name,
+ default=default,
+ conversion_func=typecast,
+ ),
+ )
+
+
+class SubsetChainConfigFactory:
+ """A class for creating backwards compatible configuration chains.
+
+ This class can be used instead of
+ :class:`botocore.configprovider.ConfigChainFactory` to make it honor the
+ methods argument to get_config_variable. This class can be used to filter
+ out providers that are not in the methods tuple when creating a new config
+ chain.
+ """
+
+ def __init__(self, session, methods, environ=None):
+ self._factory = ConfigChainFactory(session, environ)
+ self._supported_methods = methods
+
+ def create_config_chain(
+ self,
+ instance_name=None,
+ env_var_names=None,
+ config_property_name=None,
+ default=None,
+ conversion_func=None,
+ ):
+ """Build a config chain following the standard botocore pattern.
+
+ This config chain factory will omit any providers not in the methods
+ tuple provided at initialization. For example if given the tuple
+ ('instance', 'config',) it will not inject the environment provider
+ into the standard config chain. This lets the botocore session support
+ the custom ``methods`` argument for all the default botocore config
+ variables when calling ``get_config_variable``.
+ """
+ if 'instance' not in self._supported_methods:
+ instance_name = None
+ if 'env' not in self._supported_methods:
+ env_var_names = None
+ if 'config' not in self._supported_methods:
+ config_property_name = None
+ return self._factory.create_config_chain(
+ instance_name=instance_name,
+ env_var_names=env_var_names,
+ config_property_names=config_property_name,
+ default=default,
+ conversion_func=conversion_func,
+ )
+
+
+def get_session(env_vars=None):
+ """
+ Return a new session object.
+ """
+ return Session(env_vars)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/signers.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/signers.py
new file mode 100644
index 0000000000..0acbf68463
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/signers.py
@@ -0,0 +1,841 @@
+# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import base64
+import datetime
+import json
+import weakref
+
+import botocore
+import botocore.auth
+from botocore.awsrequest import create_request_object, prepare_request_dict
+from botocore.compat import OrderedDict
+from botocore.exceptions import (
+ UnknownClientMethodError,
+ UnknownSignatureVersionError,
+ UnsupportedSignatureVersionError,
+)
+from botocore.utils import ArnParser, datetime2timestamp
+
+# Keep these imported. There's pre-existing code that uses them.
+from botocore.utils import fix_s3_host # noqa
+
+
+class RequestSigner:
+ """
+ An object to sign requests before they go out over the wire using
+ one of the authentication mechanisms defined in ``auth.py``. This
+ class fires two events scoped to a service and operation name:
+
+ * choose-signer: Allows overriding the auth signer name.
+ * before-sign: Allows mutating the request before signing.
+
+ Together these events allow for customization of the request
+ signing pipeline, including overrides, request path manipulation,
+ and disabling signing per operation.
+
+
+ :type service_id: botocore.model.ServiceId
+ :param service_id: The service id for the service, e.g. ``S3``
+
+ :type region_name: string
+ :param region_name: Name of the service region, e.g. ``us-east-1``
+
+ :type signing_name: string
+ :param signing_name: Service signing name. This is usually the
+ same as the service name, but can differ. E.g.
+ ``emr`` vs. ``elasticmapreduce``.
+
+ :type signature_version: string
+ :param signature_version: Signature name like ``v4``.
+
+ :type credentials: :py:class:`~botocore.credentials.Credentials`
+ :param credentials: User credentials with which to sign requests.
+
+ :type event_emitter: :py:class:`~botocore.hooks.BaseEventHooks`
+ :param event_emitter: Extension mechanism to fire events.
+ """
+
+ def __init__(
+ self,
+ service_id,
+ region_name,
+ signing_name,
+ signature_version,
+ credentials,
+ event_emitter,
+ auth_token=None,
+ ):
+ self._region_name = region_name
+ self._signing_name = signing_name
+ self._signature_version = signature_version
+ self._credentials = credentials
+ self._auth_token = auth_token
+ self._service_id = service_id
+
+ # We need weakref to prevent leaking memory in Python 2.6 on Linux 2.6
+ self._event_emitter = weakref.proxy(event_emitter)
+
+ @property
+ def region_name(self):
+ return self._region_name
+
+ @property
+ def signature_version(self):
+ return self._signature_version
+
+ @property
+ def signing_name(self):
+ return self._signing_name
+
+ def handler(self, operation_name=None, request=None, **kwargs):
+ # This is typically hooked up to the "request-created" event
+ # from a client's event emitter. When a new request is created
+ # this method is invoked to sign the request.
+ # Don't call this method directly.
+ return self.sign(operation_name, request)
+
+ def sign(
+ self,
+ operation_name,
+ request,
+ region_name=None,
+ signing_type='standard',
+ expires_in=None,
+ signing_name=None,
+ ):
+ """Sign a request before it goes out over the wire.
+
+ :type operation_name: string
+ :param operation_name: The name of the current operation, e.g.
+ ``ListBuckets``.
+ :type request: AWSRequest
+ :param request: The request object to be sent over the wire.
+
+ :type region_name: str
+ :param region_name: The region to sign the request for.
+
+ :type signing_type: str
+ :param signing_type: The type of signing to perform. This can be one of
+ three possible values:
+
+ * 'standard' - This should be used for most requests.
+ * 'presign-url' - This should be used when pre-signing a request.
+ * 'presign-post' - This should be used when pre-signing an S3 post.
+
+ :type expires_in: int
+ :param expires_in: The number of seconds the presigned url is valid
+ for. This parameter is only valid for signing type 'presign-url'.
+
+ :type signing_name: str
+ :param signing_name: The name to use for the service when signing.
+ """
+ explicit_region_name = region_name
+ if region_name is None:
+ region_name = self._region_name
+
+ if signing_name is None:
+ signing_name = self._signing_name
+
+ signature_version = self._choose_signer(
+ operation_name, signing_type, request.context
+ )
+
+ # Allow mutating request before signing
+ self._event_emitter.emit(
+ 'before-sign.{}.{}'.format(
+ self._service_id.hyphenize(), operation_name
+ ),
+ request=request,
+ signing_name=signing_name,
+ region_name=self._region_name,
+ signature_version=signature_version,
+ request_signer=self,
+ operation_name=operation_name,
+ )
+
+ if signature_version != botocore.UNSIGNED:
+ kwargs = {
+ 'signing_name': signing_name,
+ 'region_name': region_name,
+ 'signature_version': signature_version,
+ }
+ if expires_in is not None:
+ kwargs['expires'] = expires_in
+ signing_context = request.context.get('signing', {})
+ if not explicit_region_name and signing_context.get('region'):
+ kwargs['region_name'] = signing_context['region']
+ if signing_context.get('signing_name'):
+ kwargs['signing_name'] = signing_context['signing_name']
+ try:
+ auth = self.get_auth_instance(**kwargs)
+ except UnknownSignatureVersionError as e:
+ if signing_type != 'standard':
+ raise UnsupportedSignatureVersionError(
+ signature_version=signature_version
+ )
+ else:
+ raise e
+
+ auth.add_auth(request)
+
+ def _choose_signer(self, operation_name, signing_type, context):
+ """
+ Allow setting the signature version via the choose-signer event.
+ A value of `botocore.UNSIGNED` means no signing will be performed.
+
+ :param operation_name: The operation to sign.
+ :param signing_type: The type of signing that the signer is to be used
+ for.
+ :return: The signature version to sign with.
+ """
+ signing_type_suffix_map = {
+ 'presign-post': '-presign-post',
+ 'presign-url': '-query',
+ }
+ suffix = signing_type_suffix_map.get(signing_type, '')
+
+ # operation specific signing context takes precedent over client-level
+ # defaults
+ signature_version = context.get('auth_type') or self._signature_version
+ signing = context.get('signing', {})
+ signing_name = signing.get('signing_name', self._signing_name)
+ region_name = signing.get('region', self._region_name)
+ if (
+ signature_version is not botocore.UNSIGNED
+ and not signature_version.endswith(suffix)
+ ):
+ signature_version += suffix
+
+ handler, response = self._event_emitter.emit_until_response(
+ 'choose-signer.{}.{}'.format(
+ self._service_id.hyphenize(), operation_name
+ ),
+ signing_name=signing_name,
+ region_name=region_name,
+ signature_version=signature_version,
+ context=context,
+ )
+
+ if response is not None:
+ signature_version = response
+ # The suffix needs to be checked again in case we get an improper
+ # signature version from choose-signer.
+ if (
+ signature_version is not botocore.UNSIGNED
+ and not signature_version.endswith(suffix)
+ ):
+ signature_version += suffix
+
+ return signature_version
+
+ def get_auth_instance(
+ self, signing_name, region_name, signature_version=None, **kwargs
+ ):
+ """
+ Get an auth instance which can be used to sign a request
+ using the given signature version.
+
+ :type signing_name: string
+ :param signing_name: Service signing name. This is usually the
+ same as the service name, but can differ. E.g.
+ ``emr`` vs. ``elasticmapreduce``.
+
+ :type region_name: string
+ :param region_name: Name of the service region, e.g. ``us-east-1``
+
+ :type signature_version: string
+ :param signature_version: Signature name like ``v4``.
+
+ :rtype: :py:class:`~botocore.auth.BaseSigner`
+ :return: Auth instance to sign a request.
+ """
+ if signature_version is None:
+ signature_version = self._signature_version
+
+ cls = botocore.auth.AUTH_TYPE_MAPS.get(signature_version)
+ if cls is None:
+ raise UnknownSignatureVersionError(
+ signature_version=signature_version
+ )
+
+ if cls.REQUIRES_TOKEN is True:
+ frozen_token = None
+ if self._auth_token is not None:
+ frozen_token = self._auth_token.get_frozen_token()
+ auth = cls(frozen_token)
+ return auth
+
+ # If there's no credentials provided (i.e credentials is None),
+ # then we'll pass a value of "None" over to the auth classes,
+ # which already handle the cases where no credentials have
+ # been provided.
+ frozen_credentials = None
+ if self._credentials is not None:
+ frozen_credentials = self._credentials.get_frozen_credentials()
+ kwargs['credentials'] = frozen_credentials
+ if cls.REQUIRES_REGION:
+ if self._region_name is None:
+ raise botocore.exceptions.NoRegionError()
+ kwargs['region_name'] = region_name
+ kwargs['service_name'] = signing_name
+ auth = cls(**kwargs)
+ return auth
+
+ # Alias get_auth for backwards compatibility.
+ get_auth = get_auth_instance
+
+ def generate_presigned_url(
+ self,
+ request_dict,
+ operation_name,
+ expires_in=3600,
+ region_name=None,
+ signing_name=None,
+ ):
+ """Generates a presigned url
+
+ :type request_dict: dict
+ :param request_dict: The prepared request dictionary returned by
+ ``botocore.awsrequest.prepare_request_dict()``
+
+ :type operation_name: str
+ :param operation_name: The operation being signed.
+
+ :type expires_in: int
+ :param expires_in: The number of seconds the presigned url is valid
+ for. By default it expires in an hour (3600 seconds)
+
+ :type region_name: string
+ :param region_name: The region name to sign the presigned url.
+
+ :type signing_name: str
+ :param signing_name: The name to use for the service when signing.
+
+ :returns: The presigned url
+ """
+ request = create_request_object(request_dict)
+ self.sign(
+ operation_name,
+ request,
+ region_name,
+ 'presign-url',
+ expires_in,
+ signing_name,
+ )
+
+ request.prepare()
+ return request.url
+
+
+class CloudFrontSigner:
+ '''A signer to create a signed CloudFront URL.
+
+ First you create a cloudfront signer based on a normalized RSA signer::
+
+ import rsa
+ def rsa_signer(message):
+ private_key = open('private_key.pem', 'r').read()
+ return rsa.sign(
+ message,
+ rsa.PrivateKey.load_pkcs1(private_key.encode('utf8')),
+ 'SHA-1') # CloudFront requires SHA-1 hash
+ cf_signer = CloudFrontSigner(key_id, rsa_signer)
+
+ To sign with a canned policy::
+
+ signed_url = cf_signer.generate_signed_url(
+ url, date_less_than=datetime(2015, 12, 1))
+
+ To sign with a custom policy::
+
+ signed_url = cf_signer.generate_signed_url(url, policy=my_policy)
+ '''
+
+ def __init__(self, key_id, rsa_signer):
+ """Create a CloudFrontSigner.
+
+ :type key_id: str
+ :param key_id: The CloudFront Key Pair ID
+
+ :type rsa_signer: callable
+ :param rsa_signer: An RSA signer.
+ Its only input parameter will be the message to be signed,
+ and its output will be the signed content as a binary string.
+ The hash algorithm needed by CloudFront is SHA-1.
+ """
+ self.key_id = key_id
+ self.rsa_signer = rsa_signer
+
+ def generate_presigned_url(self, url, date_less_than=None, policy=None):
+ """Creates a signed CloudFront URL based on given parameters.
+
+ :type url: str
+ :param url: The URL of the protected object
+
+ :type date_less_than: datetime
+ :param date_less_than: The URL will expire after that date and time
+
+ :type policy: str
+ :param policy: The custom policy, possibly built by self.build_policy()
+
+ :rtype: str
+ :return: The signed URL.
+ """
+ both_args_supplied = date_less_than is not None and policy is not None
+ neither_arg_supplied = date_less_than is None and policy is None
+ if both_args_supplied or neither_arg_supplied:
+ e = 'Need to provide either date_less_than or policy, but not both'
+ raise ValueError(e)
+ if date_less_than is not None:
+ # We still need to build a canned policy for signing purpose
+ policy = self.build_policy(url, date_less_than)
+ if isinstance(policy, str):
+ policy = policy.encode('utf8')
+ if date_less_than is not None:
+ params = ['Expires=%s' % int(datetime2timestamp(date_less_than))]
+ else:
+ params = ['Policy=%s' % self._url_b64encode(policy).decode('utf8')]
+ signature = self.rsa_signer(policy)
+ params.extend(
+ [
+ f"Signature={self._url_b64encode(signature).decode('utf8')}",
+ f"Key-Pair-Id={self.key_id}",
+ ]
+ )
+ return self._build_url(url, params)
+
+ def _build_url(self, base_url, extra_params):
+ separator = '&' if '?' in base_url else '?'
+ return base_url + separator + '&'.join(extra_params)
+
+ def build_policy(
+ self, resource, date_less_than, date_greater_than=None, ip_address=None
+ ):
+ """A helper to build policy.
+
+ :type resource: str
+ :param resource: The URL or the stream filename of the protected object
+
+ :type date_less_than: datetime
+ :param date_less_than: The URL will expire after the time has passed
+
+ :type date_greater_than: datetime
+ :param date_greater_than: The URL will not be valid until this time
+
+ :type ip_address: str
+ :param ip_address: Use 'x.x.x.x' for an IP, or 'x.x.x.x/x' for a subnet
+
+ :rtype: str
+ :return: The policy in a compact string.
+ """
+ # Note:
+ # 1. Order in canned policy is significant. Special care has been taken
+ # to ensure the output will match the order defined by the document.
+ # There is also a test case to ensure that order.
+ # SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html#private-content-canned-policy-creating-policy-statement
+ # 2. Albeit the order in custom policy is not required by CloudFront,
+ # we still use OrderedDict internally to ensure the result is stable
+ # and also matches canned policy requirement.
+ # SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html
+ moment = int(datetime2timestamp(date_less_than))
+ condition = OrderedDict({"DateLessThan": {"AWS:EpochTime": moment}})
+ if ip_address:
+ if '/' not in ip_address:
+ ip_address += '/32'
+ condition["IpAddress"] = {"AWS:SourceIp": ip_address}
+ if date_greater_than:
+ moment = int(datetime2timestamp(date_greater_than))
+ condition["DateGreaterThan"] = {"AWS:EpochTime": moment}
+ ordered_payload = [('Resource', resource), ('Condition', condition)]
+ custom_policy = {"Statement": [OrderedDict(ordered_payload)]}
+ return json.dumps(custom_policy, separators=(',', ':'))
+
+ def _url_b64encode(self, data):
+ # Required by CloudFront. See also:
+ # http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-linux-openssl.html
+ return (
+ base64.b64encode(data)
+ .replace(b'+', b'-')
+ .replace(b'=', b'_')
+ .replace(b'/', b'~')
+ )
+
+
+def add_generate_db_auth_token(class_attributes, **kwargs):
+ class_attributes['generate_db_auth_token'] = generate_db_auth_token
+
+
+def generate_db_auth_token(self, DBHostname, Port, DBUsername, Region=None):
+ """Generates an auth token used to connect to a db with IAM credentials.
+
+ :type DBHostname: str
+ :param DBHostname: The hostname of the database to connect to.
+
+ :type Port: int
+ :param Port: The port number the database is listening on.
+
+ :type DBUsername: str
+ :param DBUsername: The username to log in as.
+
+ :type Region: str
+ :param Region: The region the database is in. If None, the client
+ region will be used.
+
+ :return: A presigned url which can be used as an auth token.
+ """
+ region = Region
+ if region is None:
+ region = self.meta.region_name
+
+ params = {
+ 'Action': 'connect',
+ 'DBUser': DBUsername,
+ }
+
+ request_dict = {
+ 'url_path': '/',
+ 'query_string': '',
+ 'headers': {},
+ 'body': params,
+ 'method': 'GET',
+ }
+
+ # RDS requires that the scheme not be set when sent over. This can cause
+ # issues when signing because the Python url parsing libraries follow
+ # RFC 1808 closely, which states that a netloc must be introduced by `//`.
+ # Otherwise the url is presumed to be relative, and thus the whole
+ # netloc would be treated as a path component. To work around this we
+ # introduce https here and remove it once we're done processing it.
+ scheme = 'https://'
+ endpoint_url = f'{scheme}{DBHostname}:{Port}'
+ prepare_request_dict(request_dict, endpoint_url)
+ presigned_url = self._request_signer.generate_presigned_url(
+ operation_name='connect',
+ request_dict=request_dict,
+ region_name=region,
+ expires_in=900,
+ signing_name='rds-db',
+ )
+ return presigned_url[len(scheme) :]
+
+
+class S3PostPresigner:
+ def __init__(self, request_signer):
+ self._request_signer = request_signer
+
+ def generate_presigned_post(
+ self,
+ request_dict,
+ fields=None,
+ conditions=None,
+ expires_in=3600,
+ region_name=None,
+ ):
+ """Generates the url and the form fields used for a presigned s3 post
+
+ :type request_dict: dict
+ :param request_dict: The prepared request dictionary returned by
+ ``botocore.awsrequest.prepare_request_dict()``
+
+ :type fields: dict
+ :param fields: A dictionary of prefilled form fields to build on top
+ of.
+
+ :type conditions: list
+ :param conditions: A list of conditions to include in the policy. Each
+ element can be either a list or a structure. For example:
+ [
+ {"acl": "public-read"},
+ {"bucket": "mybucket"},
+ ["starts-with", "$key", "mykey"]
+ ]
+
+ :type expires_in: int
+ :param expires_in: The number of seconds the presigned post is valid
+ for.
+
+ :type region_name: string
+ :param region_name: The region name to sign the presigned post to.
+
+ :rtype: dict
+ :returns: A dictionary with two elements: ``url`` and ``fields``.
+ Url is the url to post to. Fields is a dictionary filled with
+ the form fields and respective values to use when submitting the
+ post. For example:
+
+ {'url': 'https://mybucket.s3.amazonaws.com
+ 'fields': {'acl': 'public-read',
+ 'key': 'mykey',
+ 'signature': 'mysignature',
+ 'policy': 'mybase64 encoded policy'}
+ }
+ """
+ if fields is None:
+ fields = {}
+
+ if conditions is None:
+ conditions = []
+
+ # Create the policy for the post.
+ policy = {}
+
+ # Create an expiration date for the policy
+ datetime_now = datetime.datetime.utcnow()
+ expire_date = datetime_now + datetime.timedelta(seconds=expires_in)
+ policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)
+
+ # Append all of the conditions that the user supplied.
+ policy['conditions'] = []
+ for condition in conditions:
+ policy['conditions'].append(condition)
+
+ # Store the policy and the fields in the request for signing
+ request = create_request_object(request_dict)
+ request.context['s3-presign-post-fields'] = fields
+ request.context['s3-presign-post-policy'] = policy
+
+ self._request_signer.sign(
+ 'PutObject', request, region_name, 'presign-post'
+ )
+ # Return the url and the fields for th form to post.
+ return {'url': request.url, 'fields': fields}
+
+
+def add_generate_presigned_url(class_attributes, **kwargs):
+ class_attributes['generate_presigned_url'] = generate_presigned_url
+
+
+def generate_presigned_url(
+ self, ClientMethod, Params=None, ExpiresIn=3600, HttpMethod=None
+):
+ """Generate a presigned url given a client, its method, and arguments
+
+ :type ClientMethod: string
+ :param ClientMethod: The client method to presign for
+
+ :type Params: dict
+ :param Params: The parameters normally passed to
+ ``ClientMethod``.
+
+ :type ExpiresIn: int
+ :param ExpiresIn: The number of seconds the presigned url is valid
+ for. By default it expires in an hour (3600 seconds)
+
+ :type HttpMethod: string
+ :param HttpMethod: The http method to use on the generated url. By
+ default, the http method is whatever is used in the method's model.
+
+ :returns: The presigned url
+ """
+ client_method = ClientMethod
+ params = Params
+ if params is None:
+ params = {}
+ expires_in = ExpiresIn
+ http_method = HttpMethod
+ context = {
+ 'is_presign_request': True,
+ 'use_global_endpoint': _should_use_global_endpoint(self),
+ }
+
+ request_signer = self._request_signer
+
+ try:
+ operation_name = self._PY_TO_OP_NAME[client_method]
+ except KeyError:
+ raise UnknownClientMethodError(method_name=client_method)
+
+ operation_model = self.meta.service_model.operation_model(operation_name)
+ params = self._emit_api_params(
+ api_params=params,
+ operation_model=operation_model,
+ context=context,
+ )
+ bucket_is_arn = ArnParser.is_arn(params.get('Bucket', ''))
+ endpoint_url, additional_headers = self._resolve_endpoint_ruleset(
+ operation_model,
+ params,
+ context,
+ ignore_signing_region=(not bucket_is_arn),
+ )
+
+ request_dict = self._convert_to_request_dict(
+ api_params=params,
+ operation_model=operation_model,
+ endpoint_url=endpoint_url,
+ context=context,
+ headers=additional_headers,
+ set_user_agent_header=False,
+ )
+
+ # Switch out the http method if user specified it.
+ if http_method is not None:
+ request_dict['method'] = http_method
+
+ # Generate the presigned url.
+ return request_signer.generate_presigned_url(
+ request_dict=request_dict,
+ expires_in=expires_in,
+ operation_name=operation_name,
+ )
+
+
+def add_generate_presigned_post(class_attributes, **kwargs):
+ class_attributes['generate_presigned_post'] = generate_presigned_post
+
+
+def generate_presigned_post(
+ self, Bucket, Key, Fields=None, Conditions=None, ExpiresIn=3600
+):
+ """Builds the url and the form fields used for a presigned s3 post
+
+ :type Bucket: string
+ :param Bucket: The name of the bucket to presign the post to. Note that
+ bucket related conditions should not be included in the
+ ``conditions`` parameter.
+
+ :type Key: string
+ :param Key: Key name, optionally add ${filename} to the end to
+ attach the submitted filename. Note that key related conditions and
+ fields are filled out for you and should not be included in the
+ ``Fields`` or ``Conditions`` parameter.
+
+ :type Fields: dict
+ :param Fields: A dictionary of prefilled form fields to build on top
+ of. Elements that may be included are acl, Cache-Control,
+ Content-Type, Content-Disposition, Content-Encoding, Expires,
+ success_action_redirect, redirect, success_action_status,
+ and x-amz-meta-.
+
+ Note that if a particular element is included in the fields
+ dictionary it will not be automatically added to the conditions
+ list. You must specify a condition for the element as well.
+
+ :type Conditions: list
+ :param Conditions: A list of conditions to include in the policy. Each
+ element can be either a list or a structure. For example:
+
+ [
+ {"acl": "public-read"},
+ ["content-length-range", 2, 5],
+ ["starts-with", "$success_action_redirect", ""]
+ ]
+
+ Conditions that are included may pertain to acl,
+ content-length-range, Cache-Control, Content-Type,
+ Content-Disposition, Content-Encoding, Expires,
+ success_action_redirect, redirect, success_action_status,
+ and/or x-amz-meta-.
+
+ Note that if you include a condition, you must specify
+ the a valid value in the fields dictionary as well. A value will
+ not be added automatically to the fields dictionary based on the
+ conditions.
+
+ :type ExpiresIn: int
+ :param ExpiresIn: The number of seconds the presigned post
+ is valid for.
+
+ :rtype: dict
+ :returns: A dictionary with two elements: ``url`` and ``fields``.
+ Url is the url to post to. Fields is a dictionary filled with
+ the form fields and respective values to use when submitting the
+ post. For example:
+
+ {'url': 'https://mybucket.s3.amazonaws.com
+ 'fields': {'acl': 'public-read',
+ 'key': 'mykey',
+ 'signature': 'mysignature',
+ 'policy': 'mybase64 encoded policy'}
+ }
+ """
+ bucket = Bucket
+ key = Key
+ fields = Fields
+ conditions = Conditions
+ expires_in = ExpiresIn
+
+ if fields is None:
+ fields = {}
+ else:
+ fields = fields.copy()
+
+ if conditions is None:
+ conditions = []
+
+ context = {
+ 'is_presign_request': True,
+ 'use_global_endpoint': _should_use_global_endpoint(self),
+ }
+
+ post_presigner = S3PostPresigner(self._request_signer)
+
+ # We choose the CreateBucket operation model because its url gets
+ # serialized to what a presign post requires.
+ operation_model = self.meta.service_model.operation_model('CreateBucket')
+ params = self._emit_api_params(
+ api_params={'Bucket': bucket},
+ operation_model=operation_model,
+ context=context,
+ )
+ bucket_is_arn = ArnParser.is_arn(params.get('Bucket', ''))
+ endpoint_url, additional_headers = self._resolve_endpoint_ruleset(
+ operation_model,
+ params,
+ context,
+ ignore_signing_region=(not bucket_is_arn),
+ )
+
+ request_dict = self._convert_to_request_dict(
+ api_params=params,
+ operation_model=operation_model,
+ endpoint_url=endpoint_url,
+ context=context,
+ headers=additional_headers,
+ set_user_agent_header=False,
+ )
+
+ # Append that the bucket name to the list of conditions.
+ conditions.append({'bucket': bucket})
+
+ # If the key ends with filename, the only constraint that can be
+ # imposed is if it starts with the specified prefix.
+ if key.endswith('${filename}'):
+ conditions.append(["starts-with", '$key', key[: -len('${filename}')]])
+ else:
+ conditions.append({'key': key})
+
+ # Add the key to the fields.
+ fields['key'] = key
+
+ return post_presigner.generate_presigned_post(
+ request_dict=request_dict,
+ fields=fields,
+ conditions=conditions,
+ expires_in=expires_in,
+ )
+
+
+def _should_use_global_endpoint(client):
+ if client.meta.partition != 'aws':
+ return False
+ s3_config = client.meta.config.s3
+ if s3_config:
+ if s3_config.get('use_dualstack_endpoint', False):
+ return False
+ if (
+ s3_config.get('us_east_1_regional_endpoint') == 'regional'
+ and client.meta.config.region_name == 'us-east-1'
+ ):
+ return False
+ return True
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/stub.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/stub.py
new file mode 100644
index 0000000000..137cfe4288
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/stub.py
@@ -0,0 +1,429 @@
+# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import copy
+from collections import deque
+from pprint import pformat
+
+from botocore.awsrequest import AWSResponse
+from botocore.exceptions import (
+ ParamValidationError,
+ StubAssertionError,
+ StubResponseError,
+ UnStubbedResponseError,
+)
+from botocore.validate import validate_parameters
+
+
+class _ANY:
+ """
+ A helper object that compares equal to everything. Copied from
+ unittest.mock
+ """
+
+ def __eq__(self, other):
+ return True
+
+ def __ne__(self, other):
+ return False
+
+ def __repr__(self):
+ return ''
+
+
+ANY = _ANY()
+
+
+class Stubber:
+ """
+ This class will allow you to stub out requests so you don't have to hit
+ an endpoint to write tests. Responses are returned first in, first out.
+ If operations are called out of order, or are called with no remaining
+ queued responses, an error will be raised.
+
+ **Example:**
+ ::
+ import datetime
+ import botocore.session
+ from botocore.stub import Stubber
+
+
+ s3 = botocore.session.get_session().create_client('s3')
+ stubber = Stubber(s3)
+
+ response = {
+ 'IsTruncated': False,
+ 'Name': 'test-bucket',
+ 'MaxKeys': 1000, 'Prefix': '',
+ 'Contents': [{
+ 'Key': 'test.txt',
+ 'ETag': '"abc123"',
+ 'StorageClass': 'STANDARD',
+ 'LastModified': datetime.datetime(2016, 1, 20, 22, 9),
+ 'Owner': {'ID': 'abc123', 'DisplayName': 'myname'},
+ 'Size': 14814
+ }],
+ 'EncodingType': 'url',
+ 'ResponseMetadata': {
+ 'RequestId': 'abc123',
+ 'HTTPStatusCode': 200,
+ 'HostId': 'abc123'
+ },
+ 'Marker': ''
+ }
+
+ expected_params = {'Bucket': 'test-bucket'}
+
+ stubber.add_response('list_objects', response, expected_params)
+ stubber.activate()
+
+ service_response = s3.list_objects(Bucket='test-bucket')
+ assert service_response == response
+
+
+ This class can also be called as a context manager, which will handle
+ activation / deactivation for you.
+
+ **Example:**
+ ::
+ import datetime
+ import botocore.session
+ from botocore.stub import Stubber
+
+
+ s3 = botocore.session.get_session().create_client('s3')
+
+ response = {
+ "Owner": {
+ "ID": "foo",
+ "DisplayName": "bar"
+ },
+ "Buckets": [{
+ "CreationDate": datetime.datetime(2016, 1, 20, 22, 9),
+ "Name": "baz"
+ }]
+ }
+
+
+ with Stubber(s3) as stubber:
+ stubber.add_response('list_buckets', response, {})
+ service_response = s3.list_buckets()
+
+ assert service_response == response
+
+
+ If you have an input parameter that is a randomly generated value, or you
+ otherwise don't care about its value, you can use ``stub.ANY`` to ignore
+ it in validation.
+
+ **Example:**
+ ::
+ import datetime
+ import botocore.session
+ from botocore.stub import Stubber, ANY
+
+
+ s3 = botocore.session.get_session().create_client('s3')
+ stubber = Stubber(s3)
+
+ response = {
+ 'IsTruncated': False,
+ 'Name': 'test-bucket',
+ 'MaxKeys': 1000, 'Prefix': '',
+ 'Contents': [{
+ 'Key': 'test.txt',
+ 'ETag': '"abc123"',
+ 'StorageClass': 'STANDARD',
+ 'LastModified': datetime.datetime(2016, 1, 20, 22, 9),
+ 'Owner': {'ID': 'abc123', 'DisplayName': 'myname'},
+ 'Size': 14814
+ }],
+ 'EncodingType': 'url',
+ 'ResponseMetadata': {
+ 'RequestId': 'abc123',
+ 'HTTPStatusCode': 200,
+ 'HostId': 'abc123'
+ },
+ 'Marker': ''
+ }
+
+ expected_params = {'Bucket': ANY}
+ stubber.add_response('list_objects', response, expected_params)
+
+ with stubber:
+ service_response = s3.list_objects(Bucket='test-bucket')
+
+ assert service_response == response
+ """
+
+ def __init__(self, client):
+ """
+ :param client: The client to add your stubs to.
+ """
+ self.client = client
+ self._event_id = 'boto_stubber'
+ self._expected_params_event_id = 'boto_stubber_expected_params'
+ self._queue = deque()
+
+ def __enter__(self):
+ self.activate()
+ return self
+
+ def __exit__(self, exception_type, exception_value, traceback):
+ self.deactivate()
+
+ def activate(self):
+ """
+ Activates the stubber on the client
+ """
+ self.client.meta.events.register_first(
+ 'before-parameter-build.*.*',
+ self._assert_expected_params,
+ unique_id=self._expected_params_event_id,
+ )
+ self.client.meta.events.register(
+ 'before-call.*.*',
+ self._get_response_handler,
+ unique_id=self._event_id,
+ )
+
+ def deactivate(self):
+ """
+ Deactivates the stubber on the client
+ """
+ self.client.meta.events.unregister(
+ 'before-parameter-build.*.*',
+ self._assert_expected_params,
+ unique_id=self._expected_params_event_id,
+ )
+ self.client.meta.events.unregister(
+ 'before-call.*.*',
+ self._get_response_handler,
+ unique_id=self._event_id,
+ )
+
+ def add_response(self, method, service_response, expected_params=None):
+ """
+ Adds a service response to the response queue. This will be validated
+ against the service model to ensure correctness. It should be noted,
+ however, that while missing attributes are often considered correct,
+ your code may not function properly if you leave them out. Therefore
+ you should always fill in every value you see in a typical response for
+ your particular request.
+
+ :param method: The name of the client method to stub.
+ :type method: str
+
+ :param service_response: A dict response stub. Provided parameters will
+ be validated against the service model.
+ :type service_response: dict
+
+ :param expected_params: A dictionary of the expected parameters to
+ be called for the provided service response. The parameters match
+ the names of keyword arguments passed to that client call. If
+ any of the parameters differ a ``StubResponseError`` is thrown.
+ You can use stub.ANY to indicate a particular parameter to ignore
+ in validation. stub.ANY is only valid for top level params.
+ """
+ self._add_response(method, service_response, expected_params)
+
+ def _add_response(self, method, service_response, expected_params):
+ if not hasattr(self.client, method):
+ raise ValueError(
+ "Client %s does not have method: %s"
+ % (self.client.meta.service_model.service_name, method)
+ )
+
+ # Create a successful http response
+ http_response = AWSResponse(None, 200, {}, None)
+
+ operation_name = self.client.meta.method_to_api_mapping.get(method)
+ self._validate_operation_response(operation_name, service_response)
+
+ # Add the service_response to the queue for returning responses
+ response = {
+ 'operation_name': operation_name,
+ 'response': (http_response, service_response),
+ 'expected_params': expected_params,
+ }
+ self._queue.append(response)
+
+ def add_client_error(
+ self,
+ method,
+ service_error_code='',
+ service_message='',
+ http_status_code=400,
+ service_error_meta=None,
+ expected_params=None,
+ response_meta=None,
+ modeled_fields=None,
+ ):
+ """
+ Adds a ``ClientError`` to the response queue.
+
+ :param method: The name of the service method to return the error on.
+ :type method: str
+
+ :param service_error_code: The service error code to return,
+ e.g. ``NoSuchBucket``
+ :type service_error_code: str
+
+ :param service_message: The service message to return, e.g.
+ 'The specified bucket does not exist.'
+ :type service_message: str
+
+ :param http_status_code: The HTTP status code to return, e.g. 404, etc
+ :type http_status_code: int
+
+ :param service_error_meta: Additional keys to be added to the
+ service Error
+ :type service_error_meta: dict
+
+ :param expected_params: A dictionary of the expected parameters to
+ be called for the provided service response. The parameters match
+ the names of keyword arguments passed to that client call. If
+ any of the parameters differ a ``StubResponseError`` is thrown.
+ You can use stub.ANY to indicate a particular parameter to ignore
+ in validation.
+
+ :param response_meta: Additional keys to be added to the
+ response's ResponseMetadata
+ :type response_meta: dict
+
+ :param modeled_fields: Additional keys to be added to the response
+ based on fields that are modeled for the particular error code.
+ These keys will be validated against the particular error shape
+ designated by the error code.
+ :type modeled_fields: dict
+
+ """
+ http_response = AWSResponse(None, http_status_code, {}, None)
+
+ # We don't look to the model to build this because the caller would
+ # need to know the details of what the HTTP body would need to
+ # look like.
+ parsed_response = {
+ 'ResponseMetadata': {'HTTPStatusCode': http_status_code},
+ 'Error': {'Message': service_message, 'Code': service_error_code},
+ }
+
+ if service_error_meta is not None:
+ parsed_response['Error'].update(service_error_meta)
+
+ if response_meta is not None:
+ parsed_response['ResponseMetadata'].update(response_meta)
+
+ if modeled_fields is not None:
+ service_model = self.client.meta.service_model
+ shape = service_model.shape_for_error_code(service_error_code)
+ self._validate_response(shape, modeled_fields)
+ parsed_response.update(modeled_fields)
+
+ operation_name = self.client.meta.method_to_api_mapping.get(method)
+ # Note that we do not allow for expected_params while
+ # adding errors into the queue yet.
+ response = {
+ 'operation_name': operation_name,
+ 'response': (http_response, parsed_response),
+ 'expected_params': expected_params,
+ }
+ self._queue.append(response)
+
+ def assert_no_pending_responses(self):
+ """
+ Asserts that all expected calls were made.
+ """
+ remaining = len(self._queue)
+ if remaining != 0:
+ raise AssertionError(f"{remaining} responses remaining in queue.")
+
+ def _assert_expected_call_order(self, model, params):
+ if not self._queue:
+ raise UnStubbedResponseError(
+ operation_name=model.name,
+ reason=(
+ 'Unexpected API Call: A call was made but no additional '
+ 'calls expected. Either the API Call was not stubbed or '
+ 'it was called multiple times.'
+ ),
+ )
+
+ name = self._queue[0]['operation_name']
+ if name != model.name:
+ raise StubResponseError(
+ operation_name=model.name,
+ reason=f'Operation mismatch: found response for {name}.',
+ )
+
+ def _get_response_handler(self, model, params, context, **kwargs):
+ self._assert_expected_call_order(model, params)
+ # Pop off the entire response once everything has been validated
+ return self._queue.popleft()['response']
+
+ def _assert_expected_params(self, model, params, context, **kwargs):
+ if self._should_not_stub(context):
+ return
+ self._assert_expected_call_order(model, params)
+ expected_params = self._queue[0]['expected_params']
+ if expected_params is None:
+ return
+
+ # Validate the parameters are equal
+ for param, value in expected_params.items():
+ if param not in params or expected_params[param] != params[param]:
+ raise StubAssertionError(
+ operation_name=model.name,
+ reason='Expected parameters:\n%s,\nbut received:\n%s'
+ % (pformat(expected_params), pformat(params)),
+ )
+
+ # Ensure there are no extra params hanging around
+ if sorted(expected_params.keys()) != sorted(params.keys()):
+ raise StubAssertionError(
+ operation_name=model.name,
+ reason='Expected parameters:\n%s,\nbut received:\n%s'
+ % (pformat(expected_params), pformat(params)),
+ )
+
+ def _should_not_stub(self, context):
+ # Do not include presign requests when processing stubbed client calls
+ # as a presign request will never have an HTTP request sent over the
+ # wire for it and therefore not receive a response back.
+ if context and context.get('is_presign_request'):
+ return True
+
+ def _validate_operation_response(self, operation_name, service_response):
+ service_model = self.client.meta.service_model
+ operation_model = service_model.operation_model(operation_name)
+ output_shape = operation_model.output_shape
+
+ # Remove ResponseMetadata so that the validator doesn't attempt to
+ # perform validation on it.
+ response = service_response
+ if 'ResponseMetadata' in response:
+ response = copy.copy(service_response)
+ del response['ResponseMetadata']
+
+ self._validate_response(output_shape, response)
+
+ def _validate_response(self, shape, response):
+ if shape is not None:
+ validate_parameters(response, shape)
+ elif response:
+ # If the output shape is None, that means the response should be
+ # empty apart from ResponseMetadata
+ raise ParamValidationError(
+ report=(
+ "Service response should only contain ResponseMetadata."
+ )
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/tokens.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/tokens.py
new file mode 100644
index 0000000000..6e61694611
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/tokens.py
@@ -0,0 +1,330 @@
+# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import json
+import logging
+import os
+import threading
+from datetime import datetime, timedelta
+from typing import NamedTuple, Optional
+
+import dateutil.parser
+from dateutil.tz import tzutc
+
+from botocore import UNSIGNED
+from botocore.compat import total_seconds
+from botocore.config import Config
+from botocore.exceptions import (
+ ClientError,
+ InvalidConfigError,
+ TokenRetrievalError,
+)
+from botocore.utils import CachedProperty, JSONFileCache, SSOTokenLoader
+
+logger = logging.getLogger(__name__)
+
+
+def _utc_now():
+ return datetime.now(tzutc())
+
+
+def create_token_resolver(session):
+ providers = [
+ SSOTokenProvider(session),
+ ]
+ return TokenProviderChain(providers=providers)
+
+
+def _serialize_utc_timestamp(obj):
+ if isinstance(obj, datetime):
+ return obj.strftime("%Y-%m-%dT%H:%M:%SZ")
+ return obj
+
+
+def _sso_json_dumps(obj):
+ return json.dumps(obj, default=_serialize_utc_timestamp)
+
+
+class FrozenAuthToken(NamedTuple):
+ token: str
+ expiration: Optional[datetime] = None
+
+
+class DeferredRefreshableToken:
+ # The time at which we'll attempt to refresh, but not block if someone else
+ # is refreshing.
+ _advisory_refresh_timeout = 15 * 60
+ # The time at which all threads will block waiting for a refreshed token
+ _mandatory_refresh_timeout = 10 * 60
+ # Refresh at most once every minute to avoid blocking every request
+ _attempt_timeout = 60
+
+ def __init__(self, method, refresh_using, time_fetcher=_utc_now):
+ self._time_fetcher = time_fetcher
+ self._refresh_using = refresh_using
+ self.method = method
+
+ # The frozen token is protected by this lock
+ self._refresh_lock = threading.Lock()
+ self._frozen_token = None
+ self._next_refresh = None
+
+ def get_frozen_token(self):
+ self._refresh()
+ return self._frozen_token
+
+ def _refresh(self):
+ # If we don't need to refresh just return
+ refresh_type = self._should_refresh()
+ if not refresh_type:
+ return None
+
+ # Block for refresh if we're in the mandatory refresh window
+ block_for_refresh = refresh_type == "mandatory"
+ if self._refresh_lock.acquire(block_for_refresh):
+ try:
+ self._protected_refresh()
+ finally:
+ self._refresh_lock.release()
+
+ def _protected_refresh(self):
+ # This should only be called after acquiring the refresh lock
+ # Another thread may have already refreshed, double check refresh
+ refresh_type = self._should_refresh()
+ if not refresh_type:
+ return None
+
+ try:
+ now = self._time_fetcher()
+ self._next_refresh = now + timedelta(seconds=self._attempt_timeout)
+ self._frozen_token = self._refresh_using()
+ except Exception:
+ logger.warning(
+ "Refreshing token failed during the %s refresh period.",
+ refresh_type,
+ exc_info=True,
+ )
+ if refresh_type == "mandatory":
+ # This refresh was mandatory, error must be propagated back
+ raise
+
+ if self._is_expired():
+ # Fresh credentials should never be expired
+ raise TokenRetrievalError(
+ provider=self.method,
+ error_msg="Token has expired and refresh failed",
+ )
+
+ def _is_expired(self):
+ if self._frozen_token is None:
+ return False
+
+ expiration = self._frozen_token.expiration
+ remaining = total_seconds(expiration - self._time_fetcher())
+ return remaining <= 0
+
+ def _should_refresh(self):
+ if self._frozen_token is None:
+ # We don't have a token yet, mandatory refresh
+ return "mandatory"
+
+ expiration = self._frozen_token.expiration
+ if expiration is None:
+ # No expiration, so assume we don't need to refresh.
+ return None
+
+ now = self._time_fetcher()
+ if now < self._next_refresh:
+ return None
+
+ remaining = total_seconds(expiration - now)
+
+ if remaining < self._mandatory_refresh_timeout:
+ return "mandatory"
+ elif remaining < self._advisory_refresh_timeout:
+ return "advisory"
+
+ return None
+
+
+class TokenProviderChain:
+ def __init__(self, providers=None):
+ if providers is None:
+ providers = []
+ self._providers = providers
+
+ def load_token(self):
+ for provider in self._providers:
+ token = provider.load_token()
+ if token is not None:
+ return token
+ return None
+
+
+class SSOTokenProvider:
+ METHOD = "sso"
+ _REFRESH_WINDOW = 15 * 60
+ _SSO_TOKEN_CACHE_DIR = os.path.expanduser(
+ os.path.join("~", ".aws", "sso", "cache")
+ )
+ _SSO_CONFIG_VARS = [
+ "sso_start_url",
+ "sso_region",
+ ]
+ _GRANT_TYPE = "refresh_token"
+ DEFAULT_CACHE_CLS = JSONFileCache
+
+ def __init__(
+ self, session, cache=None, time_fetcher=_utc_now, profile_name=None
+ ):
+ self._session = session
+ if cache is None:
+ cache = self.DEFAULT_CACHE_CLS(
+ self._SSO_TOKEN_CACHE_DIR,
+ dumps_func=_sso_json_dumps,
+ )
+ self._now = time_fetcher
+ self._cache = cache
+ self._token_loader = SSOTokenLoader(cache=self._cache)
+ self._profile_name = (
+ profile_name
+ or self._session.get_config_variable("profile")
+ or 'default'
+ )
+
+ def _load_sso_config(self):
+ loaded_config = self._session.full_config
+ profiles = loaded_config.get("profiles", {})
+ sso_sessions = loaded_config.get("sso_sessions", {})
+ profile_config = profiles.get(self._profile_name, {})
+
+ if "sso_session" not in profile_config:
+ return
+
+ sso_session_name = profile_config["sso_session"]
+ sso_config = sso_sessions.get(sso_session_name, None)
+
+ if not sso_config:
+ error_msg = (
+ f'The profile "{self._profile_name}" is configured to use the SSO '
+ f'token provider but the "{sso_session_name}" sso_session '
+ f"configuration does not exist."
+ )
+ raise InvalidConfigError(error_msg=error_msg)
+
+ missing_configs = []
+ for var in self._SSO_CONFIG_VARS:
+ if var not in sso_config:
+ missing_configs.append(var)
+
+ if missing_configs:
+ error_msg = (
+ f'The profile "{self._profile_name}" is configured to use the SSO '
+ f"token provider but is missing the following configuration: "
+ f"{missing_configs}."
+ )
+ raise InvalidConfigError(error_msg=error_msg)
+
+ return {
+ "session_name": sso_session_name,
+ "sso_region": sso_config["sso_region"],
+ "sso_start_url": sso_config["sso_start_url"],
+ }
+
+ @CachedProperty
+ def _sso_config(self):
+ return self._load_sso_config()
+
+ @CachedProperty
+ def _client(self):
+ config = Config(
+ region_name=self._sso_config["sso_region"],
+ signature_version=UNSIGNED,
+ )
+ return self._session.create_client("sso-oidc", config=config)
+
+ def _attempt_create_token(self, token):
+ response = self._client.create_token(
+ grantType=self._GRANT_TYPE,
+ clientId=token["clientId"],
+ clientSecret=token["clientSecret"],
+ refreshToken=token["refreshToken"],
+ )
+ expires_in = timedelta(seconds=response["expiresIn"])
+ new_token = {
+ "startUrl": self._sso_config["sso_start_url"],
+ "region": self._sso_config["sso_region"],
+ "accessToken": response["accessToken"],
+ "expiresAt": self._now() + expires_in,
+ # Cache the registration alongside the token
+ "clientId": token["clientId"],
+ "clientSecret": token["clientSecret"],
+ "registrationExpiresAt": token["registrationExpiresAt"],
+ }
+ if "refreshToken" in response:
+ new_token["refreshToken"] = response["refreshToken"]
+ logger.info("SSO Token refresh succeeded")
+ return new_token
+
+ def _refresh_access_token(self, token):
+ keys = (
+ "refreshToken",
+ "clientId",
+ "clientSecret",
+ "registrationExpiresAt",
+ )
+ missing_keys = [k for k in keys if k not in token]
+ if missing_keys:
+ msg = f"Unable to refresh SSO token: missing keys: {missing_keys}"
+ logger.info(msg)
+ return None
+
+ expiry = dateutil.parser.parse(token["registrationExpiresAt"])
+ if total_seconds(expiry - self._now()) <= 0:
+ logger.info(f"SSO token registration expired at {expiry}")
+ return None
+
+ try:
+ return self._attempt_create_token(token)
+ except ClientError:
+ logger.warning("SSO token refresh attempt failed", exc_info=True)
+ return None
+
+ def _refresher(self):
+ start_url = self._sso_config["sso_start_url"]
+ session_name = self._sso_config["session_name"]
+ logger.info(f"Loading cached SSO token for {session_name}")
+ token_dict = self._token_loader(start_url, session_name=session_name)
+ expiration = dateutil.parser.parse(token_dict["expiresAt"])
+ logger.debug(f"Cached SSO token expires at {expiration}")
+
+ remaining = total_seconds(expiration - self._now())
+ if remaining < self._REFRESH_WINDOW:
+ new_token_dict = self._refresh_access_token(token_dict)
+ if new_token_dict is not None:
+ token_dict = new_token_dict
+ expiration = token_dict["expiresAt"]
+ self._token_loader.save_token(
+ start_url, token_dict, session_name=session_name
+ )
+
+ return FrozenAuthToken(
+ token_dict["accessToken"], expiration=expiration
+ )
+
+ def load_token(self):
+ if self._sso_config is None:
+ return None
+
+ return DeferredRefreshableToken(
+ self.METHOD, self._refresher, time_fetcher=self._now
+ )
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/translate.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/translate.py
new file mode 100644
index 0000000000..ecfe3bcaf4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/translate.py
@@ -0,0 +1,78 @@
+# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
+# Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import copy
+
+from botocore.utils import merge_dicts
+
+
+def build_retry_config(
+ endpoint_prefix, retry_model, definitions, client_retry_config=None
+):
+ service_config = retry_model.get(endpoint_prefix, {})
+ resolve_references(service_config, definitions)
+ # We want to merge the global defaults with the service specific
+ # defaults, with the service specific defaults taking precedence.
+ # So we use the global defaults as the base.
+ #
+ # A deepcopy is done on the retry defaults because it ensures the
+ # retry model has no chance of getting mutated when the service specific
+ # configuration or client retry config is merged in.
+ final_retry_config = {
+ '__default__': copy.deepcopy(retry_model.get('__default__', {}))
+ }
+ resolve_references(final_retry_config, definitions)
+ # The merge the service specific config on top.
+ merge_dicts(final_retry_config, service_config)
+ if client_retry_config is not None:
+ _merge_client_retry_config(final_retry_config, client_retry_config)
+ return final_retry_config
+
+
+def _merge_client_retry_config(retry_config, client_retry_config):
+ max_retry_attempts_override = client_retry_config.get('max_attempts')
+ if max_retry_attempts_override is not None:
+ # In the retry config, the max_attempts refers to the maximum number
+ # of requests in general will be made. However, for the client's
+ # retry config it refers to how many retry attempts will be made at
+ # most. So to translate this number from the client config, one is
+ # added to convert it to the maximum number request that will be made
+ # by including the initial request.
+ #
+ # It is also important to note that if we ever support per operation
+ # configuration in the retry model via the client, we will need to
+ # revisit this logic to make sure max_attempts gets applied
+ # per operation.
+ retry_config['__default__']['max_attempts'] = (
+ max_retry_attempts_override + 1
+ )
+
+
+def resolve_references(config, definitions):
+ """Recursively replace $ref keys.
+
+ To cut down on duplication, common definitions can be declared
+ (and passed in via the ``definitions`` attribute) and then
+ references as {"$ref": "name"}, when this happens the reference
+ dict is placed with the value from the ``definition`` dict.
+
+ This is recursively done.
+
+ """
+ for key, value in config.items():
+ if isinstance(value, dict):
+ if len(value) == 1 and list(value.keys())[0] == '$ref':
+ # Then we need to resolve this reference.
+ config[key] = definitions[list(value.values())[0]]
+ else:
+ resolve_references(value, definitions)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/useragent.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/useragent.py
new file mode 100644
index 0000000000..f837fc8699
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/useragent.py
@@ -0,0 +1,503 @@
+# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+"""
+NOTE: All classes and functions in this module are considered private and are
+subject to abrupt breaking changes. Please do not use them directly.
+
+To modify the User-Agent header sent by botocore, use one of these
+configuration options:
+* The ``AWS_SDK_UA_APP_ID`` environment variable.
+* The ``sdk_ua_app_id`` setting in the shared AWS config file.
+* The ``user_agent_appid`` field in the :py:class:`botocore.config.Config`.
+* The ``user_agent_extra`` field in the :py:class:`botocore.config.Config`.
+
+"""
+import os
+import platform
+from copy import copy
+from string import ascii_letters, digits
+from typing import NamedTuple, Optional
+
+from botocore import __version__ as botocore_version
+from botocore.compat import HAS_CRT
+
+_USERAGENT_ALLOWED_CHARACTERS = ascii_letters + digits + "!$%&'*+-.^_`|~"
+_USERAGENT_ALLOWED_OS_NAMES = (
+ 'windows',
+ 'linux',
+ 'macos',
+ 'android',
+ 'ios',
+ 'watchos',
+ 'tvos',
+ 'other',
+)
+_USERAGENT_PLATFORM_NAME_MAPPINGS = {'darwin': 'macos'}
+# The name by which botocore is identified in the User-Agent header. While most
+# AWS SDKs follow a naming pattern of "aws-sdk-*", botocore and boto3 continue
+# using their existing values. Uses uppercase "B" with all other characters
+# lowercase.
+_USERAGENT_SDK_NAME = 'Botocore'
+
+
+def sanitize_user_agent_string_component(raw_str, allow_hash):
+ """Replaces all not allowed characters in the string with a dash ("-").
+
+ Allowed characters are ASCII alphanumerics and ``!$%&'*+-.^_`|~``. If
+ ``allow_hash`` is ``True``, "#"``" is also allowed.
+
+ :type raw_str: str
+ :param raw_str: The input string to be sanitized.
+
+ :type allow_hash: bool
+ :param allow_hash: Whether "#" is considered an allowed character.
+ """
+ return ''.join(
+ c
+ if c in _USERAGENT_ALLOWED_CHARACTERS or (allow_hash and c == '#')
+ else '-'
+ for c in raw_str
+ )
+
+
+class UserAgentComponent(NamedTuple):
+ """
+ Component of a Botocore User-Agent header string in the standard format.
+
+ Each component consists of a prefix, a name, and a value. In the string
+ representation these are combined in the format ``prefix/name#value``.
+
+ This class is considered private and is subject to abrupt breaking changes.
+ """
+
+ prefix: str
+ name: str
+ value: Optional[str] = None
+
+ def to_string(self):
+ """Create string like 'prefix/name#value' from a UserAgentComponent."""
+ clean_prefix = sanitize_user_agent_string_component(
+ self.prefix, allow_hash=True
+ )
+ clean_name = sanitize_user_agent_string_component(
+ self.name, allow_hash=False
+ )
+ if self.value is None or self.value == '':
+ return f'{clean_prefix}/{clean_name}'
+ clean_value = sanitize_user_agent_string_component(
+ self.value, allow_hash=True
+ )
+ return f'{clean_prefix}/{clean_name}#{clean_value}'
+
+
+class RawStringUserAgentComponent:
+ """
+ UserAgentComponent interface wrapper around ``str``.
+
+ Use for User-Agent header components that are not constructed from
+ prefix+name+value but instead are provided as strings. No sanitization is
+ performed.
+ """
+
+ def __init__(self, value):
+ self._value = value
+
+ def to_string(self):
+ return self._value
+
+
+# This is not a public interface and is subject to abrupt breaking changes.
+# Any usage is not advised or supported in external code bases.
+try:
+ from botocore.customizations.useragent import modify_components
+except ImportError:
+ # Default implementation that returns unmodified User-Agent components.
+ def modify_components(components):
+ return components
+
+
+class UserAgentString:
+ """
+ Generator for AWS SDK User-Agent header strings.
+
+ The User-Agent header format contains information from session, client, and
+ request context. ``UserAgentString`` provides methods for collecting the
+ information and ``to_string`` for assembling it into the standardized
+ string format.
+
+ Example usage:
+
+ ua_session = UserAgentString.from_environment()
+ ua_session.set_session_config(...)
+ ua_client = ua_session.with_client_config(Config(...))
+ ua_string = ua_request.to_string()
+
+ For testing or when information from all sources is available at the same
+ time, the methods can be chained:
+
+ ua_string = (
+ UserAgentString
+ .from_environment()
+ .set_session_config(...)
+ .with_client_config(Config(...))
+ .to_string()
+ )
+
+ """
+
+ def __init__(
+ self,
+ platform_name,
+ platform_version,
+ platform_machine,
+ python_version,
+ python_implementation,
+ execution_env,
+ crt_version=None,
+ ):
+ """
+ :type platform_name: str
+ :param platform_name: Name of the operating system or equivalent
+ platform name. Should be sourced from :py:meth:`platform.system`.
+ :type platform_version: str
+ :param platform_version: Version of the operating system or equivalent
+ platform name. Should be sourced from :py:meth:`platform.version`.
+ :type platform_machine: str
+ :param platform_version: Processor architecture or machine type. For
+ example "x86_64". Should be sourced from :py:meth:`platform.machine`.
+ :type python_version: str
+ :param python_version: Version of the python implementation as str.
+ Should be sourced from :py:meth:`platform.python_version`.
+ :type python_implementation: str
+ :param python_implementation: Name of the python implementation.
+ Should be sourced from :py:meth:`platform.python_implementation`.
+ :type execution_env: str
+ :param execution_env: The value of the AWS execution environment.
+ Should be sourced from the ``AWS_EXECUTION_ENV` environment
+ variable.
+ :type crt_version: str
+ :param crt_version: Version string of awscrt package, if installed.
+ """
+ self._platform_name = platform_name
+ self._platform_version = platform_version
+ self._platform_machine = platform_machine
+ self._python_version = python_version
+ self._python_implementation = python_implementation
+ self._execution_env = execution_env
+ self._crt_version = crt_version
+
+ # Components that can be added with ``set_session_config()``
+ self._session_user_agent_name = None
+ self._session_user_agent_version = None
+ self._session_user_agent_extra = None
+
+ self._client_config = None
+ self._uses_paginator = None
+ self._uses_waiter = None
+ self._uses_resource = None
+
+ @classmethod
+ def from_environment(cls):
+ crt_version = None
+ if HAS_CRT:
+ crt_version = _get_crt_version() or 'Unknown'
+ return cls(
+ platform_name=platform.system(),
+ platform_version=platform.release(),
+ platform_machine=platform.machine(),
+ python_version=platform.python_version(),
+ python_implementation=platform.python_implementation(),
+ execution_env=os.environ.get('AWS_EXECUTION_ENV'),
+ crt_version=crt_version,
+ )
+
+ def set_session_config(
+ self,
+ session_user_agent_name,
+ session_user_agent_version,
+ session_user_agent_extra,
+ ):
+ """
+ Set the user agent configuration values that apply at session level.
+
+ :param user_agent_name: The user agent name configured in the
+ :py:class:`botocore.session.Session` object. For backwards
+ compatibility, this will always be at the beginning of the
+ User-Agent string, together with ``user_agent_version``.
+ :param user_agent_version: The user agent version configured in the
+ :py:class:`botocore.session.Session` object.
+ :param user_agent_extra: The user agent "extra" configured in the
+ :py:class:`botocore.session.Session` object.
+ """
+ self._session_user_agent_name = session_user_agent_name
+ self._session_user_agent_version = session_user_agent_version
+ self._session_user_agent_extra = session_user_agent_extra
+ return self
+
+ def with_client_config(self, client_config):
+ """
+ Create a copy with all original values and client-specific values.
+
+ :type client_config: botocore.config.Config
+ :param client_config: The client configuration object.
+ """
+ cp = copy(self)
+ cp._client_config = client_config
+ return cp
+
+ def to_string(self):
+ """
+ Build User-Agent header string from the object's properties.
+ """
+ config_ua_override = None
+ if self._client_config:
+ if hasattr(self._client_config, '_supplied_user_agent'):
+ config_ua_override = self._client_config._supplied_user_agent
+ else:
+ config_ua_override = self._client_config.user_agent
+
+ if config_ua_override is not None:
+ return self._build_legacy_ua_string(config_ua_override)
+
+ components = [
+ *self._build_sdk_metadata(),
+ RawStringUserAgentComponent('ua/2.0'),
+ *self._build_os_metadata(),
+ *self._build_architecture_metadata(),
+ *self._build_language_metadata(),
+ *self._build_execution_env_metadata(),
+ *self._build_feature_metadata(),
+ *self._build_config_metadata(),
+ *self._build_app_id(),
+ *self._build_extra(),
+ ]
+
+ components = modify_components(components)
+
+ return ' '.join([comp.to_string() for comp in components])
+
+ def _build_sdk_metadata(self):
+ """
+ Build the SDK name and version component of the User-Agent header.
+
+ For backwards-compatibility both session-level and client-level config
+ of custom tool names are honored. If this removes the Botocore
+ information from the start of the string, Botocore's name and version
+ are included as a separate field with "md" prefix.
+ """
+ sdk_md = []
+ if (
+ self._session_user_agent_name
+ and self._session_user_agent_version
+ and (
+ self._session_user_agent_name != _USERAGENT_SDK_NAME
+ or self._session_user_agent_version != botocore_version
+ )
+ ):
+ sdk_md.extend(
+ [
+ UserAgentComponent(
+ self._session_user_agent_name,
+ self._session_user_agent_version,
+ ),
+ UserAgentComponent(
+ 'md', _USERAGENT_SDK_NAME, botocore_version
+ ),
+ ]
+ )
+ else:
+ sdk_md.append(
+ UserAgentComponent(_USERAGENT_SDK_NAME, botocore_version)
+ )
+
+ if self._crt_version is not None:
+ sdk_md.append(
+ UserAgentComponent('md', 'awscrt', self._crt_version)
+ )
+
+ return sdk_md
+
+ def _build_os_metadata(self):
+ """
+ Build the OS/platform components of the User-Agent header string.
+
+ For recognized platform names that match or map to an entry in the list
+ of standardized OS names, a single component with prefix "os" is
+ returned. Otherwise, one component "os/other" is returned and a second
+ with prefix "md" and the raw platform name.
+
+ String representations of example return values:
+ * ``os/macos#10.13.6``
+ * ``os/linux``
+ * ``os/other``
+ * ``os/other md/foobar#1.2.3``
+ """
+ if self._platform_name is None:
+ return [UserAgentComponent('os', 'other')]
+
+ plt_name_lower = self._platform_name.lower()
+ if plt_name_lower in _USERAGENT_ALLOWED_OS_NAMES:
+ os_family = plt_name_lower
+ elif plt_name_lower in _USERAGENT_PLATFORM_NAME_MAPPINGS:
+ os_family = _USERAGENT_PLATFORM_NAME_MAPPINGS[plt_name_lower]
+ else:
+ os_family = None
+
+ if os_family is not None:
+ return [
+ UserAgentComponent('os', os_family, self._platform_version)
+ ]
+ else:
+ return [
+ UserAgentComponent('os', 'other'),
+ UserAgentComponent(
+ 'md', self._platform_name, self._platform_version
+ ),
+ ]
+
+ def _build_architecture_metadata(self):
+ """
+ Build architecture component of the User-Agent header string.
+
+ Returns the machine type with prefix "md" and name "arch", if one is
+ available. Common values include "x86_64", "arm64", "i386".
+ """
+ if self._platform_machine:
+ return [
+ UserAgentComponent(
+ 'md', 'arch', self._platform_machine.lower()
+ )
+ ]
+ return []
+
+ def _build_language_metadata(self):
+ """
+ Build the language components of the User-Agent header string.
+
+ Returns the Python version in a component with prefix "lang" and name
+ "python". The Python implementation (e.g. CPython, PyPy) is returned as
+ separate metadata component with prefix "md" and name "pyimpl".
+
+ String representation of an example return value:
+ ``lang/python#3.10.4 md/pyimpl#CPython``
+ """
+ lang_md = [
+ UserAgentComponent('lang', 'python', self._python_version),
+ ]
+ if self._python_implementation:
+ lang_md.append(
+ UserAgentComponent('md', 'pyimpl', self._python_implementation)
+ )
+ return lang_md
+
+ def _build_execution_env_metadata(self):
+ """
+ Build the execution environment component of the User-Agent header.
+
+ Returns a single component prefixed with "exec-env", usually sourced
+ from the environment variable AWS_EXECUTION_ENV.
+ """
+ if self._execution_env:
+ return [UserAgentComponent('exec-env', self._execution_env)]
+ else:
+ return []
+
+ def _build_feature_metadata(self):
+ """
+ Build the features components of the User-Agent header string.
+
+ Botocore currently does not report any features. This may change in a
+ future version.
+ """
+ return []
+
+ def _build_config_metadata(self):
+ """
+ Build the configuration components of the User-Agent header string.
+
+ Returns a list of components with prefix "cfg" followed by the config
+ setting name and its value. Tracked configuration settings may be
+ added or removed in future versions.
+ """
+ if not self._client_config or not self._client_config.retries:
+ return []
+ retry_mode = self._client_config.retries.get('mode')
+ cfg_md = [UserAgentComponent('cfg', 'retry-mode', retry_mode)]
+ if self._client_config.endpoint_discovery_enabled:
+ cfg_md.append(UserAgentComponent('cfg', 'endpoint-discovery'))
+ return cfg_md
+
+ def _build_app_id(self):
+ """
+ Build app component of the User-Agent header string.
+
+ Returns a single component with prefix "app" and value sourced from the
+ ``user_agent_appid`` field in :py:class:`botocore.config.Config` or
+ the ``sdk_ua_app_id`` setting in the shared configuration file, or the
+ ``AWS_SDK_UA_APP_ID`` environment variable. These are the recommended
+ ways for apps built with Botocore to insert their identifer into the
+ User-Agent header.
+ """
+ if self._client_config and self._client_config.user_agent_appid:
+ return [
+ UserAgentComponent('app', self._client_config.user_agent_appid)
+ ]
+ else:
+ return []
+
+ def _build_extra(self):
+ """User agent string components based on legacy "extra" settings.
+
+ Creates components from the session-level and client-level
+ ``user_agent_extra`` setting, if present. Both are passed through
+ verbatim and should be appended at the end of the string.
+
+ Preferred ways to inject application-specific information into
+ botocore's User-Agent header string are the ``user_agent_appid` field
+ in :py:class:`botocore.config.Config`. The ``AWS_SDK_UA_APP_ID``
+ environment variable and the ``sdk_ua_app_id`` configuration file
+ setting are alternative ways to set the ``user_agent_appid`` config.
+ """
+ extra = []
+ if self._session_user_agent_extra:
+ extra.append(
+ RawStringUserAgentComponent(self._session_user_agent_extra)
+ )
+ if self._client_config and self._client_config.user_agent_extra:
+ extra.append(
+ RawStringUserAgentComponent(
+ self._client_config.user_agent_extra
+ )
+ )
+ return extra
+
+ def _build_legacy_ua_string(self, config_ua_override):
+ components = [config_ua_override]
+ if self._session_user_agent_extra:
+ components.append(self._session_user_agent_extra)
+ if self._client_config.user_agent_extra:
+ components.append(self._client_config.user_agent_extra)
+ return ' '.join(components)
+
+
+def _get_crt_version():
+ """
+ This function is considered private and is subject to abrupt breaking
+ changes.
+ """
+ try:
+ import awscrt
+
+ return awscrt.__version__
+ except AttributeError:
+ return None
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/utils.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/utils.py
new file mode 100644
index 0000000000..2cff8adc20
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/utils.py
@@ -0,0 +1,3456 @@
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import base64
+import binascii
+import datetime
+import email.message
+import functools
+import hashlib
+import io
+import logging
+import os
+import random
+import re
+import socket
+import time
+import warnings
+import weakref
+from ipaddress import ip_address
+from pathlib import Path
+from urllib.request import getproxies, proxy_bypass
+
+import dateutil.parser
+from dateutil.tz import tzutc
+from urllib3.exceptions import LocationParseError
+
+import botocore
+import botocore.awsrequest
+import botocore.httpsession
+
+# IP Regexes retained for backwards compatibility
+from botocore.compat import HEX_PAT # noqa: F401
+from botocore.compat import IPV4_PAT # noqa: F401
+from botocore.compat import IPV6_ADDRZ_PAT # noqa: F401
+from botocore.compat import IPV6_PAT # noqa: F401
+from botocore.compat import LS32_PAT # noqa: F401
+from botocore.compat import UNRESERVED_PAT # noqa: F401
+from botocore.compat import ZONE_ID_PAT # noqa: F401
+from botocore.compat import (
+ HAS_CRT,
+ IPV4_RE,
+ IPV6_ADDRZ_RE,
+ MD5_AVAILABLE,
+ UNSAFE_URL_CHARS,
+ OrderedDict,
+ get_md5,
+ get_tzinfo_options,
+ json,
+ quote,
+ urlparse,
+ urlsplit,
+ urlunsplit,
+ zip_longest,
+)
+from botocore.exceptions import (
+ ClientError,
+ ConfigNotFound,
+ ConnectionClosedError,
+ ConnectTimeoutError,
+ EndpointConnectionError,
+ HTTPClientError,
+ InvalidDNSNameError,
+ InvalidEndpointConfigurationError,
+ InvalidExpressionError,
+ InvalidHostLabelError,
+ InvalidIMDSEndpointError,
+ InvalidIMDSEndpointModeError,
+ InvalidRegionError,
+ MetadataRetrievalError,
+ MissingDependencyException,
+ ReadTimeoutError,
+ SSOTokenLoadError,
+ UnsupportedOutpostResourceError,
+ UnsupportedS3AccesspointConfigurationError,
+ UnsupportedS3ArnError,
+ UnsupportedS3ConfigurationError,
+ UnsupportedS3ControlArnError,
+ UnsupportedS3ControlConfigurationError,
+)
+
+logger = logging.getLogger(__name__)
+DEFAULT_METADATA_SERVICE_TIMEOUT = 1
+METADATA_BASE_URL = 'http://169.254.169.254/'
+METADATA_BASE_URL_IPv6 = 'http://[fd00:ec2::254]/'
+METADATA_ENDPOINT_MODES = ('ipv4', 'ipv6')
+
+# These are chars that do not need to be urlencoded.
+# Based on rfc2986, section 2.3
+SAFE_CHARS = '-._~'
+LABEL_RE = re.compile(r'[a-z0-9][a-z0-9\-]*[a-z0-9]')
+RETRYABLE_HTTP_ERRORS = (
+ ReadTimeoutError,
+ EndpointConnectionError,
+ ConnectionClosedError,
+ ConnectTimeoutError,
+)
+S3_ACCELERATE_WHITELIST = ['dualstack']
+# In switching events from using service name / endpoint prefix to service
+# id, we have to preserve compatibility. This maps the instances where either
+# is different than the transformed service id.
+EVENT_ALIASES = {
+ "a4b": "alexa-for-business",
+ "alexaforbusiness": "alexa-for-business",
+ "api.mediatailor": "mediatailor",
+ "api.pricing": "pricing",
+ "api.sagemaker": "sagemaker",
+ "apigateway": "api-gateway",
+ "application-autoscaling": "application-auto-scaling",
+ "appstream2": "appstream",
+ "autoscaling": "auto-scaling",
+ "autoscaling-plans": "auto-scaling-plans",
+ "ce": "cost-explorer",
+ "cloudhsmv2": "cloudhsm-v2",
+ "cloudsearchdomain": "cloudsearch-domain",
+ "cognito-idp": "cognito-identity-provider",
+ "config": "config-service",
+ "cur": "cost-and-usage-report-service",
+ "data.iot": "iot-data-plane",
+ "data.jobs.iot": "iot-jobs-data-plane",
+ "data.mediastore": "mediastore-data",
+ "datapipeline": "data-pipeline",
+ "devicefarm": "device-farm",
+ "devices.iot1click": "iot-1click-devices-service",
+ "directconnect": "direct-connect",
+ "discovery": "application-discovery-service",
+ "dms": "database-migration-service",
+ "ds": "directory-service",
+ "dynamodbstreams": "dynamodb-streams",
+ "elasticbeanstalk": "elastic-beanstalk",
+ "elasticfilesystem": "efs",
+ "elasticloadbalancing": "elastic-load-balancing",
+ "elasticmapreduce": "emr",
+ "elastictranscoder": "elastic-transcoder",
+ "elb": "elastic-load-balancing",
+ "elbv2": "elastic-load-balancing-v2",
+ "email": "ses",
+ "entitlement.marketplace": "marketplace-entitlement-service",
+ "es": "elasticsearch-service",
+ "events": "eventbridge",
+ "cloudwatch-events": "eventbridge",
+ "iot-data": "iot-data-plane",
+ "iot-jobs-data": "iot-jobs-data-plane",
+ "iot1click-devices": "iot-1click-devices-service",
+ "iot1click-projects": "iot-1click-projects",
+ "kinesisanalytics": "kinesis-analytics",
+ "kinesisvideo": "kinesis-video",
+ "lex-models": "lex-model-building-service",
+ "lex-runtime": "lex-runtime-service",
+ "logs": "cloudwatch-logs",
+ "machinelearning": "machine-learning",
+ "marketplace-entitlement": "marketplace-entitlement-service",
+ "marketplacecommerceanalytics": "marketplace-commerce-analytics",
+ "metering.marketplace": "marketplace-metering",
+ "meteringmarketplace": "marketplace-metering",
+ "mgh": "migration-hub",
+ "models.lex": "lex-model-building-service",
+ "monitoring": "cloudwatch",
+ "mturk-requester": "mturk",
+ "opsworks-cm": "opsworkscm",
+ "projects.iot1click": "iot-1click-projects",
+ "resourcegroupstaggingapi": "resource-groups-tagging-api",
+ "route53": "route-53",
+ "route53domains": "route-53-domains",
+ "runtime.lex": "lex-runtime-service",
+ "runtime.sagemaker": "sagemaker-runtime",
+ "sdb": "simpledb",
+ "secretsmanager": "secrets-manager",
+ "serverlessrepo": "serverlessapplicationrepository",
+ "servicecatalog": "service-catalog",
+ "states": "sfn",
+ "stepfunctions": "sfn",
+ "storagegateway": "storage-gateway",
+ "streams.dynamodb": "dynamodb-streams",
+ "tagging": "resource-groups-tagging-api",
+}
+
+
+# This pattern can be used to detect if a header is a flexible checksum header
+CHECKSUM_HEADER_PATTERN = re.compile(
+ r'^X-Amz-Checksum-([a-z0-9]*)$',
+ flags=re.IGNORECASE,
+)
+
+
+def ensure_boolean(val):
+ """Ensures a boolean value if a string or boolean is provided
+
+ For strings, the value for True/False is case insensitive
+ """
+ if isinstance(val, bool):
+ return val
+ elif isinstance(val, str):
+ return val.lower() == 'true'
+ else:
+ return False
+
+
+def resolve_imds_endpoint_mode(session):
+ """Resolving IMDS endpoint mode to either IPv6 or IPv4.
+
+ ec2_metadata_service_endpoint_mode takes precedence over imds_use_ipv6.
+ """
+ endpoint_mode = session.get_config_variable(
+ 'ec2_metadata_service_endpoint_mode'
+ )
+ if endpoint_mode is not None:
+ lendpoint_mode = endpoint_mode.lower()
+ if lendpoint_mode not in METADATA_ENDPOINT_MODES:
+ error_msg_kwargs = {
+ 'mode': endpoint_mode,
+ 'valid_modes': METADATA_ENDPOINT_MODES,
+ }
+ raise InvalidIMDSEndpointModeError(**error_msg_kwargs)
+ return lendpoint_mode
+ elif session.get_config_variable('imds_use_ipv6'):
+ return 'ipv6'
+ return 'ipv4'
+
+
+def is_json_value_header(shape):
+ """Determines if the provided shape is the special header type jsonvalue.
+
+ :type shape: botocore.shape
+ :param shape: Shape to be inspected for the jsonvalue trait.
+
+ :return: True if this type is a jsonvalue, False otherwise
+ :rtype: Bool
+ """
+ return (
+ hasattr(shape, 'serialization')
+ and shape.serialization.get('jsonvalue', False)
+ and shape.serialization.get('location') == 'header'
+ and shape.type_name == 'string'
+ )
+
+
+def has_header(header_name, headers):
+ """Case-insensitive check for header key."""
+ if header_name is None:
+ return False
+ elif isinstance(headers, botocore.awsrequest.HeadersDict):
+ return header_name in headers
+ else:
+ return header_name.lower() in [key.lower() for key in headers.keys()]
+
+
+def get_service_module_name(service_model):
+ """Returns the module name for a service
+
+ This is the value used in both the documentation and client class name
+ """
+ name = service_model.metadata.get(
+ 'serviceAbbreviation',
+ service_model.metadata.get(
+ 'serviceFullName', service_model.service_name
+ ),
+ )
+ name = name.replace('Amazon', '')
+ name = name.replace('AWS', '')
+ name = re.sub(r'\W+', '', name)
+ return name
+
+
+def normalize_url_path(path):
+ if not path:
+ return '/'
+ return remove_dot_segments(path)
+
+
+def normalize_boolean(val):
+ """Returns None if val is None, otherwise ensure value
+ converted to boolean"""
+ if val is None:
+ return val
+ else:
+ return ensure_boolean(val)
+
+
+def remove_dot_segments(url):
+ # RFC 3986, section 5.2.4 "Remove Dot Segments"
+ # Also, AWS services require consecutive slashes to be removed,
+ # so that's done here as well
+ if not url:
+ return ''
+ input_url = url.split('/')
+ output_list = []
+ for x in input_url:
+ if x and x != '.':
+ if x == '..':
+ if output_list:
+ output_list.pop()
+ else:
+ output_list.append(x)
+
+ if url[0] == '/':
+ first = '/'
+ else:
+ first = ''
+ if url[-1] == '/' and output_list:
+ last = '/'
+ else:
+ last = ''
+ return first + '/'.join(output_list) + last
+
+
+def validate_jmespath_for_set(expression):
+ # Validates a limited jmespath expression to determine if we can set a
+ # value based on it. Only works with dotted paths.
+ if not expression or expression == '.':
+ raise InvalidExpressionError(expression=expression)
+
+ for invalid in ['[', ']', '*']:
+ if invalid in expression:
+ raise InvalidExpressionError(expression=expression)
+
+
+def set_value_from_jmespath(source, expression, value, is_first=True):
+ # This takes a (limited) jmespath-like expression & can set a value based
+ # on it.
+ # Limitations:
+ # * Only handles dotted lookups
+ # * No offsets/wildcards/slices/etc.
+ if is_first:
+ validate_jmespath_for_set(expression)
+
+ bits = expression.split('.', 1)
+ current_key, remainder = bits[0], bits[1] if len(bits) > 1 else ''
+
+ if not current_key:
+ raise InvalidExpressionError(expression=expression)
+
+ if remainder:
+ if current_key not in source:
+ # We've got something in the expression that's not present in the
+ # source (new key). If there's any more bits, we'll set the key
+ # with an empty dictionary.
+ source[current_key] = {}
+
+ return set_value_from_jmespath(
+ source[current_key], remainder, value, is_first=False
+ )
+
+ # If we're down to a single key, set it.
+ source[current_key] = value
+
+
+def is_global_accesspoint(context):
+ """Determine if request is intended for an MRAP accesspoint."""
+ s3_accesspoint = context.get('s3_accesspoint', {})
+ is_global = s3_accesspoint.get('region') == ''
+ return is_global
+
+
+class _RetriesExceededError(Exception):
+ """Internal exception used when the number of retries are exceeded."""
+
+ pass
+
+
+class BadIMDSRequestError(Exception):
+ def __init__(self, request):
+ self.request = request
+
+
+class IMDSFetcher:
+ _RETRIES_EXCEEDED_ERROR_CLS = _RetriesExceededError
+ _TOKEN_PATH = 'latest/api/token'
+ _TOKEN_TTL = '21600'
+
+ def __init__(
+ self,
+ timeout=DEFAULT_METADATA_SERVICE_TIMEOUT,
+ num_attempts=1,
+ base_url=METADATA_BASE_URL,
+ env=None,
+ user_agent=None,
+ config=None,
+ ):
+ self._timeout = timeout
+ self._num_attempts = num_attempts
+ if config is None:
+ config = {}
+ self._base_url = self._select_base_url(base_url, config)
+ self._config = config
+
+ if env is None:
+ env = os.environ.copy()
+ self._disabled = (
+ env.get('AWS_EC2_METADATA_DISABLED', 'false').lower() == 'true'
+ )
+ self._imds_v1_disabled = config.get('ec2_metadata_v1_disabled')
+ self._user_agent = user_agent
+ self._session = botocore.httpsession.URLLib3Session(
+ timeout=self._timeout,
+ proxies=get_environ_proxies(self._base_url),
+ )
+
+ def get_base_url(self):
+ return self._base_url
+
+ def _select_base_url(self, base_url, config):
+ if config is None:
+ config = {}
+
+ requires_ipv6 = (
+ config.get('ec2_metadata_service_endpoint_mode') == 'ipv6'
+ )
+ custom_metadata_endpoint = config.get('ec2_metadata_service_endpoint')
+
+ if requires_ipv6 and custom_metadata_endpoint:
+ logger.warning(
+ "Custom endpoint and IMDS_USE_IPV6 are both set. Using custom endpoint."
+ )
+
+ chosen_base_url = None
+
+ if base_url != METADATA_BASE_URL:
+ chosen_base_url = base_url
+ elif custom_metadata_endpoint:
+ chosen_base_url = custom_metadata_endpoint
+ elif requires_ipv6:
+ chosen_base_url = METADATA_BASE_URL_IPv6
+ else:
+ chosen_base_url = METADATA_BASE_URL
+
+ logger.debug("IMDS ENDPOINT: %s" % chosen_base_url)
+ if not is_valid_uri(chosen_base_url):
+ raise InvalidIMDSEndpointError(endpoint=chosen_base_url)
+
+ return chosen_base_url
+
+ def _construct_url(self, path):
+ sep = ''
+ if self._base_url and not self._base_url.endswith('/'):
+ sep = '/'
+ return f'{self._base_url}{sep}{path}'
+
+ def _fetch_metadata_token(self):
+ self._assert_enabled()
+ url = self._construct_url(self._TOKEN_PATH)
+ headers = {
+ 'x-aws-ec2-metadata-token-ttl-seconds': self._TOKEN_TTL,
+ }
+ self._add_user_agent(headers)
+ request = botocore.awsrequest.AWSRequest(
+ method='PUT', url=url, headers=headers
+ )
+ for i in range(self._num_attempts):
+ try:
+ response = self._session.send(request.prepare())
+ if response.status_code == 200:
+ return response.text
+ elif response.status_code in (404, 403, 405):
+ return None
+ elif response.status_code in (400,):
+ raise BadIMDSRequestError(request)
+ except ReadTimeoutError:
+ return None
+ except RETRYABLE_HTTP_ERRORS as e:
+ logger.debug(
+ "Caught retryable HTTP exception while making metadata "
+ "service request to %s: %s",
+ url,
+ e,
+ exc_info=True,
+ )
+ except HTTPClientError as e:
+ if isinstance(e.kwargs.get('error'), LocationParseError):
+ raise InvalidIMDSEndpointError(endpoint=url, error=e)
+ else:
+ raise
+ return None
+
+ def _get_request(self, url_path, retry_func, token=None):
+ """Make a get request to the Instance Metadata Service.
+
+ :type url_path: str
+ :param url_path: The path component of the URL to make a get request.
+ This arg is appended to the base_url that was provided in the
+ initializer.
+
+ :type retry_func: callable
+ :param retry_func: A function that takes the response as an argument
+ and determines if it needs to retry. By default empty and non
+ 200 OK responses are retried.
+
+ :type token: str
+ :param token: Metadata token to send along with GET requests to IMDS.
+ """
+ self._assert_enabled()
+ if not token:
+ self._assert_v1_enabled()
+ if retry_func is None:
+ retry_func = self._default_retry
+ url = self._construct_url(url_path)
+ headers = {}
+ if token is not None:
+ headers['x-aws-ec2-metadata-token'] = token
+ self._add_user_agent(headers)
+ for i in range(self._num_attempts):
+ try:
+ request = botocore.awsrequest.AWSRequest(
+ method='GET', url=url, headers=headers
+ )
+ response = self._session.send(request.prepare())
+ if not retry_func(response):
+ return response
+ except RETRYABLE_HTTP_ERRORS as e:
+ logger.debug(
+ "Caught retryable HTTP exception while making metadata "
+ "service request to %s: %s",
+ url,
+ e,
+ exc_info=True,
+ )
+ raise self._RETRIES_EXCEEDED_ERROR_CLS()
+
+ def _add_user_agent(self, headers):
+ if self._user_agent is not None:
+ headers['User-Agent'] = self._user_agent
+
+ def _assert_enabled(self):
+ if self._disabled:
+ logger.debug("Access to EC2 metadata has been disabled.")
+ raise self._RETRIES_EXCEEDED_ERROR_CLS()
+
+ def _assert_v1_enabled(self):
+ if self._imds_v1_disabled:
+ raise MetadataRetrievalError(
+ error_msg="Unable to retrieve token for use in IMDSv2 call and IMDSv1 has been disabled"
+ )
+
+ def _default_retry(self, response):
+ return self._is_non_ok_response(response) or self._is_empty(response)
+
+ def _is_non_ok_response(self, response):
+ if response.status_code != 200:
+ self._log_imds_response(response, 'non-200', log_body=True)
+ return True
+ return False
+
+ def _is_empty(self, response):
+ if not response.content:
+ self._log_imds_response(response, 'no body', log_body=True)
+ return True
+ return False
+
+ def _log_imds_response(self, response, reason_to_log, log_body=False):
+ statement = (
+ "Metadata service returned %s response "
+ "with status code of %s for url: %s"
+ )
+ logger_args = [reason_to_log, response.status_code, response.url]
+ if log_body:
+ statement += ", content body: %s"
+ logger_args.append(response.content)
+ logger.debug(statement, *logger_args)
+
+
+class InstanceMetadataFetcher(IMDSFetcher):
+ _URL_PATH = 'latest/meta-data/iam/security-credentials/'
+ _REQUIRED_CREDENTIAL_FIELDS = [
+ 'AccessKeyId',
+ 'SecretAccessKey',
+ 'Token',
+ 'Expiration',
+ ]
+
+ def retrieve_iam_role_credentials(self):
+ try:
+ token = self._fetch_metadata_token()
+ role_name = self._get_iam_role(token)
+ credentials = self._get_credentials(role_name, token)
+ if self._contains_all_credential_fields(credentials):
+ credentials = {
+ 'role_name': role_name,
+ 'access_key': credentials['AccessKeyId'],
+ 'secret_key': credentials['SecretAccessKey'],
+ 'token': credentials['Token'],
+ 'expiry_time': credentials['Expiration'],
+ }
+ self._evaluate_expiration(credentials)
+ return credentials
+ else:
+ # IMDS can return a 200 response that has a JSON formatted
+ # error message (i.e. if ec2 is not trusted entity for the
+ # attached role). We do not necessarily want to retry for
+ # these and we also do not necessarily want to raise a key
+ # error. So at least log the problematic response and return
+ # an empty dictionary to signal that it was not able to
+ # retrieve credentials. These error will contain both a
+ # Code and Message key.
+ if 'Code' in credentials and 'Message' in credentials:
+ logger.debug(
+ 'Error response received when retrieving'
+ 'credentials: %s.',
+ credentials,
+ )
+ return {}
+ except self._RETRIES_EXCEEDED_ERROR_CLS:
+ logger.debug(
+ "Max number of attempts exceeded (%s) when "
+ "attempting to retrieve data from metadata service.",
+ self._num_attempts,
+ )
+ except BadIMDSRequestError as e:
+ logger.debug("Bad IMDS request: %s", e.request)
+ return {}
+
+ def _get_iam_role(self, token=None):
+ return self._get_request(
+ url_path=self._URL_PATH,
+ retry_func=self._needs_retry_for_role_name,
+ token=token,
+ ).text
+
+ def _get_credentials(self, role_name, token=None):
+ r = self._get_request(
+ url_path=self._URL_PATH + role_name,
+ retry_func=self._needs_retry_for_credentials,
+ token=token,
+ )
+ return json.loads(r.text)
+
+ def _is_invalid_json(self, response):
+ try:
+ json.loads(response.text)
+ return False
+ except ValueError:
+ self._log_imds_response(response, 'invalid json')
+ return True
+
+ def _needs_retry_for_role_name(self, response):
+ return self._is_non_ok_response(response) or self._is_empty(response)
+
+ def _needs_retry_for_credentials(self, response):
+ return (
+ self._is_non_ok_response(response)
+ or self._is_empty(response)
+ or self._is_invalid_json(response)
+ )
+
+ def _contains_all_credential_fields(self, credentials):
+ for field in self._REQUIRED_CREDENTIAL_FIELDS:
+ if field not in credentials:
+ logger.debug(
+ 'Retrieved credentials is missing required field: %s',
+ field,
+ )
+ return False
+ return True
+
+ def _evaluate_expiration(self, credentials):
+ expiration = credentials.get("expiry_time")
+ if expiration is None:
+ return
+ try:
+ expiration = datetime.datetime.strptime(
+ expiration, "%Y-%m-%dT%H:%M:%SZ"
+ )
+ refresh_interval = self._config.get(
+ "ec2_credential_refresh_window", 60 * 10
+ )
+ jitter = random.randint(120, 600) # Between 2 to 10 minutes
+ refresh_interval_with_jitter = refresh_interval + jitter
+ current_time = datetime.datetime.utcnow()
+ refresh_offset = datetime.timedelta(
+ seconds=refresh_interval_with_jitter
+ )
+ extension_time = expiration - refresh_offset
+ if current_time >= extension_time:
+ new_time = current_time + refresh_offset
+ credentials["expiry_time"] = new_time.strftime(
+ "%Y-%m-%dT%H:%M:%SZ"
+ )
+ logger.info(
+ f"Attempting credential expiration extension due to a "
+ f"credential service availability issue. A refresh of "
+ f"these credentials will be attempted again within "
+ f"the next {refresh_interval_with_jitter/60:.0f} minutes."
+ )
+ except ValueError:
+ logger.debug(
+ f"Unable to parse expiry_time in {credentials['expiry_time']}"
+ )
+
+
+class IMDSRegionProvider:
+ def __init__(self, session, environ=None, fetcher=None):
+ """Initialize IMDSRegionProvider.
+ :type session: :class:`botocore.session.Session`
+ :param session: The session is needed to look up configuration for
+ how to contact the instance metadata service. Specifically the
+ whether or not it should use the IMDS region at all, and if so how
+ to configure the timeout and number of attempts to reach the
+ service.
+ :type environ: None or dict
+ :param environ: A dictionary of environment variables to use. If
+ ``None`` is the argument then ``os.environ`` will be used by
+ default.
+ :type fecther: :class:`botocore.utils.InstanceMetadataRegionFetcher`
+ :param fetcher: The class to actually handle the fetching of the region
+ from the IMDS. If not provided a default one will be created.
+ """
+ self._session = session
+ if environ is None:
+ environ = os.environ
+ self._environ = environ
+ self._fetcher = fetcher
+
+ def provide(self):
+ """Provide the region value from IMDS."""
+ instance_region = self._get_instance_metadata_region()
+ return instance_region
+
+ def _get_instance_metadata_region(self):
+ fetcher = self._get_fetcher()
+ region = fetcher.retrieve_region()
+ return region
+
+ def _get_fetcher(self):
+ if self._fetcher is None:
+ self._fetcher = self._create_fetcher()
+ return self._fetcher
+
+ def _create_fetcher(self):
+ metadata_timeout = self._session.get_config_variable(
+ 'metadata_service_timeout'
+ )
+ metadata_num_attempts = self._session.get_config_variable(
+ 'metadata_service_num_attempts'
+ )
+ imds_config = {
+ 'ec2_metadata_service_endpoint': self._session.get_config_variable(
+ 'ec2_metadata_service_endpoint'
+ ),
+ 'ec2_metadata_service_endpoint_mode': resolve_imds_endpoint_mode(
+ self._session
+ ),
+ 'ec2_metadata_v1_disabled': self._session.get_config_variable(
+ 'ec2_metadata_v1_disabled'
+ ),
+ }
+ fetcher = InstanceMetadataRegionFetcher(
+ timeout=metadata_timeout,
+ num_attempts=metadata_num_attempts,
+ env=self._environ,
+ user_agent=self._session.user_agent(),
+ config=imds_config,
+ )
+ return fetcher
+
+
+class InstanceMetadataRegionFetcher(IMDSFetcher):
+ _URL_PATH = 'latest/meta-data/placement/availability-zone/'
+
+ def retrieve_region(self):
+ """Get the current region from the instance metadata service.
+ :rvalue: str
+ :returns: The region the current instance is running in or None
+ if the instance metadata service cannot be contacted or does not
+ give a valid response.
+ :rtype: None or str
+ :returns: Returns the region as a string if it is configured to use
+ IMDS as a region source. Otherwise returns ``None``. It will also
+ return ``None`` if it fails to get the region from IMDS due to
+ exhausting its retries or not being able to connect.
+ """
+ try:
+ region = self._get_region()
+ return region
+ except self._RETRIES_EXCEEDED_ERROR_CLS:
+ logger.debug(
+ "Max number of attempts exceeded (%s) when "
+ "attempting to retrieve data from metadata service.",
+ self._num_attempts,
+ )
+ return None
+
+ def _get_region(self):
+ token = self._fetch_metadata_token()
+ response = self._get_request(
+ url_path=self._URL_PATH,
+ retry_func=self._default_retry,
+ token=token,
+ )
+ availability_zone = response.text
+ region = availability_zone[:-1]
+ return region
+
+
+def merge_dicts(dict1, dict2, append_lists=False):
+ """Given two dict, merge the second dict into the first.
+
+ The dicts can have arbitrary nesting.
+
+ :param append_lists: If true, instead of clobbering a list with the new
+ value, append all of the new values onto the original list.
+ """
+ for key in dict2:
+ if isinstance(dict2[key], dict):
+ if key in dict1 and key in dict2:
+ merge_dicts(dict1[key], dict2[key])
+ else:
+ dict1[key] = dict2[key]
+ # If the value is a list and the ``append_lists`` flag is set,
+ # append the new values onto the original list
+ elif isinstance(dict2[key], list) and append_lists:
+ # The value in dict1 must be a list in order to append new
+ # values onto it.
+ if key in dict1 and isinstance(dict1[key], list):
+ dict1[key].extend(dict2[key])
+ else:
+ dict1[key] = dict2[key]
+ else:
+ # At scalar types, we iterate and merge the
+ # current dict that we're on.
+ dict1[key] = dict2[key]
+
+
+def lowercase_dict(original):
+ """Copies the given dictionary ensuring all keys are lowercase strings."""
+ copy = {}
+ for key in original:
+ copy[key.lower()] = original[key]
+ return copy
+
+
+def parse_key_val_file(filename, _open=open):
+ try:
+ with _open(filename) as f:
+ contents = f.read()
+ return parse_key_val_file_contents(contents)
+ except OSError:
+ raise ConfigNotFound(path=filename)
+
+
+def parse_key_val_file_contents(contents):
+ # This was originally extracted from the EC2 credential provider, which was
+ # fairly lenient in its parsing. We only try to parse key/val pairs if
+ # there's a '=' in the line.
+ final = {}
+ for line in contents.splitlines():
+ if '=' not in line:
+ continue
+ key, val = line.split('=', 1)
+ key = key.strip()
+ val = val.strip()
+ final[key] = val
+ return final
+
+
+def percent_encode_sequence(mapping, safe=SAFE_CHARS):
+ """Urlencode a dict or list into a string.
+
+ This is similar to urllib.urlencode except that:
+
+ * It uses quote, and not quote_plus
+ * It has a default list of safe chars that don't need
+ to be encoded, which matches what AWS services expect.
+
+ If any value in the input ``mapping`` is a list type,
+ then each list element wil be serialized. This is the equivalent
+ to ``urlencode``'s ``doseq=True`` argument.
+
+ This function should be preferred over the stdlib
+ ``urlencode()`` function.
+
+ :param mapping: Either a dict to urlencode or a list of
+ ``(key, value)`` pairs.
+
+ """
+ encoded_pairs = []
+ if hasattr(mapping, 'items'):
+ pairs = mapping.items()
+ else:
+ pairs = mapping
+ for key, value in pairs:
+ if isinstance(value, list):
+ for element in value:
+ encoded_pairs.append(
+ f'{percent_encode(key)}={percent_encode(element)}'
+ )
+ else:
+ encoded_pairs.append(
+ f'{percent_encode(key)}={percent_encode(value)}'
+ )
+ return '&'.join(encoded_pairs)
+
+
+def percent_encode(input_str, safe=SAFE_CHARS):
+ """Urlencodes a string.
+
+ Whereas percent_encode_sequence handles taking a dict/sequence and
+ producing a percent encoded string, this function deals only with
+ taking a string (not a dict/sequence) and percent encoding it.
+
+ If given the binary type, will simply URL encode it. If given the
+ text type, will produce the binary type by UTF-8 encoding the
+ text. If given something else, will convert it to the text type
+ first.
+ """
+ # If its not a binary or text string, make it a text string.
+ if not isinstance(input_str, (bytes, str)):
+ input_str = str(input_str)
+ # If it's not bytes, make it bytes by UTF-8 encoding it.
+ if not isinstance(input_str, bytes):
+ input_str = input_str.encode('utf-8')
+ return quote(input_str, safe=safe)
+
+
+def _epoch_seconds_to_datetime(value, tzinfo):
+ """Parse numerical epoch timestamps (seconds since 1970) into a
+ ``datetime.datetime`` in UTC using ``datetime.timedelta``. This is intended
+ as fallback when ``fromtimestamp`` raises ``OverflowError`` or ``OSError``.
+
+ :type value: float or int
+ :param value: The Unix timestamps as number.
+
+ :type tzinfo: callable
+ :param tzinfo: A ``datetime.tzinfo`` class or compatible callable.
+ """
+ epoch_zero = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=tzutc())
+ epoch_zero_localized = epoch_zero.astimezone(tzinfo())
+ return epoch_zero_localized + datetime.timedelta(seconds=value)
+
+
+def _parse_timestamp_with_tzinfo(value, tzinfo):
+ """Parse timestamp with pluggable tzinfo options."""
+ if isinstance(value, (int, float)):
+ # Possibly an epoch time.
+ return datetime.datetime.fromtimestamp(value, tzinfo())
+ else:
+ try:
+ return datetime.datetime.fromtimestamp(float(value), tzinfo())
+ except (TypeError, ValueError):
+ pass
+ try:
+ # In certain cases, a timestamp marked with GMT can be parsed into a
+ # different time zone, so here we provide a context which will
+ # enforce that GMT == UTC.
+ return dateutil.parser.parse(value, tzinfos={'GMT': tzutc()})
+ except (TypeError, ValueError) as e:
+ raise ValueError(f'Invalid timestamp "{value}": {e}')
+
+
+def parse_timestamp(value):
+ """Parse a timestamp into a datetime object.
+
+ Supported formats:
+
+ * iso8601
+ * rfc822
+ * epoch (value is an integer)
+
+ This will return a ``datetime.datetime`` object.
+
+ """
+ tzinfo_options = get_tzinfo_options()
+ for tzinfo in tzinfo_options:
+ try:
+ return _parse_timestamp_with_tzinfo(value, tzinfo)
+ except (OSError, OverflowError) as e:
+ logger.debug(
+ 'Unable to parse timestamp with "%s" timezone info.',
+ tzinfo.__name__,
+ exc_info=e,
+ )
+ # For numeric values attempt fallback to using fromtimestamp-free method.
+ # From Python's ``datetime.datetime.fromtimestamp`` documentation: "This
+ # may raise ``OverflowError``, if the timestamp is out of the range of
+ # values supported by the platform C localtime() function, and ``OSError``
+ # on localtime() failure. It's common for this to be restricted to years
+ # from 1970 through 2038."
+ try:
+ numeric_value = float(value)
+ except (TypeError, ValueError):
+ pass
+ else:
+ try:
+ for tzinfo in tzinfo_options:
+ return _epoch_seconds_to_datetime(numeric_value, tzinfo=tzinfo)
+ except (OSError, OverflowError) as e:
+ logger.debug(
+ 'Unable to parse timestamp using fallback method with "%s" '
+ 'timezone info.',
+ tzinfo.__name__,
+ exc_info=e,
+ )
+ raise RuntimeError(
+ 'Unable to calculate correct timezone offset for "%s"' % value
+ )
+
+
+def parse_to_aware_datetime(value):
+ """Converted the passed in value to a datetime object with tzinfo.
+
+ This function can be used to normalize all timestamp inputs. This
+ function accepts a number of different types of inputs, but
+ will always return a datetime.datetime object with time zone
+ information.
+
+ The input param ``value`` can be one of several types:
+
+ * A datetime object (both naive and aware)
+ * An integer representing the epoch time (can also be a string
+ of the integer, i.e '0', instead of 0). The epoch time is
+ considered to be UTC.
+ * An iso8601 formatted timestamp. This does not need to be
+ a complete timestamp, it can contain just the date portion
+ without the time component.
+
+ The returned value will be a datetime object that will have tzinfo.
+ If no timezone info was provided in the input value, then UTC is
+ assumed, not local time.
+
+ """
+ # This is a general purpose method that handles several cases of
+ # converting the provided value to a string timestamp suitable to be
+ # serialized to an http request. It can handle:
+ # 1) A datetime.datetime object.
+ if isinstance(value, datetime.datetime):
+ datetime_obj = value
+ else:
+ # 2) A string object that's formatted as a timestamp.
+ # We document this as being an iso8601 timestamp, although
+ # parse_timestamp is a bit more flexible.
+ datetime_obj = parse_timestamp(value)
+ if datetime_obj.tzinfo is None:
+ # I think a case would be made that if no time zone is provided,
+ # we should use the local time. However, to restore backwards
+ # compat, the previous behavior was to assume UTC, which is
+ # what we're going to do here.
+ datetime_obj = datetime_obj.replace(tzinfo=tzutc())
+ else:
+ datetime_obj = datetime_obj.astimezone(tzutc())
+ return datetime_obj
+
+
+def datetime2timestamp(dt, default_timezone=None):
+ """Calculate the timestamp based on the given datetime instance.
+
+ :type dt: datetime
+ :param dt: A datetime object to be converted into timestamp
+ :type default_timezone: tzinfo
+ :param default_timezone: If it is provided as None, we treat it as tzutc().
+ But it is only used when dt is a naive datetime.
+ :returns: The timestamp
+ """
+ epoch = datetime.datetime(1970, 1, 1)
+ if dt.tzinfo is None:
+ if default_timezone is None:
+ default_timezone = tzutc()
+ dt = dt.replace(tzinfo=default_timezone)
+ d = dt.replace(tzinfo=None) - dt.utcoffset() - epoch
+ if hasattr(d, "total_seconds"):
+ return d.total_seconds() # Works in Python 3.6+
+ return (
+ d.microseconds + (d.seconds + d.days * 24 * 3600) * 10**6
+ ) / 10**6
+
+
+def calculate_sha256(body, as_hex=False):
+ """Calculate a sha256 checksum.
+
+ This method will calculate the sha256 checksum of a file like
+ object. Note that this method will iterate through the entire
+ file contents. The caller is responsible for ensuring the proper
+ starting position of the file and ``seek()``'ing the file back
+ to its starting location if other consumers need to read from
+ the file like object.
+
+ :param body: Any file like object. The file must be opened
+ in binary mode such that a ``.read()`` call returns bytes.
+ :param as_hex: If True, then the hex digest is returned.
+ If False, then the digest (as binary bytes) is returned.
+
+ :returns: The sha256 checksum
+
+ """
+ checksum = hashlib.sha256()
+ for chunk in iter(lambda: body.read(1024 * 1024), b''):
+ checksum.update(chunk)
+ if as_hex:
+ return checksum.hexdigest()
+ else:
+ return checksum.digest()
+
+
+def calculate_tree_hash(body):
+ """Calculate a tree hash checksum.
+
+ For more information see:
+
+ http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html
+
+ :param body: Any file like object. This has the same constraints as
+ the ``body`` param in calculate_sha256
+
+ :rtype: str
+ :returns: The hex version of the calculated tree hash
+
+ """
+ chunks = []
+ required_chunk_size = 1024 * 1024
+ sha256 = hashlib.sha256
+ for chunk in iter(lambda: body.read(required_chunk_size), b''):
+ chunks.append(sha256(chunk).digest())
+ if not chunks:
+ return sha256(b'').hexdigest()
+ while len(chunks) > 1:
+ new_chunks = []
+ for first, second in _in_pairs(chunks):
+ if second is not None:
+ new_chunks.append(sha256(first + second).digest())
+ else:
+ # We're at the end of the list and there's no pair left.
+ new_chunks.append(first)
+ chunks = new_chunks
+ return binascii.hexlify(chunks[0]).decode('ascii')
+
+
+def _in_pairs(iterable):
+ # Creates iterator that iterates over the list in pairs:
+ # for a, b in _in_pairs([0, 1, 2, 3, 4]):
+ # print(a, b)
+ #
+ # will print:
+ # 0, 1
+ # 2, 3
+ # 4, None
+ shared_iter = iter(iterable)
+ # Note that zip_longest is a compat import that uses
+ # the itertools izip_longest. This creates an iterator,
+ # this call below does _not_ immediately create the list
+ # of pairs.
+ return zip_longest(shared_iter, shared_iter)
+
+
+class CachedProperty:
+ """A read only property that caches the initially computed value.
+
+ This descriptor will only call the provided ``fget`` function once.
+ Subsequent access to this property will return the cached value.
+
+ """
+
+ def __init__(self, fget):
+ self._fget = fget
+
+ def __get__(self, obj, cls):
+ if obj is None:
+ return self
+ else:
+ computed_value = self._fget(obj)
+ obj.__dict__[self._fget.__name__] = computed_value
+ return computed_value
+
+
+class ArgumentGenerator:
+ """Generate sample input based on a shape model.
+
+ This class contains a ``generate_skeleton`` method that will take
+ an input/output shape (created from ``botocore.model``) and generate
+ a sample dictionary corresponding to the input/output shape.
+
+ The specific values used are place holder values. For strings either an
+ empty string or the member name can be used, for numbers 0 or 0.0 is used.
+ The intended usage of this class is to generate the *shape* of the input
+ structure.
+
+ This can be useful for operations that have complex input shapes.
+ This allows a user to just fill in the necessary data instead of
+ worrying about the specific structure of the input arguments.
+
+ Example usage::
+
+ s = botocore.session.get_session()
+ ddb = s.get_service_model('dynamodb')
+ arg_gen = ArgumentGenerator()
+ sample_input = arg_gen.generate_skeleton(
+ ddb.operation_model('CreateTable').input_shape)
+ print("Sample input for dynamodb.CreateTable: %s" % sample_input)
+
+ """
+
+ def __init__(self, use_member_names=False):
+ self._use_member_names = use_member_names
+
+ def generate_skeleton(self, shape):
+ """Generate a sample input.
+
+ :type shape: ``botocore.model.Shape``
+ :param shape: The input shape.
+
+ :return: The generated skeleton input corresponding to the
+ provided input shape.
+
+ """
+ stack = []
+ return self._generate_skeleton(shape, stack)
+
+ def _generate_skeleton(self, shape, stack, name=''):
+ stack.append(shape.name)
+ try:
+ if shape.type_name == 'structure':
+ return self._generate_type_structure(shape, stack)
+ elif shape.type_name == 'list':
+ return self._generate_type_list(shape, stack)
+ elif shape.type_name == 'map':
+ return self._generate_type_map(shape, stack)
+ elif shape.type_name == 'string':
+ if self._use_member_names:
+ return name
+ if shape.enum:
+ return random.choice(shape.enum)
+ return ''
+ elif shape.type_name in ['integer', 'long']:
+ return 0
+ elif shape.type_name in ['float', 'double']:
+ return 0.0
+ elif shape.type_name == 'boolean':
+ return True
+ elif shape.type_name == 'timestamp':
+ return datetime.datetime(1970, 1, 1, 0, 0, 0)
+ finally:
+ stack.pop()
+
+ def _generate_type_structure(self, shape, stack):
+ if stack.count(shape.name) > 1:
+ return {}
+ skeleton = OrderedDict()
+ for member_name, member_shape in shape.members.items():
+ skeleton[member_name] = self._generate_skeleton(
+ member_shape, stack, name=member_name
+ )
+ return skeleton
+
+ def _generate_type_list(self, shape, stack):
+ # For list elements we've arbitrarily decided to
+ # return two elements for the skeleton list.
+ name = ''
+ if self._use_member_names:
+ name = shape.member.name
+ return [
+ self._generate_skeleton(shape.member, stack, name),
+ ]
+
+ def _generate_type_map(self, shape, stack):
+ key_shape = shape.key
+ value_shape = shape.value
+ assert key_shape.type_name == 'string'
+ return OrderedDict(
+ [
+ ('KeyName', self._generate_skeleton(value_shape, stack)),
+ ]
+ )
+
+
+def is_valid_ipv6_endpoint_url(endpoint_url):
+ if UNSAFE_URL_CHARS.intersection(endpoint_url):
+ return False
+ hostname = f'[{urlparse(endpoint_url).hostname}]'
+ return IPV6_ADDRZ_RE.match(hostname) is not None
+
+
+def is_valid_ipv4_endpoint_url(endpoint_url):
+ hostname = urlparse(endpoint_url).hostname
+ return IPV4_RE.match(hostname) is not None
+
+
+def is_valid_endpoint_url(endpoint_url):
+ """Verify the endpoint_url is valid.
+
+ :type endpoint_url: string
+ :param endpoint_url: An endpoint_url. Must have at least a scheme
+ and a hostname.
+
+ :return: True if the endpoint url is valid. False otherwise.
+
+ """
+ # post-bpo-43882 urlsplit() strips unsafe characters from URL, causing
+ # it to pass hostname validation below. Detect them early to fix that.
+ if UNSAFE_URL_CHARS.intersection(endpoint_url):
+ return False
+ parts = urlsplit(endpoint_url)
+ hostname = parts.hostname
+ if hostname is None:
+ return False
+ if len(hostname) > 255:
+ return False
+ if hostname[-1] == ".":
+ hostname = hostname[:-1]
+ allowed = re.compile(
+ r"^((?!-)[A-Z\d-]{1,63}(? 63:
+ # Wrong length
+ return False
+ match = LABEL_RE.match(bucket_name)
+ if match is None or match.end() != len(bucket_name):
+ return False
+ return True
+
+
+def fix_s3_host(
+ request,
+ signature_version,
+ region_name,
+ default_endpoint_url=None,
+ **kwargs,
+):
+ """
+ This handler looks at S3 requests just before they are signed.
+ If there is a bucket name on the path (true for everything except
+ ListAllBuckets) it checks to see if that bucket name conforms to
+ the DNS naming conventions. If it does, it alters the request to
+ use ``virtual hosting`` style addressing rather than ``path-style``
+ addressing.
+
+ """
+ if request.context.get('use_global_endpoint', False):
+ default_endpoint_url = 's3.amazonaws.com'
+ try:
+ switch_to_virtual_host_style(
+ request, signature_version, default_endpoint_url
+ )
+ except InvalidDNSNameError as e:
+ bucket_name = e.kwargs['bucket_name']
+ logger.debug(
+ 'Not changing URI, bucket is not DNS compatible: %s', bucket_name
+ )
+
+
+def switch_to_virtual_host_style(
+ request, signature_version, default_endpoint_url=None, **kwargs
+):
+ """
+ This is a handler to force virtual host style s3 addressing no matter
+ the signature version (which is taken in consideration for the default
+ case). If the bucket is not DNS compatible an InvalidDNSName is thrown.
+
+ :param request: A AWSRequest object that is about to be sent.
+ :param signature_version: The signature version to sign with
+ :param default_endpoint_url: The endpoint to use when switching to a
+ virtual style. If None is supplied, the virtual host will be
+ constructed from the url of the request.
+ """
+ if request.auth_path is not None:
+ # The auth_path has already been applied (this may be a
+ # retried request). We don't need to perform this
+ # customization again.
+ return
+ elif _is_get_bucket_location_request(request):
+ # For the GetBucketLocation response, we should not be using
+ # the virtual host style addressing so we can avoid any sigv4
+ # issues.
+ logger.debug(
+ "Request is GetBucketLocation operation, not checking "
+ "for DNS compatibility."
+ )
+ return
+ parts = urlsplit(request.url)
+ request.auth_path = parts.path
+ path_parts = parts.path.split('/')
+
+ # Retrieve what the endpoint we will be prepending the bucket name to.
+ if default_endpoint_url is None:
+ default_endpoint_url = parts.netloc
+
+ if len(path_parts) > 1:
+ bucket_name = path_parts[1]
+ if not bucket_name:
+ # If the bucket name is empty we should not be checking for
+ # dns compatibility.
+ return
+ logger.debug('Checking for DNS compatible bucket for: %s', request.url)
+ if check_dns_name(bucket_name):
+ # If the operation is on a bucket, the auth_path must be
+ # terminated with a '/' character.
+ if len(path_parts) == 2:
+ if request.auth_path[-1] != '/':
+ request.auth_path += '/'
+ path_parts.remove(bucket_name)
+ # At the very least the path must be a '/', such as with the
+ # CreateBucket operation when DNS style is being used. If this
+ # is not used you will get an empty path which is incorrect.
+ path = '/'.join(path_parts) or '/'
+ global_endpoint = default_endpoint_url
+ host = bucket_name + '.' + global_endpoint
+ new_tuple = (parts.scheme, host, path, parts.query, '')
+ new_uri = urlunsplit(new_tuple)
+ request.url = new_uri
+ logger.debug('URI updated to: %s', new_uri)
+ else:
+ raise InvalidDNSNameError(bucket_name=bucket_name)
+
+
+def _is_get_bucket_location_request(request):
+ return request.url.endswith('?location')
+
+
+def instance_cache(func):
+ """Method decorator for caching method calls to a single instance.
+
+ **This is not a general purpose caching decorator.**
+
+ In order to use this, you *must* provide an ``_instance_cache``
+ attribute on the instance.
+
+ This decorator is used to cache method calls. The cache is only
+ scoped to a single instance though such that multiple instances
+ will maintain their own cache. In order to keep things simple,
+ this decorator requires that you provide an ``_instance_cache``
+ attribute on your instance.
+
+ """
+ func_name = func.__name__
+
+ @functools.wraps(func)
+ def _cache_guard(self, *args, **kwargs):
+ cache_key = (func_name, args)
+ if kwargs:
+ kwarg_items = tuple(sorted(kwargs.items()))
+ cache_key = (func_name, args, kwarg_items)
+ result = self._instance_cache.get(cache_key)
+ if result is not None:
+ return result
+ result = func(self, *args, **kwargs)
+ self._instance_cache[cache_key] = result
+ return result
+
+ return _cache_guard
+
+
+def lru_cache_weakref(*cache_args, **cache_kwargs):
+ """
+ Version of functools.lru_cache that stores a weak reference to ``self``.
+
+ Serves the same purpose as :py:func:`instance_cache` but uses Python's
+ functools implementation which offers ``max_size`` and ``typed`` properties.
+
+ lru_cache is a global cache even when used on a method. The cache's
+ reference to ``self`` will prevent garbace collection of the object. This
+ wrapper around functools.lru_cache replaces the reference to ``self`` with
+ a weak reference to not interfere with garbage collection.
+ """
+
+ def wrapper(func):
+ @functools.lru_cache(*cache_args, **cache_kwargs)
+ def func_with_weakref(weakref_to_self, *args, **kwargs):
+ return func(weakref_to_self(), *args, **kwargs)
+
+ @functools.wraps(func)
+ def inner(self, *args, **kwargs):
+ return func_with_weakref(weakref.ref(self), *args, **kwargs)
+
+ inner.cache_info = func_with_weakref.cache_info
+ return inner
+
+ return wrapper
+
+
+def switch_host_s3_accelerate(request, operation_name, **kwargs):
+ """Switches the current s3 endpoint with an S3 Accelerate endpoint"""
+
+ # Note that when registered the switching of the s3 host happens
+ # before it gets changed to virtual. So we are not concerned with ensuring
+ # that the bucket name is translated to the virtual style here and we
+ # can hard code the Accelerate endpoint.
+ parts = urlsplit(request.url).netloc.split('.')
+ parts = [p for p in parts if p in S3_ACCELERATE_WHITELIST]
+ endpoint = 'https://s3-accelerate.'
+ if len(parts) > 0:
+ endpoint += '.'.join(parts) + '.'
+ endpoint += 'amazonaws.com'
+
+ if operation_name in ['ListBuckets', 'CreateBucket', 'DeleteBucket']:
+ return
+ _switch_hosts(request, endpoint, use_new_scheme=False)
+
+
+def switch_host_with_param(request, param_name):
+ """Switches the host using a parameter value from a JSON request body"""
+ request_json = json.loads(request.data.decode('utf-8'))
+ if request_json.get(param_name):
+ new_endpoint = request_json[param_name]
+ _switch_hosts(request, new_endpoint)
+
+
+def _switch_hosts(request, new_endpoint, use_new_scheme=True):
+ final_endpoint = _get_new_endpoint(
+ request.url, new_endpoint, use_new_scheme
+ )
+ request.url = final_endpoint
+
+
+def _get_new_endpoint(original_endpoint, new_endpoint, use_new_scheme=True):
+ new_endpoint_components = urlsplit(new_endpoint)
+ original_endpoint_components = urlsplit(original_endpoint)
+ scheme = original_endpoint_components.scheme
+ if use_new_scheme:
+ scheme = new_endpoint_components.scheme
+ final_endpoint_components = (
+ scheme,
+ new_endpoint_components.netloc,
+ original_endpoint_components.path,
+ original_endpoint_components.query,
+ '',
+ )
+ final_endpoint = urlunsplit(final_endpoint_components)
+ logger.debug(f'Updating URI from {original_endpoint} to {final_endpoint}')
+ return final_endpoint
+
+
+def deep_merge(base, extra):
+ """Deeply two dictionaries, overriding existing keys in the base.
+
+ :param base: The base dictionary which will be merged into.
+ :param extra: The dictionary to merge into the base. Keys from this
+ dictionary will take precedence.
+ """
+ for key in extra:
+ # If the key represents a dict on both given dicts, merge the sub-dicts
+ if (
+ key in base
+ and isinstance(base[key], dict)
+ and isinstance(extra[key], dict)
+ ):
+ deep_merge(base[key], extra[key])
+ continue
+
+ # Otherwise, set the key on the base to be the value of the extra.
+ base[key] = extra[key]
+
+
+def hyphenize_service_id(service_id):
+ """Translate the form used for event emitters.
+
+ :param service_id: The service_id to convert.
+ """
+ return service_id.replace(' ', '-').lower()
+
+
+class S3RegionRedirectorv2:
+ """Updated version of S3RegionRedirector for use when
+ EndpointRulesetResolver is in use for endpoint resolution.
+
+ This class is considered private and subject to abrupt breaking changes or
+ removal without prior announcement. Please do not use it directly.
+ """
+
+ def __init__(self, endpoint_bridge, client, cache=None):
+ self._cache = cache or {}
+ self._client = weakref.proxy(client)
+
+ def register(self, event_emitter=None):
+ logger.debug('Registering S3 region redirector handler')
+ emitter = event_emitter or self._client.meta.events
+ emitter.register('needs-retry.s3', self.redirect_from_error)
+ emitter.register(
+ 'before-parameter-build.s3', self.annotate_request_context
+ )
+ emitter.register(
+ 'before-endpoint-resolution.s3', self.redirect_from_cache
+ )
+
+ def redirect_from_error(self, request_dict, response, operation, **kwargs):
+ """
+ An S3 request sent to the wrong region will return an error that
+ contains the endpoint the request should be sent to. This handler
+ will add the redirect information to the signing context and then
+ redirect the request.
+ """
+ if response is None:
+ # This could be none if there was a ConnectionError or other
+ # transport error.
+ return
+
+ redirect_ctx = request_dict.get('context', {}).get('s3_redirect', {})
+ if ArnParser.is_arn(redirect_ctx.get('bucket')):
+ logger.debug(
+ 'S3 request was previously for an Accesspoint ARN, not '
+ 'redirecting.'
+ )
+ return
+
+ if redirect_ctx.get('redirected'):
+ logger.debug(
+ 'S3 request was previously redirected, not redirecting.'
+ )
+ return
+
+ error = response[1].get('Error', {})
+ error_code = error.get('Code')
+ response_metadata = response[1].get('ResponseMetadata', {})
+
+ # We have to account for 400 responses because
+ # if we sign a Head* request with the wrong region,
+ # we'll get a 400 Bad Request but we won't get a
+ # body saying it's an "AuthorizationHeaderMalformed".
+ is_special_head_object = (
+ error_code in ('301', '400') and operation.name == 'HeadObject'
+ )
+ is_special_head_bucket = (
+ error_code in ('301', '400')
+ and operation.name == 'HeadBucket'
+ and 'x-amz-bucket-region'
+ in response_metadata.get('HTTPHeaders', {})
+ )
+ is_wrong_signing_region = (
+ error_code == 'AuthorizationHeaderMalformed' and 'Region' in error
+ )
+ is_redirect_status = response[0] is not None and response[
+ 0
+ ].status_code in (301, 302, 307)
+ is_permanent_redirect = error_code == 'PermanentRedirect'
+ if not any(
+ [
+ is_special_head_object,
+ is_wrong_signing_region,
+ is_permanent_redirect,
+ is_special_head_bucket,
+ is_redirect_status,
+ ]
+ ):
+ return
+
+ bucket = request_dict['context']['s3_redirect']['bucket']
+ client_region = request_dict['context'].get('client_region')
+ new_region = self.get_bucket_region(bucket, response)
+
+ if new_region is None:
+ logger.debug(
+ "S3 client configured for region %s but the bucket %s is not "
+ "in that region and the proper region could not be "
+ "automatically determined." % (client_region, bucket)
+ )
+ return
+
+ logger.debug(
+ "S3 client configured for region %s but the bucket %s is in region"
+ " %s; Please configure the proper region to avoid multiple "
+ "unnecessary redirects and signing attempts."
+ % (client_region, bucket, new_region)
+ )
+ # Adding the new region to _cache will make construct_endpoint() to
+ # use the new region as value for the AWS::Region builtin parameter.
+ self._cache[bucket] = new_region
+
+ # Re-resolve endpoint with new region and modify request_dict with
+ # the new URL, auth scheme, and signing context.
+ ep_resolver = self._client._ruleset_resolver
+ ep_info = ep_resolver.construct_endpoint(
+ operation_model=operation,
+ call_args=request_dict['context']['s3_redirect']['params'],
+ request_context=request_dict['context'],
+ )
+ request_dict['url'] = self.set_request_url(
+ request_dict['url'], ep_info.url
+ )
+ request_dict['context']['s3_redirect']['redirected'] = True
+ auth_schemes = ep_info.properties.get('authSchemes')
+ if auth_schemes is not None:
+ auth_info = ep_resolver.auth_schemes_to_signing_ctx(auth_schemes)
+ auth_type, signing_context = auth_info
+ request_dict['context']['auth_type'] = auth_type
+ request_dict['context']['signing'] = {
+ **request_dict['context'].get('signing', {}),
+ **signing_context,
+ }
+
+ # Return 0 so it doesn't wait to retry
+ return 0
+
+ def get_bucket_region(self, bucket, response):
+ """
+ There are multiple potential sources for the new region to redirect to,
+ but they aren't all universally available for use. This will try to
+ find region from response elements, but will fall back to calling
+ HEAD on the bucket if all else fails.
+
+ :param bucket: The bucket to find the region for. This is necessary if
+ the region is not available in the error response.
+ :param response: A response representing a service request that failed
+ due to incorrect region configuration.
+ """
+ # First try to source the region from the headers.
+ service_response = response[1]
+ response_headers = service_response['ResponseMetadata']['HTTPHeaders']
+ if 'x-amz-bucket-region' in response_headers:
+ return response_headers['x-amz-bucket-region']
+
+ # Next, check the error body
+ region = service_response.get('Error', {}).get('Region', None)
+ if region is not None:
+ return region
+
+ # Finally, HEAD the bucket. No other choice sadly.
+ try:
+ response = self._client.head_bucket(Bucket=bucket)
+ headers = response['ResponseMetadata']['HTTPHeaders']
+ except ClientError as e:
+ headers = e.response['ResponseMetadata']['HTTPHeaders']
+
+ region = headers.get('x-amz-bucket-region', None)
+ return region
+
+ def set_request_url(self, old_url, new_endpoint, **kwargs):
+ """
+ Splice a new endpoint into an existing URL. Note that some endpoints
+ from the the endpoint provider have a path component which will be
+ discarded by this function.
+ """
+ return _get_new_endpoint(old_url, new_endpoint, False)
+
+ def redirect_from_cache(self, builtins, params, **kwargs):
+ """
+ If a bucket name has been redirected before, it is in the cache. This
+ handler will update the AWS::Region endpoint resolver builtin param
+ to use the region from cache instead of the client region to avoid the
+ redirect.
+ """
+ bucket = params.get('Bucket')
+ if bucket is not None and bucket in self._cache:
+ new_region = self._cache.get(bucket)
+ builtins['AWS::Region'] = new_region
+
+ def annotate_request_context(self, params, context, **kwargs):
+ """Store the bucket name in context for later use when redirecting.
+ The bucket name may be an access point ARN or alias.
+ """
+ bucket = params.get('Bucket')
+ context['s3_redirect'] = {
+ 'redirected': False,
+ 'bucket': bucket,
+ 'params': params,
+ }
+
+
+class S3RegionRedirector:
+ """This handler has been replaced by S3RegionRedirectorv2. The original
+ version remains in place for any third-party libraries that import it.
+ """
+
+ def __init__(self, endpoint_bridge, client, cache=None):
+ self._endpoint_resolver = endpoint_bridge
+ self._cache = cache
+ if self._cache is None:
+ self._cache = {}
+
+ # This needs to be a weak ref in order to prevent memory leaks on
+ # python 2.6
+ self._client = weakref.proxy(client)
+
+ warnings.warn(
+ 'The S3RegionRedirector class has been deprecated for a new '
+ 'internal replacement. A future version of botocore may remove '
+ 'this class.',
+ category=FutureWarning,
+ )
+
+ def register(self, event_emitter=None):
+ emitter = event_emitter or self._client.meta.events
+ emitter.register('needs-retry.s3', self.redirect_from_error)
+ emitter.register('before-call.s3', self.set_request_url)
+ emitter.register('before-parameter-build.s3', self.redirect_from_cache)
+
+ def redirect_from_error(self, request_dict, response, operation, **kwargs):
+ """
+ An S3 request sent to the wrong region will return an error that
+ contains the endpoint the request should be sent to. This handler
+ will add the redirect information to the signing context and then
+ redirect the request.
+ """
+ if response is None:
+ # This could be none if there was a ConnectionError or other
+ # transport error.
+ return
+
+ if self._is_s3_accesspoint(request_dict.get('context', {})):
+ logger.debug(
+ 'S3 request was previously to an accesspoint, not redirecting.'
+ )
+ return
+
+ if request_dict.get('context', {}).get('s3_redirected'):
+ logger.debug(
+ 'S3 request was previously redirected, not redirecting.'
+ )
+ return
+
+ error = response[1].get('Error', {})
+ error_code = error.get('Code')
+ response_metadata = response[1].get('ResponseMetadata', {})
+
+ # We have to account for 400 responses because
+ # if we sign a Head* request with the wrong region,
+ # we'll get a 400 Bad Request but we won't get a
+ # body saying it's an "AuthorizationHeaderMalformed".
+ is_special_head_object = (
+ error_code in ('301', '400') and operation.name == 'HeadObject'
+ )
+ is_special_head_bucket = (
+ error_code in ('301', '400')
+ and operation.name == 'HeadBucket'
+ and 'x-amz-bucket-region'
+ in response_metadata.get('HTTPHeaders', {})
+ )
+ is_wrong_signing_region = (
+ error_code == 'AuthorizationHeaderMalformed' and 'Region' in error
+ )
+ is_redirect_status = response[0] is not None and response[
+ 0
+ ].status_code in (301, 302, 307)
+ is_permanent_redirect = error_code == 'PermanentRedirect'
+ if not any(
+ [
+ is_special_head_object,
+ is_wrong_signing_region,
+ is_permanent_redirect,
+ is_special_head_bucket,
+ is_redirect_status,
+ ]
+ ):
+ return
+
+ bucket = request_dict['context']['signing']['bucket']
+ client_region = request_dict['context'].get('client_region')
+ new_region = self.get_bucket_region(bucket, response)
+
+ if new_region is None:
+ logger.debug(
+ "S3 client configured for region %s but the bucket %s is not "
+ "in that region and the proper region could not be "
+ "automatically determined." % (client_region, bucket)
+ )
+ return
+
+ logger.debug(
+ "S3 client configured for region %s but the bucket %s is in region"
+ " %s; Please configure the proper region to avoid multiple "
+ "unnecessary redirects and signing attempts."
+ % (client_region, bucket, new_region)
+ )
+ endpoint = self._endpoint_resolver.resolve('s3', new_region)
+ endpoint = endpoint['endpoint_url']
+
+ signing_context = {
+ 'region': new_region,
+ 'bucket': bucket,
+ 'endpoint': endpoint,
+ }
+ request_dict['context']['signing'] = signing_context
+
+ self._cache[bucket] = signing_context
+ self.set_request_url(request_dict, request_dict['context'])
+
+ request_dict['context']['s3_redirected'] = True
+
+ # Return 0 so it doesn't wait to retry
+ return 0
+
+ def get_bucket_region(self, bucket, response):
+ """
+ There are multiple potential sources for the new region to redirect to,
+ but they aren't all universally available for use. This will try to
+ find region from response elements, but will fall back to calling
+ HEAD on the bucket if all else fails.
+
+ :param bucket: The bucket to find the region for. This is necessary if
+ the region is not available in the error response.
+ :param response: A response representing a service request that failed
+ due to incorrect region configuration.
+ """
+ # First try to source the region from the headers.
+ service_response = response[1]
+ response_headers = service_response['ResponseMetadata']['HTTPHeaders']
+ if 'x-amz-bucket-region' in response_headers:
+ return response_headers['x-amz-bucket-region']
+
+ # Next, check the error body
+ region = service_response.get('Error', {}).get('Region', None)
+ if region is not None:
+ return region
+
+ # Finally, HEAD the bucket. No other choice sadly.
+ try:
+ response = self._client.head_bucket(Bucket=bucket)
+ headers = response['ResponseMetadata']['HTTPHeaders']
+ except ClientError as e:
+ headers = e.response['ResponseMetadata']['HTTPHeaders']
+
+ region = headers.get('x-amz-bucket-region', None)
+ return region
+
+ def set_request_url(self, params, context, **kwargs):
+ endpoint = context.get('signing', {}).get('endpoint', None)
+ if endpoint is not None:
+ params['url'] = _get_new_endpoint(params['url'], endpoint, False)
+
+ def redirect_from_cache(self, params, context, **kwargs):
+ """
+ This handler retrieves a given bucket's signing context from the cache
+ and adds it into the request context.
+ """
+ if self._is_s3_accesspoint(context):
+ return
+ bucket = params.get('Bucket')
+ signing_context = self._cache.get(bucket)
+ if signing_context is not None:
+ context['signing'] = signing_context
+ else:
+ context['signing'] = {'bucket': bucket}
+
+ def _is_s3_accesspoint(self, context):
+ return 's3_accesspoint' in context
+
+
+class InvalidArnException(ValueError):
+ pass
+
+
+class ArnParser:
+ def parse_arn(self, arn):
+ arn_parts = arn.split(':', 5)
+ if len(arn_parts) < 6:
+ raise InvalidArnException(
+ 'Provided ARN: %s must be of the format: '
+ 'arn:partition:service:region:account:resource' % arn
+ )
+ return {
+ 'partition': arn_parts[1],
+ 'service': arn_parts[2],
+ 'region': arn_parts[3],
+ 'account': arn_parts[4],
+ 'resource': arn_parts[5],
+ }
+
+ @staticmethod
+ def is_arn(value):
+ if not isinstance(value, str) or not value.startswith('arn:'):
+ return False
+ arn_parser = ArnParser()
+ try:
+ arn_parser.parse_arn(value)
+ return True
+ except InvalidArnException:
+ return False
+
+
+class S3ArnParamHandler:
+ _RESOURCE_REGEX = re.compile(
+ r'^(?Paccesspoint|outpost)[/:](?P.+)$'
+ )
+ _OUTPOST_RESOURCE_REGEX = re.compile(
+ r'^(?P[a-zA-Z0-9\-]{1,63})[/:]accesspoint[/:]'
+ r'(?P[a-zA-Z0-9\-]{1,63}$)'
+ )
+ _BLACKLISTED_OPERATIONS = ['CreateBucket']
+
+ def __init__(self, arn_parser=None):
+ self._arn_parser = arn_parser
+ if arn_parser is None:
+ self._arn_parser = ArnParser()
+
+ def register(self, event_emitter):
+ event_emitter.register('before-parameter-build.s3', self.handle_arn)
+
+ def handle_arn(self, params, model, context, **kwargs):
+ if model.name in self._BLACKLISTED_OPERATIONS:
+ return
+ arn_details = self._get_arn_details_from_bucket_param(params)
+ if arn_details is None:
+ return
+ if arn_details['resource_type'] == 'accesspoint':
+ self._store_accesspoint(params, context, arn_details)
+ elif arn_details['resource_type'] == 'outpost':
+ self._store_outpost(params, context, arn_details)
+
+ def _get_arn_details_from_bucket_param(self, params):
+ if 'Bucket' in params:
+ try:
+ arn = params['Bucket']
+ arn_details = self._arn_parser.parse_arn(arn)
+ self._add_resource_type_and_name(arn, arn_details)
+ return arn_details
+ except InvalidArnException:
+ pass
+ return None
+
+ def _add_resource_type_and_name(self, arn, arn_details):
+ match = self._RESOURCE_REGEX.match(arn_details['resource'])
+ if match:
+ arn_details['resource_type'] = match.group('resource_type')
+ arn_details['resource_name'] = match.group('resource_name')
+ else:
+ raise UnsupportedS3ArnError(arn=arn)
+
+ def _store_accesspoint(self, params, context, arn_details):
+ # Ideally the access-point would be stored as a parameter in the
+ # request where the serializer would then know how to serialize it,
+ # but access-points are not modeled in S3 operations so it would fail
+ # validation. Instead, we set the access-point to the bucket parameter
+ # to have some value set when serializing the request and additional
+ # information on the context from the arn to use in forming the
+ # access-point endpoint.
+ params['Bucket'] = arn_details['resource_name']
+ context['s3_accesspoint'] = {
+ 'name': arn_details['resource_name'],
+ 'account': arn_details['account'],
+ 'partition': arn_details['partition'],
+ 'region': arn_details['region'],
+ 'service': arn_details['service'],
+ }
+
+ def _store_outpost(self, params, context, arn_details):
+ resource_name = arn_details['resource_name']
+ match = self._OUTPOST_RESOURCE_REGEX.match(resource_name)
+ if not match:
+ raise UnsupportedOutpostResourceError(resource_name=resource_name)
+ # Because we need to set the bucket name to something to pass
+ # validation we're going to use the access point name to be consistent
+ # with normal access point arns.
+ accesspoint_name = match.group('accesspoint_name')
+ params['Bucket'] = accesspoint_name
+ context['s3_accesspoint'] = {
+ 'outpost_name': match.group('outpost_name'),
+ 'name': accesspoint_name,
+ 'account': arn_details['account'],
+ 'partition': arn_details['partition'],
+ 'region': arn_details['region'],
+ 'service': arn_details['service'],
+ }
+
+
+class S3EndpointSetter:
+ _DEFAULT_PARTITION = 'aws'
+ _DEFAULT_DNS_SUFFIX = 'amazonaws.com'
+
+ def __init__(
+ self,
+ endpoint_resolver,
+ region=None,
+ s3_config=None,
+ endpoint_url=None,
+ partition=None,
+ use_fips_endpoint=False,
+ ):
+ # This is calling the endpoint_resolver in regions.py
+ self._endpoint_resolver = endpoint_resolver
+ self._region = region
+ self._s3_config = s3_config
+ self._use_fips_endpoint = use_fips_endpoint
+ if s3_config is None:
+ self._s3_config = {}
+ self._endpoint_url = endpoint_url
+ self._partition = partition
+ if partition is None:
+ self._partition = self._DEFAULT_PARTITION
+
+ def register(self, event_emitter):
+ event_emitter.register('before-sign.s3', self.set_endpoint)
+ event_emitter.register('choose-signer.s3', self.set_signer)
+ event_emitter.register(
+ 'before-call.s3.WriteGetObjectResponse',
+ self.update_endpoint_to_s3_object_lambda,
+ )
+
+ def update_endpoint_to_s3_object_lambda(self, params, context, **kwargs):
+ if self._use_accelerate_endpoint:
+ raise UnsupportedS3ConfigurationError(
+ msg='S3 client does not support accelerate endpoints for S3 Object Lambda operations',
+ )
+
+ self._override_signing_name(context, 's3-object-lambda')
+ if self._endpoint_url:
+ # Only update the url if an explicit url was not provided
+ return
+
+ resolver = self._endpoint_resolver
+ # Constructing endpoints as s3-object-lambda as region
+ resolved = resolver.construct_endpoint(
+ 's3-object-lambda', self._region
+ )
+
+ # Ideally we would be able to replace the endpoint before
+ # serialization but there's no event to do that currently
+ # host_prefix is all the arn/bucket specs
+ new_endpoint = 'https://{host_prefix}{hostname}'.format(
+ host_prefix=params['host_prefix'],
+ hostname=resolved['hostname'],
+ )
+
+ params['url'] = _get_new_endpoint(params['url'], new_endpoint, False)
+
+ def set_endpoint(self, request, **kwargs):
+ if self._use_accesspoint_endpoint(request):
+ self._validate_accesspoint_supported(request)
+ self._validate_fips_supported(request)
+ self._validate_global_regions(request)
+ region_name = self._resolve_region_for_accesspoint_endpoint(
+ request
+ )
+ self._resolve_signing_name_for_accesspoint_endpoint(request)
+ self._switch_to_accesspoint_endpoint(request, region_name)
+ return
+ if self._use_accelerate_endpoint:
+ if self._use_fips_endpoint:
+ raise UnsupportedS3ConfigurationError(
+ msg=(
+ 'Client is configured to use the FIPS psuedo region '
+ 'for "%s", but S3 Accelerate does not have any FIPS '
+ 'compatible endpoints.' % (self._region)
+ )
+ )
+ switch_host_s3_accelerate(request=request, **kwargs)
+ if self._s3_addressing_handler:
+ self._s3_addressing_handler(request=request, **kwargs)
+
+ def _use_accesspoint_endpoint(self, request):
+ return 's3_accesspoint' in request.context
+
+ def _validate_fips_supported(self, request):
+ if not self._use_fips_endpoint:
+ return
+ if 'fips' in request.context['s3_accesspoint']['region']:
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg={'Invalid ARN, FIPS region not allowed in ARN.'}
+ )
+ if 'outpost_name' in request.context['s3_accesspoint']:
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client is configured to use the FIPS psuedo-region "%s", '
+ 'but outpost ARNs do not support FIPS endpoints.'
+ % (self._region)
+ )
+ )
+ # Transforming psuedo region to actual region
+ accesspoint_region = request.context['s3_accesspoint']['region']
+ if accesspoint_region != self._region:
+ if not self._s3_config.get('use_arn_region', True):
+ # TODO: Update message to reflect use_arn_region
+ # is not set
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client is configured to use the FIPS psuedo-region '
+ 'for "%s", but the access-point ARN provided is for '
+ 'the "%s" region. For clients using a FIPS '
+ 'psuedo-region calls to access-point ARNs in another '
+ 'region are not allowed.'
+ % (self._region, accesspoint_region)
+ )
+ )
+
+ def _validate_global_regions(self, request):
+ if self._s3_config.get('use_arn_region', True):
+ return
+ if self._region in ['aws-global', 's3-external-1']:
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client is configured to use the global psuedo-region '
+ '"%s". When providing access-point ARNs a regional '
+ 'endpoint must be specified.' % self._region
+ )
+ )
+
+ def _validate_accesspoint_supported(self, request):
+ if self._use_accelerate_endpoint:
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client does not support s3 accelerate configuration '
+ 'when an access-point ARN is specified.'
+ )
+ )
+ request_partition = request.context['s3_accesspoint']['partition']
+ if request_partition != self._partition:
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client is configured for "%s" partition, but access-point'
+ ' ARN provided is for "%s" partition. The client and '
+ ' access-point partition must be the same.'
+ % (self._partition, request_partition)
+ )
+ )
+ s3_service = request.context['s3_accesspoint'].get('service')
+ if s3_service == 's3-object-lambda' and self._s3_config.get(
+ 'use_dualstack_endpoint'
+ ):
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client does not support s3 dualstack configuration '
+ 'when an S3 Object Lambda access point ARN is specified.'
+ )
+ )
+ outpost_name = request.context['s3_accesspoint'].get('outpost_name')
+ if outpost_name and self._s3_config.get('use_dualstack_endpoint'):
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client does not support s3 dualstack configuration '
+ 'when an outpost ARN is specified.'
+ )
+ )
+ self._validate_mrap_s3_config(request)
+
+ def _validate_mrap_s3_config(self, request):
+ if not is_global_accesspoint(request.context):
+ return
+ if self._s3_config.get('s3_disable_multiregion_access_points'):
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Invalid configuration, Multi-Region Access Point '
+ 'ARNs are disabled.'
+ )
+ )
+ elif self._s3_config.get('use_dualstack_endpoint'):
+ raise UnsupportedS3AccesspointConfigurationError(
+ msg=(
+ 'Client does not support s3 dualstack configuration '
+ 'when a Multi-Region Access Point ARN is specified.'
+ )
+ )
+
+ def _resolve_region_for_accesspoint_endpoint(self, request):
+ if is_global_accesspoint(request.context):
+ # Requests going to MRAP endpoints MUST be set to any (*) region.
+ self._override_signing_region(request, '*')
+ elif self._s3_config.get('use_arn_region', True):
+ accesspoint_region = request.context['s3_accesspoint']['region']
+ # If we are using the region from the access point,
+ # we will also want to make sure that we set it as the
+ # signing region as well
+ self._override_signing_region(request, accesspoint_region)
+ return accesspoint_region
+ return self._region
+
+ def set_signer(self, context, **kwargs):
+ if is_global_accesspoint(context):
+ if HAS_CRT:
+ return 's3v4a'
+ else:
+ raise MissingDependencyException(
+ msg="Using S3 with an MRAP arn requires an additional "
+ "dependency. You will need to pip install "
+ "botocore[crt] before proceeding."
+ )
+
+ def _resolve_signing_name_for_accesspoint_endpoint(self, request):
+ accesspoint_service = request.context['s3_accesspoint']['service']
+ self._override_signing_name(request.context, accesspoint_service)
+
+ def _switch_to_accesspoint_endpoint(self, request, region_name):
+ original_components = urlsplit(request.url)
+ accesspoint_endpoint = urlunsplit(
+ (
+ original_components.scheme,
+ self._get_netloc(request.context, region_name),
+ self._get_accesspoint_path(
+ original_components.path, request.context
+ ),
+ original_components.query,
+ '',
+ )
+ )
+ logger.debug(
+ f'Updating URI from {request.url} to {accesspoint_endpoint}'
+ )
+ request.url = accesspoint_endpoint
+
+ def _get_netloc(self, request_context, region_name):
+ if is_global_accesspoint(request_context):
+ return self._get_mrap_netloc(request_context)
+ else:
+ return self._get_accesspoint_netloc(request_context, region_name)
+
+ def _get_mrap_netloc(self, request_context):
+ s3_accesspoint = request_context['s3_accesspoint']
+ region_name = 's3-global'
+ mrap_netloc_components = [s3_accesspoint['name']]
+ if self._endpoint_url:
+ endpoint_url_netloc = urlsplit(self._endpoint_url).netloc
+ mrap_netloc_components.append(endpoint_url_netloc)
+ else:
+ partition = s3_accesspoint['partition']
+ mrap_netloc_components.extend(
+ [
+ 'accesspoint',
+ region_name,
+ self._get_partition_dns_suffix(partition),
+ ]
+ )
+ return '.'.join(mrap_netloc_components)
+
+ def _get_accesspoint_netloc(self, request_context, region_name):
+ s3_accesspoint = request_context['s3_accesspoint']
+ accesspoint_netloc_components = [
+ '{}-{}'.format(s3_accesspoint['name'], s3_accesspoint['account']),
+ ]
+ outpost_name = s3_accesspoint.get('outpost_name')
+ if self._endpoint_url:
+ if outpost_name:
+ accesspoint_netloc_components.append(outpost_name)
+ endpoint_url_netloc = urlsplit(self._endpoint_url).netloc
+ accesspoint_netloc_components.append(endpoint_url_netloc)
+ else:
+ if outpost_name:
+ outpost_host = [outpost_name, 's3-outposts']
+ accesspoint_netloc_components.extend(outpost_host)
+ elif s3_accesspoint['service'] == 's3-object-lambda':
+ component = self._inject_fips_if_needed(
+ 's3-object-lambda', request_context
+ )
+ accesspoint_netloc_components.append(component)
+ else:
+ component = self._inject_fips_if_needed(
+ 's3-accesspoint', request_context
+ )
+ accesspoint_netloc_components.append(component)
+ if self._s3_config.get('use_dualstack_endpoint'):
+ accesspoint_netloc_components.append('dualstack')
+ accesspoint_netloc_components.extend(
+ [region_name, self._get_dns_suffix(region_name)]
+ )
+ return '.'.join(accesspoint_netloc_components)
+
+ def _inject_fips_if_needed(self, component, request_context):
+ if self._use_fips_endpoint:
+ return '%s-fips' % component
+ return component
+
+ def _get_accesspoint_path(self, original_path, request_context):
+ # The Bucket parameter was substituted with the access-point name as
+ # some value was required in serializing the bucket name. Now that
+ # we are making the request directly to the access point, we will
+ # want to remove that access-point name from the path.
+ name = request_context['s3_accesspoint']['name']
+ # All S3 operations require at least a / in their path.
+ return original_path.replace('/' + name, '', 1) or '/'
+
+ def _get_partition_dns_suffix(self, partition_name):
+ dns_suffix = self._endpoint_resolver.get_partition_dns_suffix(
+ partition_name
+ )
+ if dns_suffix is None:
+ dns_suffix = self._DEFAULT_DNS_SUFFIX
+ return dns_suffix
+
+ def _get_dns_suffix(self, region_name):
+ resolved = self._endpoint_resolver.construct_endpoint(
+ 's3', region_name
+ )
+ dns_suffix = self._DEFAULT_DNS_SUFFIX
+ if resolved and 'dnsSuffix' in resolved:
+ dns_suffix = resolved['dnsSuffix']
+ return dns_suffix
+
+ def _override_signing_region(self, request, region_name):
+ signing_context = request.context.get('signing', {})
+ # S3SigV4Auth will use the context['signing']['region'] value to
+ # sign with if present. This is used by the Bucket redirector
+ # as well but we should be fine because the redirector is never
+ # used in combination with the accesspoint setting logic.
+ signing_context['region'] = region_name
+ request.context['signing'] = signing_context
+
+ def _override_signing_name(self, context, signing_name):
+ signing_context = context.get('signing', {})
+ # S3SigV4Auth will use the context['signing']['signing_name'] value to
+ # sign with if present. This is used by the Bucket redirector
+ # as well but we should be fine because the redirector is never
+ # used in combination with the accesspoint setting logic.
+ signing_context['signing_name'] = signing_name
+ context['signing'] = signing_context
+
+ @CachedProperty
+ def _use_accelerate_endpoint(self):
+ # Enable accelerate if the configuration is set to to true or the
+ # endpoint being used matches one of the accelerate endpoints.
+
+ # Accelerate has been explicitly configured.
+ if self._s3_config.get('use_accelerate_endpoint'):
+ return True
+
+ # Accelerate mode is turned on automatically if an endpoint url is
+ # provided that matches the accelerate scheme.
+ if self._endpoint_url is None:
+ return False
+
+ # Accelerate is only valid for Amazon endpoints.
+ netloc = urlsplit(self._endpoint_url).netloc
+ if not netloc.endswith('amazonaws.com'):
+ return False
+
+ # The first part of the url should always be s3-accelerate.
+ parts = netloc.split('.')
+ if parts[0] != 's3-accelerate':
+ return False
+
+ # Url parts between 's3-accelerate' and 'amazonaws.com' which
+ # represent different url features.
+ feature_parts = parts[1:-2]
+
+ # There should be no duplicate url parts.
+ if len(feature_parts) != len(set(feature_parts)):
+ return False
+
+ # Remaining parts must all be in the whitelist.
+ return all(p in S3_ACCELERATE_WHITELIST for p in feature_parts)
+
+ @CachedProperty
+ def _addressing_style(self):
+ # Use virtual host style addressing if accelerate is enabled or if
+ # the given endpoint url is an accelerate endpoint.
+ if self._use_accelerate_endpoint:
+ return 'virtual'
+
+ # If a particular addressing style is configured, use it.
+ configured_addressing_style = self._s3_config.get('addressing_style')
+ if configured_addressing_style:
+ return configured_addressing_style
+
+ @CachedProperty
+ def _s3_addressing_handler(self):
+ # If virtual host style was configured, use it regardless of whether
+ # or not the bucket looks dns compatible.
+ if self._addressing_style == 'virtual':
+ logger.debug("Using S3 virtual host style addressing.")
+ return switch_to_virtual_host_style
+
+ # If path style is configured, no additional steps are needed. If
+ # endpoint_url was specified, don't default to virtual. We could
+ # potentially default provided endpoint urls to virtual hosted
+ # style, but for now it is avoided.
+ if self._addressing_style == 'path' or self._endpoint_url is not None:
+ logger.debug("Using S3 path style addressing.")
+ return None
+
+ logger.debug(
+ "Defaulting to S3 virtual host style addressing with "
+ "path style addressing fallback."
+ )
+
+ # By default, try to use virtual style with path fallback.
+ return fix_s3_host
+
+
+class S3ControlEndpointSetter:
+ _DEFAULT_PARTITION = 'aws'
+ _DEFAULT_DNS_SUFFIX = 'amazonaws.com'
+ _HOST_LABEL_REGEX = re.compile(r'^[a-zA-Z0-9\-]{1,63}$')
+
+ def __init__(
+ self,
+ endpoint_resolver,
+ region=None,
+ s3_config=None,
+ endpoint_url=None,
+ partition=None,
+ use_fips_endpoint=False,
+ ):
+ self._endpoint_resolver = endpoint_resolver
+ self._region = region
+ self._s3_config = s3_config
+ self._use_fips_endpoint = use_fips_endpoint
+ if s3_config is None:
+ self._s3_config = {}
+ self._endpoint_url = endpoint_url
+ self._partition = partition
+ if partition is None:
+ self._partition = self._DEFAULT_PARTITION
+
+ def register(self, event_emitter):
+ event_emitter.register('before-sign.s3-control', self.set_endpoint)
+
+ def set_endpoint(self, request, **kwargs):
+ if self._use_endpoint_from_arn_details(request):
+ self._validate_endpoint_from_arn_details_supported(request)
+ region_name = self._resolve_region_from_arn_details(request)
+ self._resolve_signing_name_from_arn_details(request)
+ self._resolve_endpoint_from_arn_details(request, region_name)
+ self._add_headers_from_arn_details(request)
+ elif self._use_endpoint_from_outpost_id(request):
+ self._validate_outpost_redirection_valid(request)
+ self._override_signing_name(request, 's3-outposts')
+ new_netloc = self._construct_outpost_endpoint(self._region)
+ self._update_request_netloc(request, new_netloc)
+
+ def _use_endpoint_from_arn_details(self, request):
+ return 'arn_details' in request.context
+
+ def _use_endpoint_from_outpost_id(self, request):
+ return 'outpost_id' in request.context
+
+ def _validate_endpoint_from_arn_details_supported(self, request):
+ if 'fips' in request.context['arn_details']['region']:
+ raise UnsupportedS3ControlArnError(
+ arn=request.context['arn_details']['original'],
+ msg='Invalid ARN, FIPS region not allowed in ARN.',
+ )
+ if not self._s3_config.get('use_arn_region', False):
+ arn_region = request.context['arn_details']['region']
+ if arn_region != self._region:
+ error_msg = (
+ 'The use_arn_region configuration is disabled but '
+ 'received arn for "%s" when the client is configured '
+ 'to use "%s"'
+ ) % (arn_region, self._region)
+ raise UnsupportedS3ControlConfigurationError(msg=error_msg)
+ request_partion = request.context['arn_details']['partition']
+ if request_partion != self._partition:
+ raise UnsupportedS3ControlConfigurationError(
+ msg=(
+ 'Client is configured for "%s" partition, but arn '
+ 'provided is for "%s" partition. The client and '
+ 'arn partition must be the same.'
+ % (self._partition, request_partion)
+ )
+ )
+ if self._s3_config.get('use_accelerate_endpoint'):
+ raise UnsupportedS3ControlConfigurationError(
+ msg='S3 control client does not support accelerate endpoints',
+ )
+ if 'outpost_name' in request.context['arn_details']:
+ self._validate_outpost_redirection_valid(request)
+
+ def _validate_outpost_redirection_valid(self, request):
+ if self._s3_config.get('use_dualstack_endpoint'):
+ raise UnsupportedS3ControlConfigurationError(
+ msg=(
+ 'Client does not support s3 dualstack configuration '
+ 'when an outpost is specified.'
+ )
+ )
+
+ def _resolve_region_from_arn_details(self, request):
+ if self._s3_config.get('use_arn_region', False):
+ arn_region = request.context['arn_details']['region']
+ # If we are using the region from the expanded arn, we will also
+ # want to make sure that we set it as the signing region as well
+ self._override_signing_region(request, arn_region)
+ return arn_region
+ return self._region
+
+ def _resolve_signing_name_from_arn_details(self, request):
+ arn_service = request.context['arn_details']['service']
+ self._override_signing_name(request, arn_service)
+ return arn_service
+
+ def _resolve_endpoint_from_arn_details(self, request, region_name):
+ new_netloc = self._resolve_netloc_from_arn_details(
+ request, region_name
+ )
+ self._update_request_netloc(request, new_netloc)
+
+ def _update_request_netloc(self, request, new_netloc):
+ original_components = urlsplit(request.url)
+ arn_details_endpoint = urlunsplit(
+ (
+ original_components.scheme,
+ new_netloc,
+ original_components.path,
+ original_components.query,
+ '',
+ )
+ )
+ logger.debug(
+ f'Updating URI from {request.url} to {arn_details_endpoint}'
+ )
+ request.url = arn_details_endpoint
+
+ def _resolve_netloc_from_arn_details(self, request, region_name):
+ arn_details = request.context['arn_details']
+ if 'outpost_name' in arn_details:
+ return self._construct_outpost_endpoint(region_name)
+ account = arn_details['account']
+ return self._construct_s3_control_endpoint(region_name, account)
+
+ def _is_valid_host_label(self, label):
+ return self._HOST_LABEL_REGEX.match(label)
+
+ def _validate_host_labels(self, *labels):
+ for label in labels:
+ if not self._is_valid_host_label(label):
+ raise InvalidHostLabelError(label=label)
+
+ def _construct_s3_control_endpoint(self, region_name, account):
+ self._validate_host_labels(region_name, account)
+ if self._endpoint_url:
+ endpoint_url_netloc = urlsplit(self._endpoint_url).netloc
+ netloc = [account, endpoint_url_netloc]
+ else:
+ netloc = [
+ account,
+ 's3-control',
+ ]
+ self._add_dualstack(netloc)
+ dns_suffix = self._get_dns_suffix(region_name)
+ netloc.extend([region_name, dns_suffix])
+ return self._construct_netloc(netloc)
+
+ def _construct_outpost_endpoint(self, region_name):
+ self._validate_host_labels(region_name)
+ if self._endpoint_url:
+ return urlsplit(self._endpoint_url).netloc
+ else:
+ netloc = [
+ 's3-outposts',
+ region_name,
+ self._get_dns_suffix(region_name),
+ ]
+ self._add_fips(netloc)
+ return self._construct_netloc(netloc)
+
+ def _construct_netloc(self, netloc):
+ return '.'.join(netloc)
+
+ def _add_fips(self, netloc):
+ if self._use_fips_endpoint:
+ netloc[0] = netloc[0] + '-fips'
+
+ def _add_dualstack(self, netloc):
+ if self._s3_config.get('use_dualstack_endpoint'):
+ netloc.append('dualstack')
+
+ def _get_dns_suffix(self, region_name):
+ resolved = self._endpoint_resolver.construct_endpoint(
+ 's3', region_name
+ )
+ dns_suffix = self._DEFAULT_DNS_SUFFIX
+ if resolved and 'dnsSuffix' in resolved:
+ dns_suffix = resolved['dnsSuffix']
+ return dns_suffix
+
+ def _override_signing_region(self, request, region_name):
+ signing_context = request.context.get('signing', {})
+ # S3SigV4Auth will use the context['signing']['region'] value to
+ # sign with if present. This is used by the Bucket redirector
+ # as well but we should be fine because the redirector is never
+ # used in combination with the accesspoint setting logic.
+ signing_context['region'] = region_name
+ request.context['signing'] = signing_context
+
+ def _override_signing_name(self, request, signing_name):
+ signing_context = request.context.get('signing', {})
+ # S3SigV4Auth will use the context['signing']['signing_name'] value to
+ # sign with if present. This is used by the Bucket redirector
+ # as well but we should be fine because the redirector is never
+ # used in combination with the accesspoint setting logic.
+ signing_context['signing_name'] = signing_name
+ request.context['signing'] = signing_context
+
+ def _add_headers_from_arn_details(self, request):
+ arn_details = request.context['arn_details']
+ outpost_name = arn_details.get('outpost_name')
+ if outpost_name:
+ self._add_outpost_id_header(request, outpost_name)
+
+ def _add_outpost_id_header(self, request, outpost_name):
+ request.headers['x-amz-outpost-id'] = outpost_name
+
+
+class S3ControlArnParamHandler:
+ """This handler has been replaced by S3ControlArnParamHandlerv2. The
+ original version remains in place for any third-party importers.
+ """
+
+ _RESOURCE_SPLIT_REGEX = re.compile(r'[/:]')
+
+ def __init__(self, arn_parser=None):
+ self._arn_parser = arn_parser
+ if arn_parser is None:
+ self._arn_parser = ArnParser()
+ warnings.warn(
+ 'The S3ControlArnParamHandler class has been deprecated for a new '
+ 'internal replacement. A future version of botocore may remove '
+ 'this class.',
+ category=FutureWarning,
+ )
+
+ def register(self, event_emitter):
+ event_emitter.register(
+ 'before-parameter-build.s3-control',
+ self.handle_arn,
+ )
+
+ def handle_arn(self, params, model, context, **kwargs):
+ if model.name in ('CreateBucket', 'ListRegionalBuckets'):
+ # CreateBucket and ListRegionalBuckets are special cases that do
+ # not obey ARN based redirection but will redirect based off of the
+ # presence of the OutpostId parameter
+ self._handle_outpost_id_param(params, model, context)
+ else:
+ self._handle_name_param(params, model, context)
+ self._handle_bucket_param(params, model, context)
+
+ def _get_arn_details_from_param(self, params, param_name):
+ if param_name not in params:
+ return None
+ try:
+ arn = params[param_name]
+ arn_details = self._arn_parser.parse_arn(arn)
+ arn_details['original'] = arn
+ arn_details['resources'] = self._split_resource(arn_details)
+ return arn_details
+ except InvalidArnException:
+ return None
+
+ def _split_resource(self, arn_details):
+ return self._RESOURCE_SPLIT_REGEX.split(arn_details['resource'])
+
+ def _override_account_id_param(self, params, arn_details):
+ account_id = arn_details['account']
+ if 'AccountId' in params and params['AccountId'] != account_id:
+ error_msg = (
+ 'Account ID in arn does not match the AccountId parameter '
+ 'provided: "%s"'
+ ) % params['AccountId']
+ raise UnsupportedS3ControlArnError(
+ arn=arn_details['original'],
+ msg=error_msg,
+ )
+ params['AccountId'] = account_id
+
+ def _handle_outpost_id_param(self, params, model, context):
+ if 'OutpostId' not in params:
+ return
+ context['outpost_id'] = params['OutpostId']
+
+ def _handle_name_param(self, params, model, context):
+ # CreateAccessPoint is a special case that does not expand Name
+ if model.name == 'CreateAccessPoint':
+ return
+ arn_details = self._get_arn_details_from_param(params, 'Name')
+ if arn_details is None:
+ return
+ if self._is_outpost_accesspoint(arn_details):
+ self._store_outpost_accesspoint(params, context, arn_details)
+ else:
+ error_msg = 'The Name parameter does not support the provided ARN'
+ raise UnsupportedS3ControlArnError(
+ arn=arn_details['original'],
+ msg=error_msg,
+ )
+
+ def _is_outpost_accesspoint(self, arn_details):
+ if arn_details['service'] != 's3-outposts':
+ return False
+ resources = arn_details['resources']
+ if len(resources) != 4:
+ return False
+ # Resource must be of the form outpost/op-123/accesspoint/name
+ return resources[0] == 'outpost' and resources[2] == 'accesspoint'
+
+ def _store_outpost_accesspoint(self, params, context, arn_details):
+ self._override_account_id_param(params, arn_details)
+ accesspoint_name = arn_details['resources'][3]
+ params['Name'] = accesspoint_name
+ arn_details['accesspoint_name'] = accesspoint_name
+ arn_details['outpost_name'] = arn_details['resources'][1]
+ context['arn_details'] = arn_details
+
+ def _handle_bucket_param(self, params, model, context):
+ arn_details = self._get_arn_details_from_param(params, 'Bucket')
+ if arn_details is None:
+ return
+ if self._is_outpost_bucket(arn_details):
+ self._store_outpost_bucket(params, context, arn_details)
+ else:
+ error_msg = (
+ 'The Bucket parameter does not support the provided ARN'
+ )
+ raise UnsupportedS3ControlArnError(
+ arn=arn_details['original'],
+ msg=error_msg,
+ )
+
+ def _is_outpost_bucket(self, arn_details):
+ if arn_details['service'] != 's3-outposts':
+ return False
+ resources = arn_details['resources']
+ if len(resources) != 4:
+ return False
+ # Resource must be of the form outpost/op-123/bucket/name
+ return resources[0] == 'outpost' and resources[2] == 'bucket'
+
+ def _store_outpost_bucket(self, params, context, arn_details):
+ self._override_account_id_param(params, arn_details)
+ bucket_name = arn_details['resources'][3]
+ params['Bucket'] = bucket_name
+ arn_details['bucket_name'] = bucket_name
+ arn_details['outpost_name'] = arn_details['resources'][1]
+ context['arn_details'] = arn_details
+
+
+class S3ControlArnParamHandlerv2(S3ControlArnParamHandler):
+ """Updated version of S3ControlArnParamHandler for use when
+ EndpointRulesetResolver is in use for endpoint resolution.
+
+ This class is considered private and subject to abrupt breaking changes or
+ removal without prior announcement. Please do not use it directly.
+ """
+
+ def __init__(self, arn_parser=None):
+ self._arn_parser = arn_parser
+ if arn_parser is None:
+ self._arn_parser = ArnParser()
+
+ def register(self, event_emitter):
+ event_emitter.register(
+ 'before-endpoint-resolution.s3-control',
+ self.handle_arn,
+ )
+
+ def _handle_name_param(self, params, model, context):
+ # CreateAccessPoint is a special case that does not expand Name
+ if model.name == 'CreateAccessPoint':
+ return
+ arn_details = self._get_arn_details_from_param(params, 'Name')
+ if arn_details is None:
+ return
+ self._raise_for_fips_pseudo_region(arn_details)
+ self._raise_for_accelerate_endpoint(context)
+ if self._is_outpost_accesspoint(arn_details):
+ self._store_outpost_accesspoint(params, context, arn_details)
+ else:
+ error_msg = 'The Name parameter does not support the provided ARN'
+ raise UnsupportedS3ControlArnError(
+ arn=arn_details['original'],
+ msg=error_msg,
+ )
+
+ def _store_outpost_accesspoint(self, params, context, arn_details):
+ self._override_account_id_param(params, arn_details)
+
+ def _handle_bucket_param(self, params, model, context):
+ arn_details = self._get_arn_details_from_param(params, 'Bucket')
+ if arn_details is None:
+ return
+ self._raise_for_fips_pseudo_region(arn_details)
+ self._raise_for_accelerate_endpoint(context)
+ if self._is_outpost_bucket(arn_details):
+ self._store_outpost_bucket(params, context, arn_details)
+ else:
+ error_msg = (
+ 'The Bucket parameter does not support the provided ARN'
+ )
+ raise UnsupportedS3ControlArnError(
+ arn=arn_details['original'],
+ msg=error_msg,
+ )
+
+ def _store_outpost_bucket(self, params, context, arn_details):
+ self._override_account_id_param(params, arn_details)
+
+ def _raise_for_fips_pseudo_region(self, arn_details):
+ # FIPS pseudo region names cannot be used in ARNs
+ arn_region = arn_details['region']
+ if arn_region.startswith('fips-') or arn_region.endswith('fips-'):
+ raise UnsupportedS3ControlArnError(
+ arn=arn_details['original'],
+ msg='Invalid ARN, FIPS region not allowed in ARN.',
+ )
+
+ def _raise_for_accelerate_endpoint(self, context):
+ s3_config = context['client_config'].s3 or {}
+ if s3_config.get('use_accelerate_endpoint'):
+ raise UnsupportedS3ControlConfigurationError(
+ msg='S3 control client does not support accelerate endpoints',
+ )
+
+
+class ContainerMetadataFetcher:
+ TIMEOUT_SECONDS = 2
+ RETRY_ATTEMPTS = 3
+ SLEEP_TIME = 1
+ IP_ADDRESS = '169.254.170.2'
+ _ALLOWED_HOSTS = [
+ IP_ADDRESS,
+ '169.254.170.23',
+ 'fd00:ec2::23',
+ 'localhost',
+ ]
+
+ def __init__(self, session=None, sleep=time.sleep):
+ if session is None:
+ session = botocore.httpsession.URLLib3Session(
+ timeout=self.TIMEOUT_SECONDS
+ )
+ self._session = session
+ self._sleep = sleep
+
+ def retrieve_full_uri(self, full_url, headers=None):
+ """Retrieve JSON metadata from container metadata.
+
+ :type full_url: str
+ :param full_url: The full URL of the metadata service.
+ This should include the scheme as well, e.g
+ "http://localhost:123/foo"
+
+ """
+ self._validate_allowed_url(full_url)
+ return self._retrieve_credentials(full_url, headers)
+
+ def _validate_allowed_url(self, full_url):
+ parsed = botocore.compat.urlparse(full_url)
+ if self._is_loopback_address(parsed.hostname):
+ return
+ is_whitelisted_host = self._check_if_whitelisted_host(parsed.hostname)
+ if not is_whitelisted_host:
+ raise ValueError(
+ f"Unsupported host '{parsed.hostname}'. Can only retrieve metadata "
+ f"from a loopback address or one of these hosts: {', '.join(self._ALLOWED_HOSTS)}"
+ )
+
+ def _is_loopback_address(self, hostname):
+ try:
+ ip = ip_address(hostname)
+ return ip.is_loopback
+ except ValueError:
+ return False
+
+ def _check_if_whitelisted_host(self, host):
+ if host in self._ALLOWED_HOSTS:
+ return True
+ return False
+
+ def retrieve_uri(self, relative_uri):
+ """Retrieve JSON metadata from container metadata.
+
+ :type relative_uri: str
+ :param relative_uri: A relative URI, e.g "/foo/bar?id=123"
+
+ :return: The parsed JSON response.
+
+ """
+ full_url = self.full_url(relative_uri)
+ return self._retrieve_credentials(full_url)
+
+ def _retrieve_credentials(self, full_url, extra_headers=None):
+ headers = {'Accept': 'application/json'}
+ if extra_headers is not None:
+ headers.update(extra_headers)
+ attempts = 0
+ while True:
+ try:
+ return self._get_response(
+ full_url, headers, self.TIMEOUT_SECONDS
+ )
+ except MetadataRetrievalError as e:
+ logger.debug(
+ "Received error when attempting to retrieve "
+ "container metadata: %s",
+ e,
+ exc_info=True,
+ )
+ self._sleep(self.SLEEP_TIME)
+ attempts += 1
+ if attempts >= self.RETRY_ATTEMPTS:
+ raise
+
+ def _get_response(self, full_url, headers, timeout):
+ try:
+ AWSRequest = botocore.awsrequest.AWSRequest
+ request = AWSRequest(method='GET', url=full_url, headers=headers)
+ response = self._session.send(request.prepare())
+ response_text = response.content.decode('utf-8')
+ if response.status_code != 200:
+ raise MetadataRetrievalError(
+ error_msg=(
+ f"Received non 200 response {response.status_code} "
+ f"from container metadata: {response_text}"
+ )
+ )
+ try:
+ return json.loads(response_text)
+ except ValueError:
+ error_msg = "Unable to parse JSON returned from container metadata services"
+ logger.debug('%s:%s', error_msg, response_text)
+ raise MetadataRetrievalError(error_msg=error_msg)
+ except RETRYABLE_HTTP_ERRORS as e:
+ error_msg = (
+ "Received error when attempting to retrieve "
+ f"container metadata: {e}"
+ )
+ raise MetadataRetrievalError(error_msg=error_msg)
+
+ def full_url(self, relative_uri):
+ return f'http://{self.IP_ADDRESS}{relative_uri}'
+
+
+def get_environ_proxies(url):
+ if should_bypass_proxies(url):
+ return {}
+ else:
+ return getproxies()
+
+
+def should_bypass_proxies(url):
+ """
+ Returns whether we should bypass proxies or not.
+ """
+ # NOTE: requests allowed for ip/cidr entries in no_proxy env that we don't
+ # support current as urllib only checks DNS suffix
+ # If the system proxy settings indicate that this URL should be bypassed,
+ # don't proxy.
+ # The proxy_bypass function is incredibly buggy on OS X in early versions
+ # of Python 2.6, so allow this call to fail. Only catch the specific
+ # exceptions we've seen, though: this call failing in other ways can reveal
+ # legitimate problems.
+ try:
+ if proxy_bypass(urlparse(url).netloc):
+ return True
+ except (TypeError, socket.gaierror):
+ pass
+
+ return False
+
+
+def determine_content_length(body):
+ # No body, content length of 0
+ if not body:
+ return 0
+
+ # Try asking the body for it's length
+ try:
+ return len(body)
+ except (AttributeError, TypeError):
+ pass
+
+ # Try getting the length from a seekable stream
+ if hasattr(body, 'seek') and hasattr(body, 'tell'):
+ try:
+ orig_pos = body.tell()
+ body.seek(0, 2)
+ end_file_pos = body.tell()
+ body.seek(orig_pos)
+ return end_file_pos - orig_pos
+ except io.UnsupportedOperation:
+ # in case when body is, for example, io.BufferedIOBase object
+ # it has "seek" method which throws "UnsupportedOperation"
+ # exception in such case we want to fall back to "chunked"
+ # encoding
+ pass
+ # Failed to determine the length
+ return None
+
+
+def get_encoding_from_headers(headers, default='ISO-8859-1'):
+ """Returns encodings from given HTTP Header Dict.
+
+ :param headers: dictionary to extract encoding from.
+ :param default: default encoding if the content-type is text
+ """
+
+ content_type = headers.get('content-type')
+
+ if not content_type:
+ return None
+
+ message = email.message.Message()
+ message['content-type'] = content_type
+ charset = message.get_param("charset")
+
+ if charset is not None:
+ return charset
+
+ if 'text' in content_type:
+ return default
+
+
+def calculate_md5(body, **kwargs):
+ if isinstance(body, (bytes, bytearray)):
+ binary_md5 = _calculate_md5_from_bytes(body)
+ else:
+ binary_md5 = _calculate_md5_from_file(body)
+ return base64.b64encode(binary_md5).decode('ascii')
+
+
+def _calculate_md5_from_bytes(body_bytes):
+ md5 = get_md5(body_bytes)
+ return md5.digest()
+
+
+def _calculate_md5_from_file(fileobj):
+ start_position = fileobj.tell()
+ md5 = get_md5()
+ for chunk in iter(lambda: fileobj.read(1024 * 1024), b''):
+ md5.update(chunk)
+ fileobj.seek(start_position)
+ return md5.digest()
+
+
+def conditionally_calculate_md5(params, **kwargs):
+ """Only add a Content-MD5 if the system supports it."""
+ headers = params['headers']
+ body = params['body']
+ checksum_context = params.get('context', {}).get('checksum', {})
+ checksum_algorithm = checksum_context.get('request_algorithm')
+ if checksum_algorithm and checksum_algorithm != 'conditional-md5':
+ # Skip for requests that will have a flexible checksum applied
+ return
+ # If a header matching the x-amz-checksum-* pattern is present, we
+ # assume a checksum has already been provided and an md5 is not needed
+ for header in headers:
+ if CHECKSUM_HEADER_PATTERN.match(header):
+ return
+ if MD5_AVAILABLE and body is not None and 'Content-MD5' not in headers:
+ md5_digest = calculate_md5(body, **kwargs)
+ params['headers']['Content-MD5'] = md5_digest
+
+
+class FileWebIdentityTokenLoader:
+ def __init__(self, web_identity_token_path, _open=open):
+ self._web_identity_token_path = web_identity_token_path
+ self._open = _open
+
+ def __call__(self):
+ with self._open(self._web_identity_token_path) as token_file:
+ return token_file.read()
+
+
+class SSOTokenLoader:
+ def __init__(self, cache=None):
+ if cache is None:
+ cache = {}
+ self._cache = cache
+
+ def _generate_cache_key(self, start_url, session_name):
+ input_str = start_url
+ if session_name is not None:
+ input_str = session_name
+ return hashlib.sha1(input_str.encode('utf-8')).hexdigest()
+
+ def save_token(self, start_url, token, session_name=None):
+ cache_key = self._generate_cache_key(start_url, session_name)
+ self._cache[cache_key] = token
+
+ def __call__(self, start_url, session_name=None):
+ cache_key = self._generate_cache_key(start_url, session_name)
+ logger.debug(f'Checking for cached token at: {cache_key}')
+ if cache_key not in self._cache:
+ name = start_url
+ if session_name is not None:
+ name = session_name
+ error_msg = f'Token for {name} does not exist'
+ raise SSOTokenLoadError(error_msg=error_msg)
+
+ token = self._cache[cache_key]
+ if 'accessToken' not in token or 'expiresAt' not in token:
+ error_msg = f'Token for {start_url} is invalid'
+ raise SSOTokenLoadError(error_msg=error_msg)
+ return token
+
+
+class EventbridgeSignerSetter:
+ _DEFAULT_PARTITION = 'aws'
+ _DEFAULT_DNS_SUFFIX = 'amazonaws.com'
+
+ def __init__(self, endpoint_resolver, region=None, endpoint_url=None):
+ self._endpoint_resolver = endpoint_resolver
+ self._region = region
+ self._endpoint_url = endpoint_url
+
+ def register(self, event_emitter):
+ event_emitter.register(
+ 'before-parameter-build.events.PutEvents',
+ self.check_for_global_endpoint,
+ )
+ event_emitter.register(
+ 'before-call.events.PutEvents', self.set_endpoint_url
+ )
+
+ def set_endpoint_url(self, params, context, **kwargs):
+ if 'eventbridge_endpoint' in context:
+ endpoint = context['eventbridge_endpoint']
+ logger.debug(f"Rewriting URL from {params['url']} to {endpoint}")
+ params['url'] = endpoint
+
+ def check_for_global_endpoint(self, params, context, **kwargs):
+ endpoint = params.get('EndpointId')
+ if endpoint is None:
+ return
+
+ if len(endpoint) == 0:
+ raise InvalidEndpointConfigurationError(
+ msg='EndpointId must not be a zero length string'
+ )
+
+ if not HAS_CRT:
+ raise MissingDependencyException(
+ msg="Using EndpointId requires an additional "
+ "dependency. You will need to pip install "
+ "botocore[crt] before proceeding."
+ )
+
+ config = context.get('client_config')
+ endpoint_variant_tags = None
+ if config is not None:
+ if config.use_fips_endpoint:
+ raise InvalidEndpointConfigurationError(
+ msg="FIPS is not supported with EventBridge "
+ "multi-region endpoints."
+ )
+ if config.use_dualstack_endpoint:
+ endpoint_variant_tags = ['dualstack']
+
+ if self._endpoint_url is None:
+ # Validate endpoint is a valid hostname component
+ parts = urlparse(f'https://{endpoint}')
+ if parts.hostname != endpoint:
+ raise InvalidEndpointConfigurationError(
+ msg='EndpointId is not a valid hostname component.'
+ )
+ resolved_endpoint = self._get_global_endpoint(
+ endpoint, endpoint_variant_tags=endpoint_variant_tags
+ )
+ else:
+ resolved_endpoint = self._endpoint_url
+
+ context['eventbridge_endpoint'] = resolved_endpoint
+ context['auth_type'] = 'v4a'
+
+ def _get_global_endpoint(self, endpoint, endpoint_variant_tags=None):
+ resolver = self._endpoint_resolver
+
+ partition = resolver.get_partition_for_region(self._region)
+ if partition is None:
+ partition = self._DEFAULT_PARTITION
+ dns_suffix = resolver.get_partition_dns_suffix(
+ partition, endpoint_variant_tags=endpoint_variant_tags
+ )
+ if dns_suffix is None:
+ dns_suffix = self._DEFAULT_DNS_SUFFIX
+
+ return f"https://{endpoint}.endpoint.events.{dns_suffix}/"
+
+
+def is_s3_accelerate_url(url):
+ """Does the URL match the S3 Accelerate endpoint scheme?
+
+ Virtual host naming style with bucket names in the netloc part of the URL
+ are not allowed by this function.
+ """
+ if url is None:
+ return False
+
+ # Accelerate is only valid for Amazon endpoints.
+ url_parts = urlsplit(url)
+ if not url_parts.netloc.endswith(
+ 'amazonaws.com'
+ ) or url_parts.scheme not in ['https', 'http']:
+ return False
+
+ # The first part of the URL must be s3-accelerate.
+ parts = url_parts.netloc.split('.')
+ if parts[0] != 's3-accelerate':
+ return False
+
+ # Url parts between 's3-accelerate' and 'amazonaws.com' which
+ # represent different url features.
+ feature_parts = parts[1:-2]
+
+ # There should be no duplicate URL parts.
+ if len(feature_parts) != len(set(feature_parts)):
+ return False
+
+ # Remaining parts must all be in the whitelist.
+ return all(p in S3_ACCELERATE_WHITELIST for p in feature_parts)
+
+
+class JSONFileCache:
+ """JSON file cache.
+ This provides a dict like interface that stores JSON serializable
+ objects.
+ The objects are serialized to JSON and stored in a file. These
+ values can be retrieved at a later time.
+ """
+
+ CACHE_DIR = os.path.expanduser(os.path.join('~', '.aws', 'boto', 'cache'))
+
+ def __init__(self, working_dir=CACHE_DIR, dumps_func=None):
+ self._working_dir = working_dir
+ if dumps_func is None:
+ dumps_func = self._default_dumps
+ self._dumps = dumps_func
+
+ def _default_dumps(self, obj):
+ return json.dumps(obj, default=self._serialize_if_needed)
+
+ def __contains__(self, cache_key):
+ actual_key = self._convert_cache_key(cache_key)
+ return os.path.isfile(actual_key)
+
+ def __getitem__(self, cache_key):
+ """Retrieve value from a cache key."""
+ actual_key = self._convert_cache_key(cache_key)
+ try:
+ with open(actual_key) as f:
+ return json.load(f)
+ except (OSError, ValueError):
+ raise KeyError(cache_key)
+
+ def __delitem__(self, cache_key):
+ actual_key = self._convert_cache_key(cache_key)
+ try:
+ key_path = Path(actual_key)
+ key_path.unlink()
+ except FileNotFoundError:
+ raise KeyError(cache_key)
+
+ def __setitem__(self, cache_key, value):
+ full_key = self._convert_cache_key(cache_key)
+ try:
+ file_content = self._dumps(value)
+ except (TypeError, ValueError):
+ raise ValueError(
+ f"Value cannot be cached, must be "
+ f"JSON serializable: {value}"
+ )
+ if not os.path.isdir(self._working_dir):
+ os.makedirs(self._working_dir)
+ with os.fdopen(
+ os.open(full_key, os.O_WRONLY | os.O_CREAT, 0o600), 'w'
+ ) as f:
+ f.truncate()
+ f.write(file_content)
+
+ def _convert_cache_key(self, cache_key):
+ full_path = os.path.join(self._working_dir, cache_key + '.json')
+ return full_path
+
+ def _serialize_if_needed(self, value, iso=False):
+ if isinstance(value, datetime.datetime):
+ if iso:
+ return value.isoformat()
+ return value.strftime('%Y-%m-%dT%H:%M:%S%Z')
+ return value
+
+
+# This parameter is not part of the public interface and is subject to abrupt
+# breaking changes or removal without prior announcement.
+# Mapping of services that have been renamed for backwards compatibility reasons.
+# Keys are the previous name that should be allowed, values are the documented
+# and preferred client name.
+SERVICE_NAME_ALIASES = {'runtime.sagemaker': 'sagemaker-runtime'}
+
+
+# This parameter is not part of the public interface and is subject to abrupt
+# breaking changes or removal without prior announcement.
+# Mapping to determine the service ID for services that do not use it as the
+# model data directory name. The keys are the data directory name and the
+# values are the transformed service IDs (lower case and hyphenated).
+CLIENT_NAME_TO_HYPHENIZED_SERVICE_ID_OVERRIDES = {
+ # Actual service name we use -> Allowed computed service name.
+ 'alexaforbusiness': 'alexa-for-business',
+ 'apigateway': 'api-gateway',
+ 'application-autoscaling': 'application-auto-scaling',
+ 'appmesh': 'app-mesh',
+ 'autoscaling': 'auto-scaling',
+ 'autoscaling-plans': 'auto-scaling-plans',
+ 'ce': 'cost-explorer',
+ 'cloudhsmv2': 'cloudhsm-v2',
+ 'cloudsearchdomain': 'cloudsearch-domain',
+ 'cognito-idp': 'cognito-identity-provider',
+ 'config': 'config-service',
+ 'cur': 'cost-and-usage-report-service',
+ 'datapipeline': 'data-pipeline',
+ 'directconnect': 'direct-connect',
+ 'devicefarm': 'device-farm',
+ 'discovery': 'application-discovery-service',
+ 'dms': 'database-migration-service',
+ 'ds': 'directory-service',
+ 'dynamodbstreams': 'dynamodb-streams',
+ 'elasticbeanstalk': 'elastic-beanstalk',
+ 'elastictranscoder': 'elastic-transcoder',
+ 'elb': 'elastic-load-balancing',
+ 'elbv2': 'elastic-load-balancing-v2',
+ 'es': 'elasticsearch-service',
+ 'events': 'eventbridge',
+ 'globalaccelerator': 'global-accelerator',
+ 'iot-data': 'iot-data-plane',
+ 'iot-jobs-data': 'iot-jobs-data-plane',
+ 'iot1click-devices': 'iot-1click-devices-service',
+ 'iot1click-projects': 'iot-1click-projects',
+ 'iotevents-data': 'iot-events-data',
+ 'iotevents': 'iot-events',
+ 'iotwireless': 'iot-wireless',
+ 'kinesisanalytics': 'kinesis-analytics',
+ 'kinesisanalyticsv2': 'kinesis-analytics-v2',
+ 'kinesisvideo': 'kinesis-video',
+ 'lex-models': 'lex-model-building-service',
+ 'lexv2-models': 'lex-models-v2',
+ 'lex-runtime': 'lex-runtime-service',
+ 'lexv2-runtime': 'lex-runtime-v2',
+ 'logs': 'cloudwatch-logs',
+ 'machinelearning': 'machine-learning',
+ 'marketplacecommerceanalytics': 'marketplace-commerce-analytics',
+ 'marketplace-entitlement': 'marketplace-entitlement-service',
+ 'meteringmarketplace': 'marketplace-metering',
+ 'mgh': 'migration-hub',
+ 'sms-voice': 'pinpoint-sms-voice',
+ 'resourcegroupstaggingapi': 'resource-groups-tagging-api',
+ 'route53': 'route-53',
+ 'route53domains': 'route-53-domains',
+ 's3control': 's3-control',
+ 'sdb': 'simpledb',
+ 'secretsmanager': 'secrets-manager',
+ 'serverlessrepo': 'serverlessapplicationrepository',
+ 'servicecatalog': 'service-catalog',
+ 'servicecatalog-appregistry': 'service-catalog-appregistry',
+ 'stepfunctions': 'sfn',
+ 'storagegateway': 'storage-gateway',
+}
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/validate.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/validate.py
new file mode 100644
index 0000000000..dfcca3daa8
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/validate.py
@@ -0,0 +1,384 @@
+"""User input parameter validation.
+
+This module handles user input parameter validation
+against a provided input model.
+
+Note that the objects in this module do *not* mutate any
+arguments. No type version happens here. It is up to another
+layer to properly convert arguments to any required types.
+
+Validation Errors
+-----------------
+
+
+"""
+
+import decimal
+import json
+from datetime import datetime
+
+from botocore.exceptions import ParamValidationError
+from botocore.utils import is_json_value_header, parse_to_aware_datetime
+
+
+def validate_parameters(params, shape):
+ """Validates input parameters against a schema.
+
+ This is a convenience function that validates parameters against a schema.
+ You can also instantiate and use the ParamValidator class directly if you
+ want more control.
+
+ If there are any validation errors then a ParamValidationError
+ will be raised. If there are no validation errors than no exception
+ is raised and a value of None is returned.
+
+ :param params: The user provided input parameters.
+
+ :type shape: botocore.model.Shape
+ :param shape: The schema which the input parameters should
+ adhere to.
+
+ :raise: ParamValidationError
+
+ """
+ validator = ParamValidator()
+ report = validator.validate(params, shape)
+ if report.has_errors():
+ raise ParamValidationError(report=report.generate_report())
+
+
+def type_check(valid_types):
+ def _create_type_check_guard(func):
+ def _on_passes_type_check(self, param, shape, errors, name):
+ if _type_check(param, errors, name):
+ return func(self, param, shape, errors, name)
+
+ def _type_check(param, errors, name):
+ if not isinstance(param, valid_types):
+ valid_type_names = [str(t) for t in valid_types]
+ errors.report(
+ name,
+ 'invalid type',
+ param=param,
+ valid_types=valid_type_names,
+ )
+ return False
+ return True
+
+ return _on_passes_type_check
+
+ return _create_type_check_guard
+
+
+def range_check(name, value, shape, error_type, errors):
+ failed = False
+ min_allowed = float('-inf')
+ if 'min' in shape.metadata:
+ min_allowed = shape.metadata['min']
+ if value < min_allowed:
+ failed = True
+ elif hasattr(shape, 'serialization'):
+ # Members that can be bound to the host have an implicit min of 1
+ if shape.serialization.get('hostLabel'):
+ min_allowed = 1
+ if value < min_allowed:
+ failed = True
+ if failed:
+ errors.report(name, error_type, param=value, min_allowed=min_allowed)
+
+
+class ValidationErrors:
+ def __init__(self):
+ self._errors = []
+
+ def has_errors(self):
+ if self._errors:
+ return True
+ return False
+
+ def generate_report(self):
+ error_messages = []
+ for error in self._errors:
+ error_messages.append(self._format_error(error))
+ return '\n'.join(error_messages)
+
+ def _format_error(self, error):
+ error_type, name, additional = error
+ name = self._get_name(name)
+ if error_type == 'missing required field':
+ return (
+ f"Missing required parameter in {name}: "
+ f"\"{additional['required_name']}\""
+ )
+ elif error_type == 'unknown field':
+ unknown_param = additional['unknown_param']
+ valid_names = ', '.join(additional['valid_names'])
+ return (
+ f'Unknown parameter in {name}: "{unknown_param}", '
+ f'must be one of: {valid_names}'
+ )
+ elif error_type == 'invalid type':
+ param = additional['param']
+ param_type = type(param)
+ valid_types = ', '.join(additional['valid_types'])
+ return (
+ f'Invalid type for parameter {name}, value: {param}, '
+ f'type: {param_type}, valid types: {valid_types}'
+ )
+ elif error_type == 'invalid range':
+ param = additional['param']
+ min_allowed = additional['min_allowed']
+ return (
+ f'Invalid value for parameter {name}, value: {param}, '
+ f'valid min value: {min_allowed}'
+ )
+ elif error_type == 'invalid length':
+ param = additional['param']
+ min_allowed = additional['min_allowed']
+ return (
+ f'Invalid length for parameter {name}, value: {param}, '
+ f'valid min length: {min_allowed}'
+ )
+ elif error_type == 'unable to encode to json':
+ return 'Invalid parameter {} must be json serializable: {}'.format(
+ name,
+ additional['type_error'],
+ )
+ elif error_type == 'invalid type for document':
+ param = additional['param']
+ param_type = type(param)
+ valid_types = ', '.join(additional['valid_types'])
+ return (
+ f'Invalid type for document parameter {name}, value: {param}, '
+ f'type: {param_type}, valid types: {valid_types}'
+ )
+ elif error_type == 'more than one input':
+ members = ', '.join(additional['members'])
+ return (
+ f'Invalid number of parameters set for tagged union structure '
+ f'{name}. Can only set one of the following keys: '
+ f'{members}.'
+ )
+ elif error_type == 'empty input':
+ members = ', '.join(additional['members'])
+ return (
+ f'Must set one of the following keys for tagged union'
+ f'structure {name}: {members}.'
+ )
+
+ def _get_name(self, name):
+ if not name:
+ return 'input'
+ elif name.startswith('.'):
+ return name[1:]
+ else:
+ return name
+
+ def report(self, name, reason, **kwargs):
+ self._errors.append((reason, name, kwargs))
+
+
+class ParamValidator:
+ """Validates parameters against a shape model."""
+
+ def validate(self, params, shape):
+ """Validate parameters against a shape model.
+
+ This method will validate the parameters against a provided shape model.
+ All errors will be collected before returning to the caller. This means
+ that this method will not stop at the first error, it will return all
+ possible errors.
+
+ :param params: User provided dict of parameters
+ :param shape: A shape model describing the expected input.
+
+ :return: A list of errors.
+
+ """
+ errors = ValidationErrors()
+ self._validate(params, shape, errors, name='')
+ return errors
+
+ def _check_special_validation_cases(self, shape):
+ if is_json_value_header(shape):
+ return self._validate_jsonvalue_string
+ if shape.type_name == 'structure' and shape.is_document_type:
+ return self._validate_document
+
+ def _validate(self, params, shape, errors, name):
+ special_validator = self._check_special_validation_cases(shape)
+ if special_validator:
+ special_validator(params, shape, errors, name)
+ else:
+ getattr(self, '_validate_%s' % shape.type_name)(
+ params, shape, errors, name
+ )
+
+ def _validate_jsonvalue_string(self, params, shape, errors, name):
+ # Check to see if a value marked as a jsonvalue can be dumped to
+ # a json string.
+ try:
+ json.dumps(params)
+ except (ValueError, TypeError) as e:
+ errors.report(name, 'unable to encode to json', type_error=e)
+
+ def _validate_document(self, params, shape, errors, name):
+ if params is None:
+ return
+
+ if isinstance(params, dict):
+ for key in params:
+ self._validate_document(params[key], shape, errors, key)
+ elif isinstance(params, list):
+ for index, entity in enumerate(params):
+ self._validate_document(
+ entity, shape, errors, '%s[%d]' % (name, index)
+ )
+ elif not isinstance(params, ((str,), int, bool, float)):
+ valid_types = (str, int, bool, float, list, dict)
+ valid_type_names = [str(t) for t in valid_types]
+ errors.report(
+ name,
+ 'invalid type for document',
+ param=params,
+ param_type=type(params),
+ valid_types=valid_type_names,
+ )
+
+ @type_check(valid_types=(dict,))
+ def _validate_structure(self, params, shape, errors, name):
+ if shape.is_tagged_union:
+ if len(params) == 0:
+ errors.report(name, 'empty input', members=shape.members)
+ elif len(params) > 1:
+ errors.report(
+ name, 'more than one input', members=shape.members
+ )
+
+ # Validate required fields.
+ for required_member in shape.metadata.get('required', []):
+ if required_member not in params:
+ errors.report(
+ name,
+ 'missing required field',
+ required_name=required_member,
+ user_params=params,
+ )
+ members = shape.members
+ known_params = []
+ # Validate known params.
+ for param in params:
+ if param not in members:
+ errors.report(
+ name,
+ 'unknown field',
+ unknown_param=param,
+ valid_names=list(members),
+ )
+ else:
+ known_params.append(param)
+ # Validate structure members.
+ for param in known_params:
+ self._validate(
+ params[param],
+ shape.members[param],
+ errors,
+ f'{name}.{param}',
+ )
+
+ @type_check(valid_types=(str,))
+ def _validate_string(self, param, shape, errors, name):
+ # Validate range. For a string, the min/max constraints
+ # are of the string length.
+ # Looks like:
+ # "WorkflowId":{
+ # "type":"string",
+ # "min":1,
+ # "max":256
+ # }
+ range_check(name, len(param), shape, 'invalid length', errors)
+
+ @type_check(valid_types=(list, tuple))
+ def _validate_list(self, param, shape, errors, name):
+ member_shape = shape.member
+ range_check(name, len(param), shape, 'invalid length', errors)
+ for i, item in enumerate(param):
+ self._validate(item, member_shape, errors, f'{name}[{i}]')
+
+ @type_check(valid_types=(dict,))
+ def _validate_map(self, param, shape, errors, name):
+ key_shape = shape.key
+ value_shape = shape.value
+ for key, value in param.items():
+ self._validate(key, key_shape, errors, f"{name} (key: {key})")
+ self._validate(value, value_shape, errors, f'{name}.{key}')
+
+ @type_check(valid_types=(int,))
+ def _validate_integer(self, param, shape, errors, name):
+ range_check(name, param, shape, 'invalid range', errors)
+
+ def _validate_blob(self, param, shape, errors, name):
+ if isinstance(param, (bytes, bytearray, str)):
+ return
+ elif hasattr(param, 'read'):
+ # File like objects are also allowed for blob types.
+ return
+ else:
+ errors.report(
+ name,
+ 'invalid type',
+ param=param,
+ valid_types=[str(bytes), str(bytearray), 'file-like object'],
+ )
+
+ @type_check(valid_types=(bool,))
+ def _validate_boolean(self, param, shape, errors, name):
+ pass
+
+ @type_check(valid_types=(float, decimal.Decimal) + (int,))
+ def _validate_double(self, param, shape, errors, name):
+ range_check(name, param, shape, 'invalid range', errors)
+
+ _validate_float = _validate_double
+
+ @type_check(valid_types=(int,))
+ def _validate_long(self, param, shape, errors, name):
+ range_check(name, param, shape, 'invalid range', errors)
+
+ def _validate_timestamp(self, param, shape, errors, name):
+ # We don't use @type_check because datetimes are a bit
+ # more flexible. You can either provide a datetime
+ # object, or a string that parses to a datetime.
+ is_valid_type = self._type_check_datetime(param)
+ if not is_valid_type:
+ valid_type_names = [str(datetime), 'timestamp-string']
+ errors.report(
+ name, 'invalid type', param=param, valid_types=valid_type_names
+ )
+
+ def _type_check_datetime(self, value):
+ try:
+ parse_to_aware_datetime(value)
+ return True
+ except (TypeError, ValueError, AttributeError):
+ # Yes, dateutil can sometimes raise an AttributeError
+ # when parsing timestamps.
+ return False
+
+
+class ParamValidationDecorator:
+ def __init__(self, param_validator, serializer):
+ self._param_validator = param_validator
+ self._serializer = serializer
+
+ def serialize_to_request(self, parameters, operation_model):
+ input_shape = operation_model.input_shape
+ if input_shape is not None:
+ report = self._param_validator.validate(
+ parameters, operation_model.input_shape
+ )
+ if report.has_errors():
+ raise ParamValidationError(report=report.generate_report())
+ return self._serializer.serialize_to_request(
+ parameters, operation_model
+ )
diff --git a/lambda-sfn/ response.json b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__init__.py
similarity index 100%
rename from lambda-sfn/ response.json
rename to eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__init__.py
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..aed15aeeca
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__pycache__/six.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__pycache__/six.cpython-311.pyc
new file mode 100644
index 0000000000..33d167fc18
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/__pycache__/six.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__init__.py
new file mode 100644
index 0000000000..0ada6e0f4c
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__init__.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+
+# __
+# /__) _ _ _ _ _/ _
+# / ( (- (/ (/ (- _) / _)
+# /
+from .exceptions import (
+ RequestException, Timeout, URLRequired,
+ TooManyRedirects, HTTPError, ConnectionError
+)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..46c2eeb05b
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__pycache__/exceptions.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__pycache__/exceptions.cpython-311.pyc
new file mode 100644
index 0000000000..b16ac08942
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/__pycache__/exceptions.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/exceptions.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/exceptions.py
new file mode 100644
index 0000000000..89135a802e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/exceptions.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+
+"""
+requests.exceptions
+~~~~~~~~~~~~~~~~~~~
+
+This module contains the set of Requests' exceptions.
+
+"""
+from .packages.urllib3.exceptions import HTTPError as BaseHTTPError
+
+
+class RequestException(IOError):
+ """There was an ambiguous exception that occurred while handling your
+ request."""
+
+ def __init__(self, *args, **kwargs):
+ """
+ Initialize RequestException with `request` and `response` objects.
+ """
+ response = kwargs.pop('response', None)
+ self.response = response
+ self.request = kwargs.pop('request', None)
+ if (response is not None and not self.request and
+ hasattr(response, 'request')):
+ self.request = self.response.request
+ super(RequestException, self).__init__(*args, **kwargs)
+
+
+class HTTPError(RequestException):
+ """An HTTP error occurred."""
+
+
+class ConnectionError(RequestException):
+ """A Connection error occurred."""
+
+
+class ProxyError(ConnectionError):
+ """A proxy error occurred."""
+
+
+class SSLError(ConnectionError):
+ """An SSL error occurred."""
+
+
+class Timeout(RequestException):
+ """The request timed out.
+
+ Catching this error will catch both
+ :exc:`~requests.exceptions.ConnectTimeout` and
+ :exc:`~requests.exceptions.ReadTimeout` errors.
+ """
+
+
+class ConnectTimeout(ConnectionError, Timeout):
+ """The request timed out while trying to connect to the remote server.
+
+ Requests that produced this error are safe to retry.
+ """
+
+
+class ReadTimeout(Timeout):
+ """The server did not send any data in the allotted amount of time."""
+
+
+class URLRequired(RequestException):
+ """A valid URL is required to make a request."""
+
+
+class TooManyRedirects(RequestException):
+ """Too many redirects."""
+
+
+class MissingSchema(RequestException, ValueError):
+ """The URL schema (e.g. http or https) is missing."""
+
+
+class InvalidSchema(RequestException, ValueError):
+ """See defaults.py for valid schemas."""
+
+
+class InvalidURL(RequestException, ValueError):
+ """ The URL provided was somehow invalid. """
+
+
+class ChunkedEncodingError(RequestException):
+ """The server declared chunked encoding but sent an invalid chunk."""
+
+
+class ContentDecodingError(RequestException, BaseHTTPError):
+ """Failed to decode response content"""
+
+
+class StreamConsumedError(RequestException, TypeError):
+ """The content for this response was already consumed"""
+
+
+class RetryError(RequestException):
+ """Custom retries logic failed"""
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/__init__.py
new file mode 100644
index 0000000000..d62c4b7111
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/__init__.py
@@ -0,0 +1,3 @@
+from __future__ import absolute_import
+
+from . import urllib3
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..6dd11ff28e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__init__.py
new file mode 100644
index 0000000000..88697016b4
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__init__.py
@@ -0,0 +1,10 @@
+"""
+urllib3 - Thread-safe connection pooling and re-using.
+"""
+
+__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)'
+__license__ = 'MIT'
+__version__ = ''
+
+
+from . import exceptions
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..69ced53c2d
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__pycache__/exceptions.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__pycache__/exceptions.cpython-311.pyc
new file mode 100644
index 0000000000..7832f0ff71
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/__pycache__/exceptions.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/exceptions.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/exceptions.py
new file mode 100644
index 0000000000..31bda1c07e
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/requests/packages/urllib3/exceptions.py
@@ -0,0 +1,169 @@
+
+## Base Exceptions
+
+class HTTPError(Exception):
+ "Base exception used by this module."
+ pass
+
+class HTTPWarning(Warning):
+ "Base warning used by this module."
+ pass
+
+
+
+class PoolError(HTTPError):
+ "Base exception for errors caused within a pool."
+ def __init__(self, pool, message):
+ self.pool = pool
+ HTTPError.__init__(self, "%s: %s" % (pool, message))
+
+ def __reduce__(self):
+ # For pickling purposes.
+ return self.__class__, (None, None)
+
+
+class RequestError(PoolError):
+ "Base exception for PoolErrors that have associated URLs."
+ def __init__(self, pool, url, message):
+ self.url = url
+ PoolError.__init__(self, pool, message)
+
+ def __reduce__(self):
+ # For pickling purposes.
+ return self.__class__, (None, self.url, None)
+
+
+class SSLError(HTTPError):
+ "Raised when SSL certificate fails in an HTTPS connection."
+ pass
+
+
+class ProxyError(HTTPError):
+ "Raised when the connection to a proxy fails."
+ pass
+
+
+class DecodeError(HTTPError):
+ "Raised when automatic decoding based on Content-Type fails."
+ pass
+
+
+class ProtocolError(HTTPError):
+ "Raised when something unexpected happens mid-request/response."
+ pass
+
+
+#: Renamed to ProtocolError but aliased for backwards compatibility.
+ConnectionError = ProtocolError
+
+
+## Leaf Exceptions
+
+class MaxRetryError(RequestError):
+ """Raised when the maximum number of retries is exceeded.
+
+ :param pool: The connection pool
+ :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
+ :param string url: The requested Url
+ :param exceptions.Exception reason: The underlying error
+
+ """
+
+ def __init__(self, pool, url, reason=None):
+ self.reason = reason
+
+ message = "Max retries exceeded with url: %s (Caused by %r)" % (
+ url, reason)
+
+ RequestError.__init__(self, pool, url, message)
+
+
+class HostChangedError(RequestError):
+ "Raised when an existing pool gets a request for a foreign host."
+
+ def __init__(self, pool, url, retries=3):
+ message = "Tried to open a foreign host with url: %s" % url
+ RequestError.__init__(self, pool, url, message)
+ self.retries = retries
+
+
+class TimeoutStateError(HTTPError):
+ """ Raised when passing an invalid state to a timeout """
+ pass
+
+
+class TimeoutError(HTTPError):
+ """ Raised when a socket timeout error occurs.
+
+ Catching this error will catch both :exc:`ReadTimeoutErrors
+ ` and :exc:`ConnectTimeoutErrors `.
+ """
+ pass
+
+
+class ReadTimeoutError(TimeoutError, RequestError):
+ "Raised when a socket timeout occurs while receiving data from a server"
+ pass
+
+
+# This timeout error does not have a URL attached and needs to inherit from the
+# base HTTPError
+class ConnectTimeoutError(TimeoutError):
+ "Raised when a socket timeout occurs while connecting to a server"
+ pass
+
+
+class EmptyPoolError(PoolError):
+ "Raised when a pool runs out of connections and no more are allowed."
+ pass
+
+
+class ClosedPoolError(PoolError):
+ "Raised when a request enters a pool after the pool has been closed."
+ pass
+
+
+class LocationValueError(ValueError, HTTPError):
+ "Raised when there is something wrong with a given URL input."
+ pass
+
+
+class LocationParseError(LocationValueError):
+ "Raised when get_host or similar fails to parse the URL input."
+
+ def __init__(self, location):
+ message = "Failed to parse: %s" % location
+ HTTPError.__init__(self, message)
+
+ self.location = location
+
+
+class ResponseError(HTTPError):
+ "Used as a container for an error reason supplied in a MaxRetryError."
+ GENERIC_ERROR = 'too many error responses'
+ SPECIFIC_ERROR = 'too many {status_code} error responses'
+
+
+class SecurityWarning(HTTPWarning):
+ "Warned when perfoming security reducing actions"
+ pass
+
+
+class InsecureRequestWarning(SecurityWarning):
+ "Warned when making an unverified HTTPS request."
+ pass
+
+
+class SystemTimeWarning(SecurityWarning):
+ "Warned when system time is suspected to be wrong"
+ pass
+
+
+class InsecurePlatformWarning(SecurityWarning):
+ "Warned when certain SSL configuration is not available on a platform."
+ pass
+
+
+class ResponseNotChunked(ProtocolError, ValueError):
+ "Response needs to be chunked in order to read it as chunks."
+ pass
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/six.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/six.py
new file mode 100644
index 0000000000..4e15675d8b
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/vendored/six.py
@@ -0,0 +1,998 @@
+# Copyright (c) 2010-2020 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+from __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson "
+__version__ = "1.16.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+ string_types = str,
+ integer_types = int,
+ class_types = type,
+ text_type = str
+ binary_type = bytes
+
+ MAXSIZE = sys.maxsize
+else:
+ string_types = basestring,
+ integer_types = (int, long)
+ class_types = (type, types.ClassType)
+ text_type = unicode
+ binary_type = str
+
+ if sys.platform.startswith("java"):
+ # Jython always uses 32 bits.
+ MAXSIZE = int((1 << 31) - 1)
+ else:
+ # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+ class X(object):
+
+ def __len__(self):
+ return 1 << 31
+ try:
+ len(X())
+ except OverflowError:
+ # 32-bit
+ MAXSIZE = int((1 << 31) - 1)
+ else:
+ # 64-bit
+ MAXSIZE = int((1 << 63) - 1)
+ del X
+
+if PY34:
+ from importlib.util import spec_from_loader
+else:
+ spec_from_loader = None
+
+
+def _add_doc(func, doc):
+ """Add documentation to a function."""
+ func.__doc__ = doc
+
+
+def _import_module(name):
+ """Import module, returning the module after the last dot."""
+ __import__(name)
+ return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+ def __init__(self, name):
+ self.name = name
+
+ def __get__(self, obj, tp):
+ result = self._resolve()
+ setattr(obj, self.name, result) # Invokes __set__.
+ try:
+ # This is a bit ugly, but it avoids running this again by
+ # removing this descriptor.
+ delattr(obj.__class__, self.name)
+ except AttributeError:
+ pass
+ return result
+
+
+class MovedModule(_LazyDescr):
+
+ def __init__(self, name, old, new=None):
+ super(MovedModule, self).__init__(name)
+ if PY3:
+ if new is None:
+ new = name
+ self.mod = new
+ else:
+ self.mod = old
+
+ def _resolve(self):
+ return _import_module(self.mod)
+
+ def __getattr__(self, attr):
+ _module = self._resolve()
+ value = getattr(_module, attr)
+ setattr(self, attr, value)
+ return value
+
+
+class _LazyModule(types.ModuleType):
+
+ def __init__(self, name):
+ super(_LazyModule, self).__init__(name)
+ self.__doc__ = self.__class__.__doc__
+
+ def __dir__(self):
+ attrs = ["__doc__", "__name__"]
+ attrs += [attr.name for attr in self._moved_attributes]
+ return attrs
+
+ # Subclasses should override this
+ _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+ def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+ super(MovedAttribute, self).__init__(name)
+ if PY3:
+ if new_mod is None:
+ new_mod = name
+ self.mod = new_mod
+ if new_attr is None:
+ if old_attr is None:
+ new_attr = name
+ else:
+ new_attr = old_attr
+ self.attr = new_attr
+ else:
+ self.mod = old_mod
+ if old_attr is None:
+ old_attr = name
+ self.attr = old_attr
+
+ def _resolve(self):
+ module = _import_module(self.mod)
+ return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+ """
+ A meta path importer to import six.moves and its submodules.
+
+ This class implements a PEP302 finder and loader. It should be compatible
+ with Python 2.5 and all existing versions of Python3
+ """
+
+ def __init__(self, six_module_name):
+ self.name = six_module_name
+ self.known_modules = {}
+
+ def _add_module(self, mod, *fullnames):
+ for fullname in fullnames:
+ self.known_modules[self.name + "." + fullname] = mod
+
+ def _get_module(self, fullname):
+ return self.known_modules[self.name + "." + fullname]
+
+ def find_module(self, fullname, path=None):
+ if fullname in self.known_modules:
+ return self
+ return None
+
+ def find_spec(self, fullname, path, target=None):
+ if fullname in self.known_modules:
+ return spec_from_loader(fullname, self)
+ return None
+
+ def __get_module(self, fullname):
+ try:
+ return self.known_modules[fullname]
+ except KeyError:
+ raise ImportError("This loader does not know module " + fullname)
+
+ def load_module(self, fullname):
+ try:
+ # in case of a reload
+ return sys.modules[fullname]
+ except KeyError:
+ pass
+ mod = self.__get_module(fullname)
+ if isinstance(mod, MovedModule):
+ mod = mod._resolve()
+ else:
+ mod.__loader__ = self
+ sys.modules[fullname] = mod
+ return mod
+
+ def is_package(self, fullname):
+ """
+ Return true, if the named module is a package.
+
+ We need this method to get correct spec objects with
+ Python 3.4 (see PEP451)
+ """
+ return hasattr(self.__get_module(fullname), "__path__")
+
+ def get_code(self, fullname):
+ """Return None
+
+ Required, if is_package is implemented"""
+ self.__get_module(fullname) # eventually raises ImportError
+ return None
+ get_source = get_code # same as get_code
+
+ def create_module(self, spec):
+ return self.load_module(spec.name)
+
+ def exec_module(self, module):
+ pass
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+ """Lazy loading of moved objects"""
+ __path__ = [] # mark as package
+
+
+_moved_attributes = [
+ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+ MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+ MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+ MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+ MovedAttribute("intern", "__builtin__", "sys"),
+ MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+ MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+ MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+ MovedAttribute("getoutput", "commands", "subprocess"),
+ MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+ MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+ MovedAttribute("reduce", "__builtin__", "functools"),
+ MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+ MovedAttribute("StringIO", "StringIO", "io"),
+ MovedAttribute("UserDict", "UserDict", "collections"),
+ MovedAttribute("UserList", "UserList", "collections"),
+ MovedAttribute("UserString", "UserString", "collections"),
+ MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+ MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+ MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+ MovedModule("builtins", "__builtin__"),
+ MovedModule("configparser", "ConfigParser"),
+ MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
+ MovedModule("copyreg", "copy_reg"),
+ MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+ MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
+ MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
+ MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+ MovedModule("http_cookies", "Cookie", "http.cookies"),
+ MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+ MovedModule("html_parser", "HTMLParser", "html.parser"),
+ MovedModule("http_client", "httplib", "http.client"),
+ MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+ MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
+ MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+ MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+ MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+ MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+ MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+ MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+ MovedModule("cPickle", "cPickle", "pickle"),
+ MovedModule("queue", "Queue"),
+ MovedModule("reprlib", "repr"),
+ MovedModule("socketserver", "SocketServer"),
+ MovedModule("_thread", "thread", "_thread"),
+ MovedModule("tkinter", "Tkinter"),
+ MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+ MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+ MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+ MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+ MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+ MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+ MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+ MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+ MovedModule("tkinter_colorchooser", "tkColorChooser",
+ "tkinter.colorchooser"),
+ MovedModule("tkinter_commondialog", "tkCommonDialog",
+ "tkinter.commondialog"),
+ MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+ MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+ MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+ MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+ "tkinter.simpledialog"),
+ MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+ MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+ MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+ MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+ MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+ MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+ _moved_attributes += [
+ MovedModule("winreg", "_winreg"),
+ ]
+
+for attr in _moved_attributes:
+ setattr(_MovedItems, attr.name, attr)
+ if isinstance(attr, MovedModule):
+ _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+ MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+ MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+ MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+ MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+ MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+ MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+ MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+ MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+ MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+ MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+ MovedAttribute("quote", "urllib", "urllib.parse"),
+ MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("unquote", "urllib", "urllib.parse"),
+ MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
+ MovedAttribute("urlencode", "urllib", "urllib.parse"),
+ MovedAttribute("splitquery", "urllib", "urllib.parse"),
+ MovedAttribute("splittag", "urllib", "urllib.parse"),
+ MovedAttribute("splituser", "urllib", "urllib.parse"),
+ MovedAttribute("splitvalue", "urllib", "urllib.parse"),
+ MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+ setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+ "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+ MovedAttribute("URLError", "urllib2", "urllib.error"),
+ MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+ MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+ setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+ "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+ MovedAttribute("urlopen", "urllib2", "urllib.request"),
+ MovedAttribute("install_opener", "urllib2", "urllib.request"),
+ MovedAttribute("build_opener", "urllib2", "urllib.request"),
+ MovedAttribute("pathname2url", "urllib", "urllib.request"),
+ MovedAttribute("url2pathname", "urllib", "urllib.request"),
+ MovedAttribute("getproxies", "urllib", "urllib.request"),
+ MovedAttribute("Request", "urllib2", "urllib.request"),
+ MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+ MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+ MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+ MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+ MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+ MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+ MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+ MovedAttribute("URLopener", "urllib", "urllib.request"),
+ MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+ MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+ MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
+ MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+ setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+ "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+ MovedAttribute("addbase", "urllib", "urllib.response"),
+ MovedAttribute("addclosehook", "urllib", "urllib.response"),
+ MovedAttribute("addinfo", "urllib", "urllib.response"),
+ MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+ setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+ "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+ setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+ "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+ """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+ __path__ = [] # mark as package
+ parse = _importer._get_module("moves.urllib_parse")
+ error = _importer._get_module("moves.urllib_error")
+ request = _importer._get_module("moves.urllib_request")
+ response = _importer._get_module("moves.urllib_response")
+ robotparser = _importer._get_module("moves.urllib_robotparser")
+
+ def __dir__(self):
+ return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+ "moves.urllib")
+
+
+def add_move(move):
+ """Add an item to six.moves."""
+ setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+ """Remove item from six.moves."""
+ try:
+ delattr(_MovedItems, name)
+ except AttributeError:
+ try:
+ del moves.__dict__[name]
+ except KeyError:
+ raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+ _meth_func = "__func__"
+ _meth_self = "__self__"
+
+ _func_closure = "__closure__"
+ _func_code = "__code__"
+ _func_defaults = "__defaults__"
+ _func_globals = "__globals__"
+else:
+ _meth_func = "im_func"
+ _meth_self = "im_self"
+
+ _func_closure = "func_closure"
+ _func_code = "func_code"
+ _func_defaults = "func_defaults"
+ _func_globals = "func_globals"
+
+
+try:
+ advance_iterator = next
+except NameError:
+ def advance_iterator(it):
+ return it.next()
+next = advance_iterator
+
+
+try:
+ callable = callable
+except NameError:
+ def callable(obj):
+ return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+ def get_unbound_function(unbound):
+ return unbound
+
+ create_bound_method = types.MethodType
+
+ def create_unbound_method(func, cls):
+ return func
+
+ Iterator = object
+else:
+ def get_unbound_function(unbound):
+ return unbound.im_func
+
+ def create_bound_method(func, obj):
+ return types.MethodType(func, obj, obj.__class__)
+
+ def create_unbound_method(func, cls):
+ return types.MethodType(func, None, cls)
+
+ class Iterator(object):
+
+ def next(self):
+ return type(self).__next__(self)
+
+ callable = callable
+_add_doc(get_unbound_function,
+ """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+ def iterkeys(d, **kw):
+ return iter(d.keys(**kw))
+
+ def itervalues(d, **kw):
+ return iter(d.values(**kw))
+
+ def iteritems(d, **kw):
+ return iter(d.items(**kw))
+
+ def iterlists(d, **kw):
+ return iter(d.lists(**kw))
+
+ viewkeys = operator.methodcaller("keys")
+
+ viewvalues = operator.methodcaller("values")
+
+ viewitems = operator.methodcaller("items")
+else:
+ def iterkeys(d, **kw):
+ return d.iterkeys(**kw)
+
+ def itervalues(d, **kw):
+ return d.itervalues(**kw)
+
+ def iteritems(d, **kw):
+ return d.iteritems(**kw)
+
+ def iterlists(d, **kw):
+ return d.iterlists(**kw)
+
+ viewkeys = operator.methodcaller("viewkeys")
+
+ viewvalues = operator.methodcaller("viewvalues")
+
+ viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+ "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+ "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+ def b(s):
+ return s.encode("latin-1")
+
+ def u(s):
+ return s
+ unichr = chr
+ import struct
+ int2byte = struct.Struct(">B").pack
+ del struct
+ byte2int = operator.itemgetter(0)
+ indexbytes = operator.getitem
+ iterbytes = iter
+ import io
+ StringIO = io.StringIO
+ BytesIO = io.BytesIO
+ del io
+ _assertCountEqual = "assertCountEqual"
+ if sys.version_info[1] <= 1:
+ _assertRaisesRegex = "assertRaisesRegexp"
+ _assertRegex = "assertRegexpMatches"
+ _assertNotRegex = "assertNotRegexpMatches"
+ else:
+ _assertRaisesRegex = "assertRaisesRegex"
+ _assertRegex = "assertRegex"
+ _assertNotRegex = "assertNotRegex"
+else:
+ def b(s):
+ return s
+ # Workaround for standalone backslash
+
+ def u(s):
+ return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+ unichr = unichr
+ int2byte = chr
+
+ def byte2int(bs):
+ return ord(bs[0])
+
+ def indexbytes(buf, i):
+ return ord(buf[i])
+ iterbytes = functools.partial(itertools.imap, ord)
+ import StringIO
+ StringIO = BytesIO = StringIO.StringIO
+ _assertCountEqual = "assertItemsEqual"
+ _assertRaisesRegex = "assertRaisesRegexp"
+ _assertRegex = "assertRegexpMatches"
+ _assertNotRegex = "assertNotRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+ return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+ return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+ return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+def assertNotRegex(self, *args, **kwargs):
+ return getattr(self, _assertNotRegex)(*args, **kwargs)
+
+
+if PY3:
+ exec_ = getattr(moves.builtins, "exec")
+
+ def reraise(tp, value, tb=None):
+ try:
+ if value is None:
+ value = tp()
+ if value.__traceback__ is not tb:
+ raise value.with_traceback(tb)
+ raise value
+ finally:
+ value = None
+ tb = None
+
+else:
+ def exec_(_code_, _globs_=None, _locs_=None):
+ """Execute code in a namespace."""
+ if _globs_ is None:
+ frame = sys._getframe(1)
+ _globs_ = frame.f_globals
+ if _locs_ is None:
+ _locs_ = frame.f_locals
+ del frame
+ elif _locs_ is None:
+ _locs_ = _globs_
+ exec("""exec _code_ in _globs_, _locs_""")
+
+ exec_("""def reraise(tp, value, tb=None):
+ try:
+ raise tp, value, tb
+ finally:
+ tb = None
+""")
+
+
+if sys.version_info[:2] > (3,):
+ exec_("""def raise_from(value, from_value):
+ try:
+ raise value from from_value
+ finally:
+ value = None
+""")
+else:
+ def raise_from(value, from_value):
+ raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+ def print_(*args, **kwargs):
+ """The new-style print function for Python 2.4 and 2.5."""
+ fp = kwargs.pop("file", sys.stdout)
+ if fp is None:
+ return
+
+ def write(data):
+ if not isinstance(data, basestring):
+ data = str(data)
+ # If the file has an encoding, encode unicode with it.
+ if (isinstance(fp, file) and
+ isinstance(data, unicode) and
+ fp.encoding is not None):
+ errors = getattr(fp, "errors", None)
+ if errors is None:
+ errors = "strict"
+ data = data.encode(fp.encoding, errors)
+ fp.write(data)
+ want_unicode = False
+ sep = kwargs.pop("sep", None)
+ if sep is not None:
+ if isinstance(sep, unicode):
+ want_unicode = True
+ elif not isinstance(sep, str):
+ raise TypeError("sep must be None or a string")
+ end = kwargs.pop("end", None)
+ if end is not None:
+ if isinstance(end, unicode):
+ want_unicode = True
+ elif not isinstance(end, str):
+ raise TypeError("end must be None or a string")
+ if kwargs:
+ raise TypeError("invalid keyword arguments to print()")
+ if not want_unicode:
+ for arg in args:
+ if isinstance(arg, unicode):
+ want_unicode = True
+ break
+ if want_unicode:
+ newline = unicode("\n")
+ space = unicode(" ")
+ else:
+ newline = "\n"
+ space = " "
+ if sep is None:
+ sep = space
+ if end is None:
+ end = newline
+ for i, arg in enumerate(args):
+ if i:
+ write(sep)
+ write(arg)
+ write(end)
+if sys.version_info[:2] < (3, 3):
+ _print = print_
+
+ def print_(*args, **kwargs):
+ fp = kwargs.get("file", sys.stdout)
+ flush = kwargs.pop("flush", False)
+ _print(*args, **kwargs)
+ if flush and fp is not None:
+ fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+ # This does exactly the same what the :func:`py3:functools.update_wrapper`
+ # function does on Python versions after 3.2. It sets the ``__wrapped__``
+ # attribute on ``wrapper`` object and it doesn't raise an error if any of
+ # the attributes mentioned in ``assigned`` and ``updated`` are missing on
+ # ``wrapped`` object.
+ def _update_wrapper(wrapper, wrapped,
+ assigned=functools.WRAPPER_ASSIGNMENTS,
+ updated=functools.WRAPPER_UPDATES):
+ for attr in assigned:
+ try:
+ value = getattr(wrapped, attr)
+ except AttributeError:
+ continue
+ else:
+ setattr(wrapper, attr, value)
+ for attr in updated:
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
+ wrapper.__wrapped__ = wrapped
+ return wrapper
+ _update_wrapper.__doc__ = functools.update_wrapper.__doc__
+
+ def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+ updated=functools.WRAPPER_UPDATES):
+ return functools.partial(_update_wrapper, wrapped=wrapped,
+ assigned=assigned, updated=updated)
+ wraps.__doc__ = functools.wraps.__doc__
+
+else:
+ wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+ """Create a base class with a metaclass."""
+ # This requires a bit of explanation: the basic idea is to make a dummy
+ # metaclass for one level of class instantiation that replaces itself with
+ # the actual metaclass.
+ class metaclass(type):
+
+ def __new__(cls, name, this_bases, d):
+ if sys.version_info[:2] >= (3, 7):
+ # This version introduced PEP 560 that requires a bit
+ # of extra care (we mimic what is done by __build_class__).
+ resolved_bases = types.resolve_bases(bases)
+ if resolved_bases is not bases:
+ d['__orig_bases__'] = bases
+ else:
+ resolved_bases = bases
+ return meta(name, resolved_bases, d)
+
+ @classmethod
+ def __prepare__(cls, name, this_bases):
+ return meta.__prepare__(name, bases)
+ return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+ """Class decorator for creating a class with a metaclass."""
+ def wrapper(cls):
+ orig_vars = cls.__dict__.copy()
+ slots = orig_vars.get('__slots__')
+ if slots is not None:
+ if isinstance(slots, str):
+ slots = [slots]
+ for slots_var in slots:
+ orig_vars.pop(slots_var)
+ orig_vars.pop('__dict__', None)
+ orig_vars.pop('__weakref__', None)
+ if hasattr(cls, '__qualname__'):
+ orig_vars['__qualname__'] = cls.__qualname__
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
+ return wrapper
+
+
+def ensure_binary(s, encoding='utf-8', errors='strict'):
+ """Coerce **s** to six.binary_type.
+
+ For Python 2:
+ - `unicode` -> encoded to `str`
+ - `str` -> `str`
+
+ For Python 3:
+ - `str` -> encoded to `bytes`
+ - `bytes` -> `bytes`
+ """
+ if isinstance(s, binary_type):
+ return s
+ if isinstance(s, text_type):
+ return s.encode(encoding, errors)
+ raise TypeError("not expecting type '%s'" % type(s))
+
+
+def ensure_str(s, encoding='utf-8', errors='strict'):
+ """Coerce *s* to `str`.
+
+ For Python 2:
+ - `unicode` -> encoded to `str`
+ - `str` -> `str`
+
+ For Python 3:
+ - `str` -> `str`
+ - `bytes` -> decoded to `str`
+ """
+ # Optimization: Fast return for the common case.
+ if type(s) is str:
+ return s
+ if PY2 and isinstance(s, text_type):
+ return s.encode(encoding, errors)
+ elif PY3 and isinstance(s, binary_type):
+ return s.decode(encoding, errors)
+ elif not isinstance(s, (text_type, binary_type)):
+ raise TypeError("not expecting type '%s'" % type(s))
+ return s
+
+
+def ensure_text(s, encoding='utf-8', errors='strict'):
+ """Coerce *s* to six.text_type.
+
+ For Python 2:
+ - `unicode` -> `unicode`
+ - `str` -> `unicode`
+
+ For Python 3:
+ - `str` -> `str`
+ - `bytes` -> decoded to `str`
+ """
+ if isinstance(s, binary_type):
+ return s.decode(encoding, errors)
+ elif isinstance(s, text_type):
+ return s
+ else:
+ raise TypeError("not expecting type '%s'" % type(s))
+
+
+def python_2_unicode_compatible(klass):
+ """
+ A class decorator that defines __unicode__ and __str__ methods under Python 2.
+ Under Python 3 it does nothing.
+
+ To support Python 2 and 3 with a single code base, define a __str__ method
+ returning text and apply this decorator to the class.
+ """
+ if PY2:
+ if '__str__' not in klass.__dict__:
+ raise ValueError("@python_2_unicode_compatible cannot be applied "
+ "to %s because it doesn't define __str__()." %
+ klass.__name__)
+ klass.__unicode__ = klass.__str__
+ klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+ return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = [] # required for PEP 302 and PEP 451
+__package__ = __name__ # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+ __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+ for i, importer in enumerate(sys.meta_path):
+ # Here's some real nastiness: Another "instance" of the six module might
+ # be floating around. Therefore, we can't use isinstance() to check for
+ # the six meta path importer, since the other six instance will have
+ # inserted an importer with different class.
+ if (type(importer).__name__ == "_SixMetaPathImporter" and
+ importer.name == __name__):
+ del sys.meta_path[i]
+ break
+ del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/waiter.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/waiter.py
new file mode 100644
index 0000000000..2362eebeda
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/botocore/waiter.py
@@ -0,0 +1,393 @@
+# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import logging
+import time
+
+import jmespath
+
+from botocore.docs.docstring import WaiterDocstring
+from botocore.utils import get_service_module_name
+
+from . import xform_name
+from .exceptions import ClientError, WaiterConfigError, WaiterError
+
+logger = logging.getLogger(__name__)
+
+
+def create_waiter_with_client(waiter_name, waiter_model, client):
+ """
+
+ :type waiter_name: str
+ :param waiter_name: The name of the waiter. The name should match
+ the name (including the casing) of the key name in the waiter
+ model file (typically this is CamelCasing).
+
+ :type waiter_model: botocore.waiter.WaiterModel
+ :param waiter_model: The model for the waiter configuration.
+
+ :type client: botocore.client.BaseClient
+ :param client: The botocore client associated with the service.
+
+ :rtype: botocore.waiter.Waiter
+ :return: The waiter object.
+
+ """
+ single_waiter_config = waiter_model.get_waiter(waiter_name)
+ operation_name = xform_name(single_waiter_config.operation)
+ operation_method = NormalizedOperationMethod(
+ getattr(client, operation_name)
+ )
+
+ # Create a new wait method that will serve as a proxy to the underlying
+ # Waiter.wait method. This is needed to attach a docstring to the
+ # method.
+ def wait(self, **kwargs):
+ Waiter.wait(self, **kwargs)
+
+ wait.__doc__ = WaiterDocstring(
+ waiter_name=waiter_name,
+ event_emitter=client.meta.events,
+ service_model=client.meta.service_model,
+ service_waiter_model=waiter_model,
+ include_signature=False,
+ )
+
+ # Rename the waiter class based on the type of waiter.
+ waiter_class_name = str(
+ '%s.Waiter.%s'
+ % (get_service_module_name(client.meta.service_model), waiter_name)
+ )
+
+ # Create the new waiter class
+ documented_waiter_cls = type(waiter_class_name, (Waiter,), {'wait': wait})
+
+ # Return an instance of the new waiter class.
+ return documented_waiter_cls(
+ waiter_name, single_waiter_config, operation_method
+ )
+
+
+def is_valid_waiter_error(response):
+ error = response.get('Error')
+ if isinstance(error, dict) and 'Code' in error:
+ return True
+ return False
+
+
+class NormalizedOperationMethod:
+ def __init__(self, client_method):
+ self._client_method = client_method
+
+ def __call__(self, **kwargs):
+ try:
+ return self._client_method(**kwargs)
+ except ClientError as e:
+ return e.response
+
+
+class WaiterModel:
+ SUPPORTED_VERSION = 2
+
+ def __init__(self, waiter_config):
+ """
+
+ Note that the WaiterModel takes ownership of the waiter_config.
+ It may or may not mutate the waiter_config. If this is a concern,
+ it is best to make a copy of the waiter config before passing it to
+ the WaiterModel.
+
+ :type waiter_config: dict
+ :param waiter_config: The loaded waiter config
+ from the *.waiters.json file. This can be
+ obtained from a botocore Loader object as well.
+
+ """
+ self._waiter_config = waiter_config['waiters']
+
+ # These are part of the public API. Changing these
+ # will result in having to update the consuming code,
+ # so don't change unless you really need to.
+ version = waiter_config.get('version', 'unknown')
+ self._verify_supported_version(version)
+ self.version = version
+ self.waiter_names = list(sorted(waiter_config['waiters'].keys()))
+
+ def _verify_supported_version(self, version):
+ if version != self.SUPPORTED_VERSION:
+ raise WaiterConfigError(
+ error_msg=(
+ "Unsupported waiter version, supported version "
+ "must be: %s, but version of waiter config "
+ "is: %s" % (self.SUPPORTED_VERSION, version)
+ )
+ )
+
+ def get_waiter(self, waiter_name):
+ try:
+ single_waiter_config = self._waiter_config[waiter_name]
+ except KeyError:
+ raise ValueError("Waiter does not exist: %s" % waiter_name)
+ return SingleWaiterConfig(single_waiter_config)
+
+
+class SingleWaiterConfig:
+ """Represents the waiter configuration for a single waiter.
+
+ A single waiter is considered the configuration for a single
+ value associated with a named waiter (i.e TableExists).
+
+ """
+
+ def __init__(self, single_waiter_config):
+ self._config = single_waiter_config
+
+ # These attributes are part of the public API.
+ self.description = single_waiter_config.get('description', '')
+ # Per the spec, these three fields are required.
+ self.operation = single_waiter_config['operation']
+ self.delay = single_waiter_config['delay']
+ self.max_attempts = single_waiter_config['maxAttempts']
+
+ @property
+ def acceptors(self):
+ acceptors = []
+ for acceptor_config in self._config['acceptors']:
+ acceptor = AcceptorConfig(acceptor_config)
+ acceptors.append(acceptor)
+ return acceptors
+
+
+class AcceptorConfig:
+ def __init__(self, config):
+ self.state = config['state']
+ self.matcher = config['matcher']
+ self.expected = config['expected']
+ self.argument = config.get('argument')
+ self.matcher_func = self._create_matcher_func()
+
+ @property
+ def explanation(self):
+ if self.matcher == 'path':
+ return 'For expression "{}" we matched expected path: "{}"'.format(
+ self.argument,
+ self.expected,
+ )
+ elif self.matcher == 'pathAll':
+ return (
+ 'For expression "%s" all members matched excepted path: "%s"'
+ % (self.argument, self.expected)
+ )
+ elif self.matcher == 'pathAny':
+ return (
+ 'For expression "%s" we matched expected path: "%s" at least once'
+ % (self.argument, self.expected)
+ )
+ elif self.matcher == 'status':
+ return 'Matched expected HTTP status code: %s' % self.expected
+ elif self.matcher == 'error':
+ return 'Matched expected service error code: %s' % self.expected
+ else:
+ return (
+ 'No explanation for unknown waiter type: "%s"' % self.matcher
+ )
+
+ def _create_matcher_func(self):
+ # An acceptor function is a callable that takes a single value. The
+ # parsed AWS response. Note that the parsed error response is also
+ # provided in the case of errors, so it's entirely possible to
+ # handle all the available matcher capabilities in the future.
+ # There's only three supported matchers, so for now, this is all
+ # contained to a single method. If this grows, we can expand this
+ # out to separate methods or even objects.
+
+ if self.matcher == 'path':
+ return self._create_path_matcher()
+ elif self.matcher == 'pathAll':
+ return self._create_path_all_matcher()
+ elif self.matcher == 'pathAny':
+ return self._create_path_any_matcher()
+ elif self.matcher == 'status':
+ return self._create_status_matcher()
+ elif self.matcher == 'error':
+ return self._create_error_matcher()
+ else:
+ raise WaiterConfigError(
+ error_msg="Unknown acceptor: %s" % self.matcher
+ )
+
+ def _create_path_matcher(self):
+ expression = jmespath.compile(self.argument)
+ expected = self.expected
+
+ def acceptor_matches(response):
+ if is_valid_waiter_error(response):
+ return
+ return expression.search(response) == expected
+
+ return acceptor_matches
+
+ def _create_path_all_matcher(self):
+ expression = jmespath.compile(self.argument)
+ expected = self.expected
+
+ def acceptor_matches(response):
+ if is_valid_waiter_error(response):
+ return
+ result = expression.search(response)
+ if not isinstance(result, list) or not result:
+ # pathAll matcher must result in a list.
+ # Also we require at least one element in the list,
+ # that is, an empty list should not result in this
+ # acceptor match.
+ return False
+ for element in result:
+ if element != expected:
+ return False
+ return True
+
+ return acceptor_matches
+
+ def _create_path_any_matcher(self):
+ expression = jmespath.compile(self.argument)
+ expected = self.expected
+
+ def acceptor_matches(response):
+ if is_valid_waiter_error(response):
+ return
+ result = expression.search(response)
+ if not isinstance(result, list) or not result:
+ # pathAny matcher must result in a list.
+ # Also we require at least one element in the list,
+ # that is, an empty list should not result in this
+ # acceptor match.
+ return False
+ for element in result:
+ if element == expected:
+ return True
+ return False
+
+ return acceptor_matches
+
+ def _create_status_matcher(self):
+ expected = self.expected
+
+ def acceptor_matches(response):
+ # We don't have any requirements on the expected incoming data
+ # other than it is a dict, so we don't assume there's
+ # a ResponseMetadata.HTTPStatusCode.
+ status_code = response.get('ResponseMetadata', {}).get(
+ 'HTTPStatusCode'
+ )
+ return status_code == expected
+
+ return acceptor_matches
+
+ def _create_error_matcher(self):
+ expected = self.expected
+
+ def acceptor_matches(response):
+ # When the client encounters an error, it will normally raise
+ # an exception. However, the waiter implementation will catch
+ # this exception, and instead send us the parsed error
+ # response. So response is still a dictionary, and in the case
+ # of an error response will contain the "Error" and
+ # "ResponseMetadata" key.
+ return response.get("Error", {}).get("Code", "") == expected
+
+ return acceptor_matches
+
+
+class Waiter:
+ def __init__(self, name, config, operation_method):
+ """
+
+ :type name: string
+ :param name: The name of the waiter
+
+ :type config: botocore.waiter.SingleWaiterConfig
+ :param config: The configuration for the waiter.
+
+ :type operation_method: callable
+ :param operation_method: A callable that accepts **kwargs
+ and returns a response. For example, this can be
+ a method from a botocore client.
+
+ """
+ self._operation_method = operation_method
+ # The two attributes are exposed to allow for introspection
+ # and documentation.
+ self.name = name
+ self.config = config
+
+ def wait(self, **kwargs):
+ acceptors = list(self.config.acceptors)
+ current_state = 'waiting'
+ # pop the invocation specific config
+ config = kwargs.pop('WaiterConfig', {})
+ sleep_amount = config.get('Delay', self.config.delay)
+ max_attempts = config.get('MaxAttempts', self.config.max_attempts)
+ last_matched_acceptor = None
+ num_attempts = 0
+
+ while True:
+ response = self._operation_method(**kwargs)
+ num_attempts += 1
+ for acceptor in acceptors:
+ if acceptor.matcher_func(response):
+ last_matched_acceptor = acceptor
+ current_state = acceptor.state
+ break
+ else:
+ # If none of the acceptors matched, we should
+ # transition to the failure state if an error
+ # response was received.
+ if is_valid_waiter_error(response):
+ # Transition to a failure state, which we
+ # can just handle here by raising an exception.
+ raise WaiterError(
+ name=self.name,
+ reason='An error occurred (%s): %s'
+ % (
+ response['Error'].get('Code', 'Unknown'),
+ response['Error'].get('Message', 'Unknown'),
+ ),
+ last_response=response,
+ )
+ if current_state == 'success':
+ logger.debug(
+ "Waiting complete, waiter matched the " "success state."
+ )
+ return
+ if current_state == 'failure':
+ reason = 'Waiter encountered a terminal failure state: %s' % (
+ acceptor.explanation
+ )
+ raise WaiterError(
+ name=self.name,
+ reason=reason,
+ last_response=response,
+ )
+ if num_attempts >= max_attempts:
+ if last_matched_acceptor is None:
+ reason = 'Max attempts exceeded'
+ else:
+ reason = (
+ 'Max attempts exceeded. Previously accepted state: %s'
+ % (acceptor.explanation)
+ )
+ raise WaiterError(
+ name=self.name,
+ reason=reason,
+ last_response=response,
+ )
+ time.sleep(sleep_amount)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__init__.py
new file mode 100644
index 0000000000..0defb82e21
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__init__.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+try:
+ from ._version import version as __version__
+except ImportError:
+ __version__ = 'unknown'
+
+__all__ = ['easter', 'parser', 'relativedelta', 'rrule', 'tz',
+ 'utils', 'zoneinfo']
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..da095d0b43
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/_common.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/_common.cpython-311.pyc
new file mode 100644
index 0000000000..1ada6c4b5a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/_common.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/_version.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/_version.cpython-311.pyc
new file mode 100644
index 0000000000..b2b3d80d2c
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/_version.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/easter.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/easter.cpython-311.pyc
new file mode 100644
index 0000000000..200870c89e
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/easter.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/relativedelta.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/relativedelta.cpython-311.pyc
new file mode 100644
index 0000000000..391536c0b0
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/relativedelta.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/rrule.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/rrule.cpython-311.pyc
new file mode 100644
index 0000000000..6832c72a0a
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/rrule.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/tzwin.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/tzwin.cpython-311.pyc
new file mode 100644
index 0000000000..24c0672ce8
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/tzwin.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/utils.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/utils.cpython-311.pyc
new file mode 100644
index 0000000000..4737c4f895
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/__pycache__/utils.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/_common.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/_common.py
new file mode 100644
index 0000000000..4eb2659bd2
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/_common.py
@@ -0,0 +1,43 @@
+"""
+Common code used in multiple modules.
+"""
+
+
+class weekday(object):
+ __slots__ = ["weekday", "n"]
+
+ def __init__(self, weekday, n=None):
+ self.weekday = weekday
+ self.n = n
+
+ def __call__(self, n):
+ if n == self.n:
+ return self
+ else:
+ return self.__class__(self.weekday, n)
+
+ def __eq__(self, other):
+ try:
+ if self.weekday != other.weekday or self.n != other.n:
+ return False
+ except AttributeError:
+ return False
+ return True
+
+ def __hash__(self):
+ return hash((
+ self.weekday,
+ self.n,
+ ))
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
+ if not self.n:
+ return s
+ else:
+ return "%s(%+d)" % (s, self.n)
+
+# vim:ts=4:sw=4:et
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/_version.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/_version.py
new file mode 100644
index 0000000000..b723056a75
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/_version.py
@@ -0,0 +1,5 @@
+# coding: utf-8
+# file generated by setuptools_scm
+# don't change, don't track in version control
+version = '2.8.2'
+version_tuple = (2, 8, 2)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/easter.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/easter.py
new file mode 100644
index 0000000000..f74d1f7442
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/easter.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+"""
+This module offers a generic Easter computing method for any given year, using
+Western, Orthodox or Julian algorithms.
+"""
+
+import datetime
+
+__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"]
+
+EASTER_JULIAN = 1
+EASTER_ORTHODOX = 2
+EASTER_WESTERN = 3
+
+
+def easter(year, method=EASTER_WESTERN):
+ """
+ This method was ported from the work done by GM Arts,
+ on top of the algorithm by Claus Tondering, which was
+ based in part on the algorithm of Ouding (1940), as
+ quoted in "Explanatory Supplement to the Astronomical
+ Almanac", P. Kenneth Seidelmann, editor.
+
+ This algorithm implements three different Easter
+ calculation methods:
+
+ 1. Original calculation in Julian calendar, valid in
+ dates after 326 AD
+ 2. Original method, with date converted to Gregorian
+ calendar, valid in years 1583 to 4099
+ 3. Revised method, in Gregorian calendar, valid in
+ years 1583 to 4099 as well
+
+ These methods are represented by the constants:
+
+ * ``EASTER_JULIAN = 1``
+ * ``EASTER_ORTHODOX = 2``
+ * ``EASTER_WESTERN = 3``
+
+ The default method is method 3.
+
+ More about the algorithm may be found at:
+
+ `GM Arts: Easter Algorithms `_
+
+ and
+
+ `The Calendar FAQ: Easter `_
+
+ """
+
+ if not (1 <= method <= 3):
+ raise ValueError("invalid method")
+
+ # g - Golden year - 1
+ # c - Century
+ # h - (23 - Epact) mod 30
+ # i - Number of days from March 21 to Paschal Full Moon
+ # j - Weekday for PFM (0=Sunday, etc)
+ # p - Number of days from March 21 to Sunday on or before PFM
+ # (-6 to 28 methods 1 & 3, to 56 for method 2)
+ # e - Extra days to add for method 2 (converting Julian
+ # date to Gregorian date)
+
+ y = year
+ g = y % 19
+ e = 0
+ if method < 3:
+ # Old method
+ i = (19*g + 15) % 30
+ j = (y + y//4 + i) % 7
+ if method == 2:
+ # Extra dates to convert Julian to Gregorian date
+ e = 10
+ if y > 1600:
+ e = e + y//100 - 16 - (y//100 - 16)//4
+ else:
+ # New method
+ c = y//100
+ h = (c - c//4 - (8*c + 13)//25 + 19*g + 15) % 30
+ i = h - (h//28)*(1 - (h//28)*(29//(h + 1))*((21 - g)//11))
+ j = (y + y//4 + i + 2 - c + c//4) % 7
+
+ # p can be from -6 to 56 corresponding to dates 22 March to 23 May
+ # (later dates apply to method 2, although 23 May never actually occurs)
+ p = i - j + e
+ d = 1 + (p + 27 + (p + 6)//40) % 31
+ m = 3 + (p + 26)//30
+ return datetime.date(int(y), int(m), int(d))
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__init__.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__init__.py
new file mode 100644
index 0000000000..d174b0e4dc
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__init__.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+from ._parser import parse, parser, parserinfo, ParserError
+from ._parser import DEFAULTPARSER, DEFAULTTZPARSER
+from ._parser import UnknownTimezoneWarning
+
+from ._parser import __doc__
+
+from .isoparser import isoparser, isoparse
+
+__all__ = ['parse', 'parser', 'parserinfo',
+ 'isoparse', 'isoparser',
+ 'ParserError',
+ 'UnknownTimezoneWarning']
+
+
+###
+# Deprecate portions of the private interface so that downstream code that
+# is improperly relying on it is given *some* notice.
+
+
+def __deprecated_private_func(f):
+ from functools import wraps
+ import warnings
+
+ msg = ('{name} is a private function and may break without warning, '
+ 'it will be moved and or renamed in future versions.')
+ msg = msg.format(name=f.__name__)
+
+ @wraps(f)
+ def deprecated_func(*args, **kwargs):
+ warnings.warn(msg, DeprecationWarning)
+ return f(*args, **kwargs)
+
+ return deprecated_func
+
+def __deprecate_private_class(c):
+ import warnings
+
+ msg = ('{name} is a private class and may break without warning, '
+ 'it will be moved and or renamed in future versions.')
+ msg = msg.format(name=c.__name__)
+
+ class private_class(c):
+ __doc__ = c.__doc__
+
+ def __init__(self, *args, **kwargs):
+ warnings.warn(msg, DeprecationWarning)
+ super(private_class, self).__init__(*args, **kwargs)
+
+ private_class.__name__ = c.__name__
+
+ return private_class
+
+
+from ._parser import _timelex, _resultbase
+from ._parser import _tzparser, _parsetz
+
+_timelex = __deprecate_private_class(_timelex)
+_tzparser = __deprecate_private_class(_tzparser)
+_resultbase = __deprecate_private_class(_resultbase)
+_parsetz = __deprecated_private_func(_parsetz)
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/__init__.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000..319096cfe5
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/__init__.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/_parser.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/_parser.cpython-311.pyc
new file mode 100644
index 0000000000..4db881f505
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/_parser.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/isoparser.cpython-311.pyc b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/isoparser.cpython-311.pyc
new file mode 100644
index 0000000000..85002db397
Binary files /dev/null and b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/__pycache__/isoparser.cpython-311.pyc differ
diff --git a/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/_parser.py b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/_parser.py
new file mode 100644
index 0000000000..37d1663b2f
--- /dev/null
+++ b/eventbridge-lambda-fsx-openzfs-periodic-replication/dependencies/python/dateutil/parser/_parser.py
@@ -0,0 +1,1613 @@
+# -*- coding: utf-8 -*-
+"""
+This module offers a generic date/time string parser which is able to parse
+most known formats to represent a date and/or time.
+
+This module attempts to be forgiving with regards to unlikely input formats,
+returning a datetime object even for dates which are ambiguous. If an element
+of a date/time stamp is omitted, the following rules are applied:
+
+- If AM or PM is left unspecified, a 24-hour clock is assumed, however, an hour
+ on a 12-hour clock (``0 <= hour <= 12``) *must* be specified if AM or PM is
+ specified.
+- If a time zone is omitted, a timezone-naive datetime is returned.
+
+If any other elements are missing, they are taken from the
+:class:`datetime.datetime` object passed to the parameter ``default``. If this
+results in a day number exceeding the valid number of days per month, the
+value falls back to the end of the month.
+
+Additional resources about date/time string formats can be found below:
+
+- `A summary of the international standard date and time notation
+ `_
+- `W3C Date and Time Formats