From c60b59f819ccef685412230ed50398b96d1ce7c4 Mon Sep 17 00:00:00 2001 From: AsyncAws Bot Date: Thu, 20 Nov 2025 06:35:13 +0000 Subject: [PATCH] update generated code --- manifest.json | 2 +- psalm.baseline.xml | 8 ++ .../RequestLimitExceededException.php | 2 +- src/Service/Lambda/CHANGELOG.md | 1 + .../Lambda/src/Enum/TenantIsolationMode.php | 15 ++++ .../Lambda/src/Input/InvocationRequest.php | 25 +++++++ src/Service/Lambda/src/LambdaClient.php | 1 + .../src/Result/FunctionConfiguration.php | 24 ++++++ .../src/Result/ListFunctionsResponse.php | 9 +++ .../Result/ListVersionsByFunctionResponse.php | 9 +++ .../src/ValueObject/FunctionConfiguration.php | 16 ++++ .../Lambda/src/ValueObject/TenancyConfig.php | 58 +++++++++++++++ src/Service/S3/CHANGELOG.md | 1 + src/Service/S3/src/Enum/EncryptionType.php | 17 +++++ .../src/Result/GetBucketEncryptionOutput.php | 23 ++++++ src/Service/S3/src/S3Client.php | 15 +++- .../ValueObject/BlockedEncryptionTypes.php | 73 +++++++++++++++++++ .../ValueObject/CreateBucketConfiguration.php | 6 +- .../ValueObject/ServerSideEncryptionRule.php | 26 +++++++ src/Service/SecretsManager/CHANGELOG.md | 1 + .../src/Input/CreateSecretRequest.php | 28 +++++++ .../src/Input/PutSecretValueRequest.php | 10 ++- .../src/Input/UpdateSecretRequest.php | 28 +++++++ .../src/Result/ListSecretsResponse.php | 25 +++++++ .../src/SecretsManagerClient.php | 16 ++-- .../ExternalSecretRotationMetadataItem.php | 59 +++++++++++++++ .../src/ValueObject/SecretListEntry.php | 58 +++++++++++++++ 27 files changed, 537 insertions(+), 19 deletions(-) create mode 100644 src/Service/Lambda/src/Enum/TenantIsolationMode.php create mode 100644 src/Service/Lambda/src/ValueObject/TenancyConfig.php create mode 100644 src/Service/S3/src/Enum/EncryptionType.php create mode 100644 src/Service/S3/src/ValueObject/BlockedEncryptionTypes.php create mode 100644 src/Service/SecretsManager/src/ValueObject/ExternalSecretRotationMetadataItem.php diff --git a/manifest.json b/manifest.json index 46f2b5683..6efa411d6 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "variables": { - "${LATEST}": "3.360.1" + "${LATEST}": "3.362.0" }, "endpoints": "https://raw.githubusercontent.com/aws/aws-sdk-php/${LATEST}/src/data/endpoints.json", "services": { diff --git a/psalm.baseline.xml b/psalm.baseline.xml index 82ff1a77f..16d69a6f0 100644 --- a/psalm.baseline.xml +++ b/psalm.baseline.xml @@ -262,6 +262,14 @@ ]]> + + + + + + ]]> + + diff --git a/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php b/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php index 1c7fb9e84..f189f1657 100644 --- a/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php +++ b/src/Service/DynamoDb/src/Exception/RequestLimitExceededException.php @@ -9,7 +9,7 @@ /** * Throughput exceeds the current throughput quota for your account. For detailed information about why the request was * throttled and the ARN of the impacted resource, find the ThrottlingReason [^1] field in the returned exception. - * Contact Amazon Web ServicesSupport [^2] to request a quota increase. + * Contact Amazon Web Services Support [^2] to request a quota increase. * * [^1]: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ThrottlingReason.html * [^2]: https://aws.amazon.com/support diff --git a/src/Service/Lambda/CHANGELOG.md b/src/Service/Lambda/CHANGELOG.md index 4549b4bb7..c5a2fbb9a 100644 --- a/src/Service/Lambda/CHANGELOG.md +++ b/src/Service/Lambda/CHANGELOG.md @@ -8,6 +8,7 @@ - AWS api-change: Added `us-isob-west-1` region - AWS api-change: Added SerializedRequestEntityTooLargeException to Lambda Invoke API - AWS api-change: Add Python3.14 (python3.14) and Java 25 (java25) support to AWS Lambda +- AWS api-change: Added support for creating and invoking Tenant Isolated functions in AWS Lambda APIs. ### Dependency bumped diff --git a/src/Service/Lambda/src/Enum/TenantIsolationMode.php b/src/Service/Lambda/src/Enum/TenantIsolationMode.php new file mode 100644 index 000000000..a18406092 --- /dev/null +++ b/src/Service/Lambda/src/Enum/TenantIsolationMode.php @@ -0,0 +1,15 @@ + true, + ][$value]); + } +} diff --git a/src/Service/Lambda/src/Input/InvocationRequest.php b/src/Service/Lambda/src/Input/InvocationRequest.php index 2a9d769d5..01782ed85 100644 --- a/src/Service/Lambda/src/Input/InvocationRequest.php +++ b/src/Service/Lambda/src/Input/InvocationRequest.php @@ -75,6 +75,13 @@ final class InvocationRequest extends Input */ private $qualifier; + /** + * The identifier of the tenant in a multi-tenant Lambda function. + * + * @var string|null + */ + private $tenantId; + /** * @param array{ * FunctionName?: string, @@ -83,6 +90,7 @@ final class InvocationRequest extends Input * ClientContext?: string|null, * Payload?: string|null, * Qualifier?: string|null, + * TenantId?: string|null, * '@region'?: string|null, * } $input */ @@ -94,6 +102,7 @@ public function __construct(array $input = []) $this->clientContext = $input['ClientContext'] ?? null; $this->payload = $input['Payload'] ?? null; $this->qualifier = $input['Qualifier'] ?? null; + $this->tenantId = $input['TenantId'] ?? null; parent::__construct($input); } @@ -105,6 +114,7 @@ public function __construct(array $input = []) * ClientContext?: string|null, * Payload?: string|null, * Qualifier?: string|null, + * TenantId?: string|null, * '@region'?: string|null, * }|InvocationRequest $input */ @@ -149,6 +159,11 @@ public function getQualifier(): ?string return $this->qualifier; } + public function getTenantId(): ?string + { + return $this->tenantId; + } + /** * @internal */ @@ -174,6 +189,9 @@ public function request(): Request if (null !== $this->clientContext) { $headers['X-Amz-Client-Context'] = $this->clientContext; } + if (null !== $this->tenantId) { + $headers['X-Amz-Tenant-Id'] = $this->tenantId; + } // Prepare query $query = []; @@ -243,4 +261,11 @@ public function setQualifier(?string $value): self return $this; } + + public function setTenantId(?string $value): self + { + $this->tenantId = $value; + + return $this; + } } diff --git a/src/Service/Lambda/src/LambdaClient.php b/src/Service/Lambda/src/LambdaClient.php index e6f3574a6..cfcf1e0f4 100644 --- a/src/Service/Lambda/src/LambdaClient.php +++ b/src/Service/Lambda/src/LambdaClient.php @@ -254,6 +254,7 @@ public function getFunctionConfiguration($input): FunctionConfiguration * ClientContext?: string|null, * Payload?: string|null, * Qualifier?: string|null, + * TenantId?: string|null, * '@region'?: string|null, * }|InvocationRequest $input * diff --git a/src/Service/Lambda/src/Result/FunctionConfiguration.php b/src/Service/Lambda/src/Result/FunctionConfiguration.php index 164b5251e..f540962ab 100644 --- a/src/Service/Lambda/src/Result/FunctionConfiguration.php +++ b/src/Service/Lambda/src/Result/FunctionConfiguration.php @@ -24,6 +24,7 @@ use AsyncAws\Lambda\ValueObject\RuntimeVersionConfig; use AsyncAws\Lambda\ValueObject\RuntimeVersionError; use AsyncAws\Lambda\ValueObject\SnapStartResponse; +use AsyncAws\Lambda\ValueObject\TenancyConfig; use AsyncAws\Lambda\ValueObject\TracingConfigResponse; use AsyncAws\Lambda\ValueObject\VpcConfigResponse; @@ -329,6 +330,14 @@ class FunctionConfiguration extends Result */ private $loggingConfig; + /** + * The function's tenant isolation configuration settings. Determines whether the Lambda function runs on a shared or + * dedicated infrastructure per unique tenant. + * + * @var TenancyConfig|null + */ + private $tenancyConfig; + /** * @return list */ @@ -580,6 +589,13 @@ public function getStateReasonCode(): ?string return $this->stateReasonCode; } + public function getTenancyConfig(): ?TenancyConfig + { + $this->initialize(); + + return $this->tenancyConfig; + } + public function getTimeout(): ?int { $this->initialize(); @@ -648,6 +664,7 @@ protected function populateResult(Response $response): void $this->snapStart = empty($data['SnapStart']) ? null : $this->populateResultSnapStartResponse($data['SnapStart']); $this->runtimeVersionConfig = empty($data['RuntimeVersionConfig']) ? null : $this->populateResultRuntimeVersionConfig($data['RuntimeVersionConfig']); $this->loggingConfig = empty($data['LoggingConfig']) ? null : $this->populateResultLoggingConfig($data['LoggingConfig']); + $this->tenancyConfig = empty($data['TenancyConfig']) ? null : $this->populateResultTenancyConfig($data['TenancyConfig']); } /** @@ -860,6 +877,13 @@ private function populateResultSubnetIds(array $json): array return $items; } + private function populateResultTenancyConfig(array $json): TenancyConfig + { + return new TenancyConfig([ + 'TenantIsolationMode' => (string) $json['TenantIsolationMode'], + ]); + } + private function populateResultTracingConfigResponse(array $json): TracingConfigResponse { return new TracingConfigResponse([ diff --git a/src/Service/Lambda/src/Result/ListFunctionsResponse.php b/src/Service/Lambda/src/Result/ListFunctionsResponse.php index b9d356704..e44965363 100644 --- a/src/Service/Lambda/src/Result/ListFunctionsResponse.php +++ b/src/Service/Lambda/src/Result/ListFunctionsResponse.php @@ -22,6 +22,7 @@ use AsyncAws\Lambda\ValueObject\RuntimeVersionConfig; use AsyncAws\Lambda\ValueObject\RuntimeVersionError; use AsyncAws\Lambda\ValueObject\SnapStartResponse; +use AsyncAws\Lambda\ValueObject\TenancyConfig; use AsyncAws\Lambda\ValueObject\TracingConfigResponse; use AsyncAws\Lambda\ValueObject\VpcConfigResponse; @@ -234,6 +235,7 @@ private function populateResultFunctionConfiguration(array $json): FunctionConfi 'SnapStart' => empty($json['SnapStart']) ? null : $this->populateResultSnapStartResponse($json['SnapStart']), 'RuntimeVersionConfig' => empty($json['RuntimeVersionConfig']) ? null : $this->populateResultRuntimeVersionConfig($json['RuntimeVersionConfig']), 'LoggingConfig' => empty($json['LoggingConfig']) ? null : $this->populateResultLoggingConfig($json['LoggingConfig']), + 'TenancyConfig' => empty($json['TenancyConfig']) ? null : $this->populateResultTenancyConfig($json['TenancyConfig']), ]); } @@ -380,6 +382,13 @@ private function populateResultSubnetIds(array $json): array return $items; } + private function populateResultTenancyConfig(array $json): TenancyConfig + { + return new TenancyConfig([ + 'TenantIsolationMode' => (string) $json['TenantIsolationMode'], + ]); + } + private function populateResultTracingConfigResponse(array $json): TracingConfigResponse { return new TracingConfigResponse([ diff --git a/src/Service/Lambda/src/Result/ListVersionsByFunctionResponse.php b/src/Service/Lambda/src/Result/ListVersionsByFunctionResponse.php index 8fc119f6d..5f5d7ea4e 100644 --- a/src/Service/Lambda/src/Result/ListVersionsByFunctionResponse.php +++ b/src/Service/Lambda/src/Result/ListVersionsByFunctionResponse.php @@ -22,6 +22,7 @@ use AsyncAws\Lambda\ValueObject\RuntimeVersionConfig; use AsyncAws\Lambda\ValueObject\RuntimeVersionError; use AsyncAws\Lambda\ValueObject\SnapStartResponse; +use AsyncAws\Lambda\ValueObject\TenancyConfig; use AsyncAws\Lambda\ValueObject\TracingConfigResponse; use AsyncAws\Lambda\ValueObject\VpcConfigResponse; @@ -232,6 +233,7 @@ private function populateResultFunctionConfiguration(array $json): FunctionConfi 'SnapStart' => empty($json['SnapStart']) ? null : $this->populateResultSnapStartResponse($json['SnapStart']), 'RuntimeVersionConfig' => empty($json['RuntimeVersionConfig']) ? null : $this->populateResultRuntimeVersionConfig($json['RuntimeVersionConfig']), 'LoggingConfig' => empty($json['LoggingConfig']) ? null : $this->populateResultLoggingConfig($json['LoggingConfig']), + 'TenancyConfig' => empty($json['TenancyConfig']) ? null : $this->populateResultTenancyConfig($json['TenancyConfig']), ]); } @@ -378,6 +380,13 @@ private function populateResultSubnetIds(array $json): array return $items; } + private function populateResultTenancyConfig(array $json): TenancyConfig + { + return new TenancyConfig([ + 'TenantIsolationMode' => (string) $json['TenantIsolationMode'], + ]); + } + private function populateResultTracingConfigResponse(array $json): TracingConfigResponse { return new TracingConfigResponse([ diff --git a/src/Service/Lambda/src/ValueObject/FunctionConfiguration.php b/src/Service/Lambda/src/ValueObject/FunctionConfiguration.php index a3e0b3b86..be07b74a5 100644 --- a/src/Service/Lambda/src/ValueObject/FunctionConfiguration.php +++ b/src/Service/Lambda/src/ValueObject/FunctionConfiguration.php @@ -312,6 +312,14 @@ final class FunctionConfiguration */ private $loggingConfig; + /** + * The function's tenant isolation configuration settings. Determines whether the Lambda function runs on a shared or + * dedicated infrastructure per unique tenant. + * + * @var TenancyConfig|null + */ + private $tenancyConfig; + /** * @param array{ * FunctionName?: string|null, @@ -350,6 +358,7 @@ final class FunctionConfiguration * SnapStart?: SnapStartResponse|array|null, * RuntimeVersionConfig?: RuntimeVersionConfig|array|null, * LoggingConfig?: LoggingConfig|array|null, + * TenancyConfig?: TenancyConfig|array|null, * } $input */ public function __construct(array $input) @@ -390,6 +399,7 @@ public function __construct(array $input) $this->snapStart = isset($input['SnapStart']) ? SnapStartResponse::create($input['SnapStart']) : null; $this->runtimeVersionConfig = isset($input['RuntimeVersionConfig']) ? RuntimeVersionConfig::create($input['RuntimeVersionConfig']) : null; $this->loggingConfig = isset($input['LoggingConfig']) ? LoggingConfig::create($input['LoggingConfig']) : null; + $this->tenancyConfig = isset($input['TenancyConfig']) ? TenancyConfig::create($input['TenancyConfig']) : null; } /** @@ -430,6 +440,7 @@ public function __construct(array $input) * SnapStart?: SnapStartResponse|array|null, * RuntimeVersionConfig?: RuntimeVersionConfig|array|null, * LoggingConfig?: LoggingConfig|array|null, + * TenancyConfig?: TenancyConfig|array|null, * }|FunctionConfiguration $input */ public static function create($input): self @@ -624,6 +635,11 @@ public function getStateReasonCode(): ?string return $this->stateReasonCode; } + public function getTenancyConfig(): ?TenancyConfig + { + return $this->tenancyConfig; + } + public function getTimeout(): ?int { return $this->timeout; diff --git a/src/Service/Lambda/src/ValueObject/TenancyConfig.php b/src/Service/Lambda/src/ValueObject/TenancyConfig.php new file mode 100644 index 000000000..3c3802dd0 --- /dev/null +++ b/src/Service/Lambda/src/ValueObject/TenancyConfig.php @@ -0,0 +1,58 @@ +tenantIsolationMode = $input['TenantIsolationMode'] ?? $this->throwException(new InvalidArgument('Missing required field "TenantIsolationMode".')); + } + + /** + * @param array{ + * TenantIsolationMode: TenantIsolationMode::*, + * }|TenancyConfig $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return TenantIsolationMode::* + */ + public function getTenantIsolationMode(): string + { + return $this->tenantIsolationMode; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/src/Service/S3/CHANGELOG.md b/src/Service/S3/CHANGELOG.md index 7cb239c07..78f96d0a4 100644 --- a/src/Service/S3/CHANGELOG.md +++ b/src/Service/S3/CHANGELOG.md @@ -11,6 +11,7 @@ - AWS api-change: Added `us-isob-west-1` region - Added `S3Client::putPublicAccessBlock()` method - AWS api-change: Amazon Simple Storage Service / Features: Add conditional writes in CopyObject on destination key to prevent unintended object modifications. +- AWS api-change: Adds support for blocking SSE-C writes to general purpose buckets. ### Dependency bumped diff --git a/src/Service/S3/src/Enum/EncryptionType.php b/src/Service/S3/src/Enum/EncryptionType.php new file mode 100644 index 000000000..216686ba4 --- /dev/null +++ b/src/Service/S3/src/Enum/EncryptionType.php @@ -0,0 +1,17 @@ + true, + self::SSE_C => true, + ][$value]); + } +} diff --git a/src/Service/S3/src/Result/GetBucketEncryptionOutput.php b/src/Service/S3/src/Result/GetBucketEncryptionOutput.php index 8265266f0..74eaf8166 100644 --- a/src/Service/S3/src/Result/GetBucketEncryptionOutput.php +++ b/src/Service/S3/src/Result/GetBucketEncryptionOutput.php @@ -4,6 +4,8 @@ use AsyncAws\Core\Response; use AsyncAws\Core\Result; +use AsyncAws\S3\Enum\EncryptionType; +use AsyncAws\S3\ValueObject\BlockedEncryptionTypes; use AsyncAws\S3\ValueObject\ServerSideEncryptionByDefault; use AsyncAws\S3\ValueObject\ServerSideEncryptionConfiguration; use AsyncAws\S3\ValueObject\ServerSideEncryptionRule; @@ -28,6 +30,26 @@ protected function populateResult(Response $response): void $this->serverSideEncryptionConfiguration = $this->populateResultServerSideEncryptionConfiguration($data); } + private function populateResultBlockedEncryptionTypes(\SimpleXMLElement $xml): BlockedEncryptionTypes + { + return new BlockedEncryptionTypes([ + 'EncryptionType' => (0 === ($v = $xml->EncryptionType)->count()) ? null : $this->populateResultEncryptionTypeList($v), + ]); + } + + /** + * @return list + */ + private function populateResultEncryptionTypeList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = (string) $item; + } + + return $items; + } + private function populateResultServerSideEncryptionByDefault(\SimpleXMLElement $xml): ServerSideEncryptionByDefault { return new ServerSideEncryptionByDefault([ @@ -48,6 +70,7 @@ private function populateResultServerSideEncryptionRule(\SimpleXMLElement $xml): return new ServerSideEncryptionRule([ 'ApplyServerSideEncryptionByDefault' => 0 === $xml->ApplyServerSideEncryptionByDefault->count() ? null : $this->populateResultServerSideEncryptionByDefault($xml->ApplyServerSideEncryptionByDefault), 'BucketKeyEnabled' => (null !== $v = $xml->BucketKeyEnabled[0]) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + 'BlockedEncryptionTypes' => 0 === $xml->BlockedEncryptionTypes->count() ? null : $this->populateResultBlockedEncryptionTypes($xml->BlockedEncryptionTypes), ]); } diff --git a/src/Service/S3/src/S3Client.php b/src/Service/S3/src/S3Client.php index b6503d527..9dc00f569 100644 --- a/src/Service/S3/src/S3Client.php +++ b/src/Service/S3/src/S3Client.php @@ -1107,6 +1107,10 @@ public function deleteBucketCors($input): Result * - **`s3:DeleteObjectVersion`** - To delete a specific version of an object from a versioning-enabled bucket, you * must have the `s3:DeleteObjectVersion` permission. * + * > If the `s3:DeleteObject` or `s3:DeleteObjectVersion` permissions are explicitly denied in your bucket policy, + * > attempts to delete any unversioned objects result in a `403 Access Denied` error. + * + * * - **Directory bucket permissions** - To grant access to this API operation on a directory bucket, we recommend that * you use the `CreateSession` [^8] API operation for session-based authorization. Specifically, you grant the * `s3express:CreateSession` permission to the directory bucket in a bucket policy or an IAM identity-based policy. @@ -1252,6 +1256,10 @@ public function deleteObjectTagging($input): DeleteObjectTaggingOutput * - **`s3:DeleteObjectVersion`** - To delete a specific version of an object from a versioning-enabled bucket, you * must specify the `s3:DeleteObjectVersion` permission. * + * > If the `s3:DeleteObject` or `s3:DeleteObjectVersion` permissions are explicitly denied in your bucket policy, + * > attempts to delete any unversioned objects result in a `403 Access Denied` error. + * + * * - **Directory bucket permissions** - To grant access to this API operation on a directory bucket, we recommend that * you use the `CreateSession` [^4] API operation for session-based authorization. Specifically, you grant the * `s3express:CreateSession` permission to the directory bucket in a bucket policy or an IAM identity-based policy. @@ -1368,7 +1376,8 @@ public function getBucketCors($input): GetBucketCorsOutput /** * Returns the default encryption configuration for an Amazon S3 bucket. By default, all buckets have a default - * encryption configuration that uses server-side encryption with Amazon S3 managed keys (SSE-S3). + * encryption configuration that uses server-side encryption with Amazon S3 managed keys (SSE-S3). This operation also + * returns the `BucketKeyEnabled` and `BlockedEncryptionTypes` statuses. * * > - **General purpose buckets** - For information about the bucket default encryption feature, see Amazon S3 Bucket * > Default Encryption [^1] in the *Amazon S3 User Guide*. @@ -1402,7 +1411,7 @@ public function getBucketCors($input): GetBucketCorsOutput * ! You must URL encode any signed header values that contain spaces. For example, if your header value is `my * ! file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`. * - * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-bucket-encryption.html * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html @@ -2520,7 +2529,7 @@ public function putBucketNotificationConfiguration($input): Result /** * > This operation is not supported for directory buckets. * - * Sets the tags for a bucket. + * Sets the tags for a general purpose bucket. * * Use tags to organize your Amazon Web Services bill to reflect your own cost structure. To do this, sign up to get * your Amazon Web Services account bill with tag key values included. Then, to see the cost of combined resources, diff --git a/src/Service/S3/src/ValueObject/BlockedEncryptionTypes.php b/src/Service/S3/src/ValueObject/BlockedEncryptionTypes.php new file mode 100644 index 000000000..f5817d2f9 --- /dev/null +++ b/src/Service/S3/src/ValueObject/BlockedEncryptionTypes.php @@ -0,0 +1,73 @@ + Currently, this parameter only supports blocking or unblocking server side encryption with customer-provided keys + * > (SSE-C). For more information about SSE-C, see Using server-side encryption with customer-provided keys (SSE-C) + * > [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html + * + * @var list|null + */ + private $encryptionType; + + /** + * @param array{ + * EncryptionType?: array|null, + * } $input + */ + public function __construct(array $input) + { + $this->encryptionType = $input['EncryptionType'] ?? null; + } + + /** + * @param array{ + * EncryptionType?: array|null, + * }|BlockedEncryptionTypes $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEncryptionType(): array + { + return $this->encryptionType ?? []; + } +} diff --git a/src/Service/S3/src/ValueObject/CreateBucketConfiguration.php b/src/Service/S3/src/ValueObject/CreateBucketConfiguration.php index 3b937d6d4..46391c9f2 100644 --- a/src/Service/S3/src/ValueObject/CreateBucketConfiguration.php +++ b/src/Service/S3/src/ValueObject/CreateBucketConfiguration.php @@ -56,10 +56,10 @@ final class CreateBucketConfiguration * An array of tags that you can apply to the bucket that you're creating. Tags are key-value pairs of metadata used to * categorize and organize your buckets, track costs, and control access. * - * > - This parameter is only supported for S3 directory buckets. For more information, see Using tags with directory - * > buckets [^1]. - * > - You must have the `s3express:TagResource` permission to create a directory bucket with tags. + * > This parameter is only supported for S3 directory buckets. For more information, see Using tags with directory + * > buckets [^1]. * > + * > You must have the `s3express:TagResource` permission to create a directory bucket with tags. * * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-tagging.html * diff --git a/src/Service/S3/src/ValueObject/ServerSideEncryptionRule.php b/src/Service/S3/src/ValueObject/ServerSideEncryptionRule.php index ed8c597c9..332828481 100644 --- a/src/Service/S3/src/ValueObject/ServerSideEncryptionRule.php +++ b/src/Service/S3/src/ValueObject/ServerSideEncryptionRule.php @@ -50,22 +50,43 @@ final class ServerSideEncryptionRule */ private $bucketKeyEnabled; + /** + * A bucket-level setting for Amazon S3 general purpose buckets used to prevent the upload of new objects encrypted with + * the specified server-side encryption type. For example, blocking an encryption type will block `PutObject`, + * `CopyObject`, `PostObject`, multipart upload, and replication requests to the bucket for objects with the specified + * encryption type. However, you can continue to read and list any pre-existing objects already encrypted with the + * specified encryption type. For more information, see Blocking an encryption type for a general purpose bucket [^1]. + * + * > Currently, this parameter only supports blocking or unblocking Server Side Encryption with Customer Provided Keys + * > (SSE-C). For more information about SSE-C, see Using server-side encryption with customer-provided keys (SSE-C) + * > [^2]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/userguide/block-encryption-type.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html + * + * @var BlockedEncryptionTypes|null + */ + private $blockedEncryptionTypes; + /** * @param array{ * ApplyServerSideEncryptionByDefault?: ServerSideEncryptionByDefault|array|null, * BucketKeyEnabled?: bool|null, + * BlockedEncryptionTypes?: BlockedEncryptionTypes|array|null, * } $input */ public function __construct(array $input) { $this->applyServerSideEncryptionByDefault = isset($input['ApplyServerSideEncryptionByDefault']) ? ServerSideEncryptionByDefault::create($input['ApplyServerSideEncryptionByDefault']) : null; $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->blockedEncryptionTypes = isset($input['BlockedEncryptionTypes']) ? BlockedEncryptionTypes::create($input['BlockedEncryptionTypes']) : null; } /** * @param array{ * ApplyServerSideEncryptionByDefault?: ServerSideEncryptionByDefault|array|null, * BucketKeyEnabled?: bool|null, + * BlockedEncryptionTypes?: BlockedEncryptionTypes|array|null, * }|ServerSideEncryptionRule $input */ public static function create($input): self @@ -78,6 +99,11 @@ public function getApplyServerSideEncryptionByDefault(): ?ServerSideEncryptionBy return $this->applyServerSideEncryptionByDefault; } + public function getBlockedEncryptionTypes(): ?BlockedEncryptionTypes + { + return $this->blockedEncryptionTypes; + } + public function getBucketKeyEnabled(): ?bool { return $this->bucketKeyEnabled; diff --git a/src/Service/SecretsManager/CHANGELOG.md b/src/Service/SecretsManager/CHANGELOG.md index b685bd3e7..dcd4bfe69 100644 --- a/src/Service/SecretsManager/CHANGELOG.md +++ b/src/Service/SecretsManager/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - AWS api-change: Added `us-isob-west-1` region +- AWS api-change: Adds support to create, update, retrieve, rotate, and delete managed external secrets. ### Dependency bumped diff --git a/src/Service/SecretsManager/src/Input/CreateSecretRequest.php b/src/Service/SecretsManager/src/Input/CreateSecretRequest.php index e98ea3094..549689ff0 100644 --- a/src/Service/SecretsManager/src/Input/CreateSecretRequest.php +++ b/src/Service/SecretsManager/src/Input/CreateSecretRequest.php @@ -160,6 +160,16 @@ final class CreateSecretRequest extends Input */ private $forceOverwriteReplicaSecret; + /** + * The exact string that identifies the partner that holds the external secret. For more information, see Using Secrets + * Manager managed external secrets [^1]. + * + * [^1]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/managed-external-secrets.html + * + * @var string|null + */ + private $type; + /** * @param array{ * Name?: string, @@ -171,6 +181,7 @@ final class CreateSecretRequest extends Input * Tags?: array|null, * AddReplicaRegions?: array|null, * ForceOverwriteReplicaSecret?: bool|null, + * Type?: string|null, * '@region'?: string|null, * } $input */ @@ -185,6 +196,7 @@ public function __construct(array $input = []) $this->tags = isset($input['Tags']) ? array_map([Tag::class, 'create'], $input['Tags']) : null; $this->addReplicaRegions = isset($input['AddReplicaRegions']) ? array_map([ReplicaRegionType::class, 'create'], $input['AddReplicaRegions']) : null; $this->forceOverwriteReplicaSecret = $input['ForceOverwriteReplicaSecret'] ?? null; + $this->type = $input['Type'] ?? null; parent::__construct($input); } @@ -199,6 +211,7 @@ public function __construct(array $input = []) * Tags?: array|null, * AddReplicaRegions?: array|null, * ForceOverwriteReplicaSecret?: bool|null, + * Type?: string|null, * '@region'?: string|null, * }|CreateSecretRequest $input */ @@ -258,6 +271,11 @@ public function getTags(): array return $this->tags ?? []; } + public function getType(): ?string + { + return $this->type; + } + /** * @internal */ @@ -353,6 +371,13 @@ public function setTags(array $value): self return $this; } + public function setType(?string $value): self + { + $this->type = $value; + + return $this; + } + private function requestBody(): array { $payload = []; @@ -395,6 +420,9 @@ private function requestBody(): array if (null !== $v = $this->forceOverwriteReplicaSecret) { $payload['ForceOverwriteReplicaSecret'] = (bool) $v; } + if (null !== $v = $this->type) { + $payload['Type'] = $v; + } return $payload; } diff --git a/src/Service/SecretsManager/src/Input/PutSecretValueRequest.php b/src/Service/SecretsManager/src/Input/PutSecretValueRequest.php index fdceeb397..f0bdb9652 100644 --- a/src/Service/SecretsManager/src/Input/PutSecretValueRequest.php +++ b/src/Service/SecretsManager/src/Input/PutSecretValueRequest.php @@ -101,15 +101,17 @@ final class PutSecretValueRequest extends Input private $versionStages; /** - * A unique identifier that indicates the source of the request. For cross-account rotation (when you rotate a secret in - * one account by using a Lambda rotation function in another account) and the Lambda rotation function assumes an IAM - * role to call Secrets Manager, Secrets Manager validates the identity with the rotation token. For more information, - * see How rotation works [^1]. + * A unique identifier that indicates the source of the request. Required for secret rotations using an IAM assumed role + * or cross-account rotation, in which you rotate a secret in one account by using a Lambda rotation function in another + * account. In both cases, the rotation function assumes an IAM role to call Secrets Manager, and then Secrets Manager + * validates the identity using the token. For more information, see How rotation works [^1] and Rotation by Lambda + * functions [^2]. * * Sensitive: This field contains sensitive information, so the service does not include it in CloudTrail log entries. * If you create your own log entries, you must also avoid logging the information in this field. * * [^1]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html + * [^2]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotate-secrets_lambda * * @var string|null */ diff --git a/src/Service/SecretsManager/src/Input/UpdateSecretRequest.php b/src/Service/SecretsManager/src/Input/UpdateSecretRequest.php index 6fc655791..376ae4deb 100644 --- a/src/Service/SecretsManager/src/Input/UpdateSecretRequest.php +++ b/src/Service/SecretsManager/src/Input/UpdateSecretRequest.php @@ -105,6 +105,16 @@ final class UpdateSecretRequest extends Input */ private $secretString; + /** + * The exact string that identifies the third-party partner that holds the external secret. For more information, see + * Managed external secret partners [^1]. + * + * [^1]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/mes-partners.html + * + * @var string|null + */ + private $type; + /** * @param array{ * SecretId?: string, @@ -113,6 +123,7 @@ final class UpdateSecretRequest extends Input * KmsKeyId?: string|null, * SecretBinary?: string|null, * SecretString?: string|null, + * Type?: string|null, * '@region'?: string|null, * } $input */ @@ -124,6 +135,7 @@ public function __construct(array $input = []) $this->kmsKeyId = $input['KmsKeyId'] ?? null; $this->secretBinary = $input['SecretBinary'] ?? null; $this->secretString = $input['SecretString'] ?? null; + $this->type = $input['Type'] ?? null; parent::__construct($input); } @@ -135,6 +147,7 @@ public function __construct(array $input = []) * KmsKeyId?: string|null, * SecretBinary?: string|null, * SecretString?: string|null, + * Type?: string|null, * '@region'?: string|null, * }|UpdateSecretRequest $input */ @@ -173,6 +186,11 @@ public function getSecretString(): ?string return $this->secretString; } + public function getType(): ?string + { + return $this->type; + } + /** * @internal */ @@ -241,6 +259,13 @@ public function setSecretString(?string $value): self return $this; } + public function setType(?string $value): self + { + $this->type = $value; + + return $this; + } + private function requestBody(): array { $payload = []; @@ -264,6 +289,9 @@ private function requestBody(): array if (null !== $v = $this->secretString) { $payload['SecretString'] = $v; } + if (null !== $v = $this->type) { + $payload['Type'] = $v; + } return $payload; } diff --git a/src/Service/SecretsManager/src/Result/ListSecretsResponse.php b/src/Service/SecretsManager/src/Result/ListSecretsResponse.php index bd58b58bc..82ef42252 100644 --- a/src/Service/SecretsManager/src/Result/ListSecretsResponse.php +++ b/src/Service/SecretsManager/src/Result/ListSecretsResponse.php @@ -7,6 +7,7 @@ use AsyncAws\Core\Result; use AsyncAws\SecretsManager\Input\ListSecretsRequest; use AsyncAws\SecretsManager\SecretsManagerClient; +use AsyncAws\SecretsManager\ValueObject\ExternalSecretRotationMetadataItem; use AsyncAws\SecretsManager\ValueObject\RotationRulesType; use AsyncAws\SecretsManager\ValueObject\SecretListEntry; use AsyncAws\SecretsManager\ValueObject\Tag; @@ -101,6 +102,27 @@ protected function populateResult(Response $response): void $this->nextToken = isset($data['NextToken']) ? (string) $data['NextToken'] : null; } + private function populateResultExternalSecretRotationMetadataItem(array $json): ExternalSecretRotationMetadataItem + { + return new ExternalSecretRotationMetadataItem([ + 'Key' => isset($json['Key']) ? (string) $json['Key'] : null, + 'Value' => isset($json['Value']) ? (string) $json['Value'] : null, + ]); + } + + /** + * @return ExternalSecretRotationMetadataItem[] + */ + private function populateResultExternalSecretRotationMetadataType(array $json): array + { + $items = []; + foreach ($json as $item) { + $items[] = $this->populateResultExternalSecretRotationMetadataItem($item); + } + + return $items; + } + private function populateResultRotationRulesType(array $json): RotationRulesType { return new RotationRulesType([ @@ -115,11 +137,14 @@ private function populateResultSecretListEntry(array $json): SecretListEntry return new SecretListEntry([ 'ARN' => isset($json['ARN']) ? (string) $json['ARN'] : null, 'Name' => isset($json['Name']) ? (string) $json['Name'] : null, + 'Type' => isset($json['Type']) ? (string) $json['Type'] : null, 'Description' => isset($json['Description']) ? (string) $json['Description'] : null, 'KmsKeyId' => isset($json['KmsKeyId']) ? (string) $json['KmsKeyId'] : null, 'RotationEnabled' => isset($json['RotationEnabled']) ? filter_var($json['RotationEnabled'], \FILTER_VALIDATE_BOOLEAN) : null, 'RotationLambdaARN' => isset($json['RotationLambdaARN']) ? (string) $json['RotationLambdaARN'] : null, 'RotationRules' => empty($json['RotationRules']) ? null : $this->populateResultRotationRulesType($json['RotationRules']), + 'ExternalSecretRotationMetadata' => !isset($json['ExternalSecretRotationMetadata']) ? null : $this->populateResultExternalSecretRotationMetadataType($json['ExternalSecretRotationMetadata']), + 'ExternalSecretRotationRoleArn' => isset($json['ExternalSecretRotationRoleArn']) ? (string) $json['ExternalSecretRotationRoleArn'] : null, 'LastRotatedDate' => (isset($json['LastRotatedDate']) && ($d = \DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $json['LastRotatedDate'])))) ? $d : null, 'LastChangedDate' => (isset($json['LastChangedDate']) && ($d = \DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $json['LastChangedDate'])))) ? $d : null, 'LastAccessedDate' => (isset($json['LastAccessedDate']) && ($d = \DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $json['LastAccessedDate'])))) ? $d : null, diff --git a/src/Service/SecretsManager/src/SecretsManagerClient.php b/src/Service/SecretsManager/src/SecretsManagerClient.php index af1d3df7b..1aa1f031e 100644 --- a/src/Service/SecretsManager/src/SecretsManagerClient.php +++ b/src/Service/SecretsManager/src/SecretsManagerClient.php @@ -101,6 +101,7 @@ class SecretsManagerClient extends AbstractApi * Tags?: array|null, * AddReplicaRegions?: array|null, * ForceOverwriteReplicaSecret?: bool|null, + * Type?: string|null, * '@region'?: string|null, * }|CreateSecretRequest $input * @@ -314,14 +315,14 @@ public function listSecrets($input = []): ListSecretsResponse } /** - * Creates a new version with a new encrypted secret value and attaches it to the secret. The version can contain a new - * `SecretString` value or a new `SecretBinary` value. + * Creates a new version of your secret by creating a new encrypted value and attaching it to the secret. version can + * contain a new `SecretString` value or a new `SecretBinary` value. * - * We recommend you avoid calling `PutSecretValue` at a sustained rate of more than once every 10 minutes. When you - * update the secret value, Secrets Manager creates a new version of the secret. Secrets Manager removes outdated - * versions when there are more than 100, but it does not remove versions created less than 24 hours ago. If you call - * `PutSecretValue` more than once every 10 minutes, you create more versions than Secrets Manager removes, and you will - * reach the quota for secret versions. + * Do not call `PutSecretValue` at a sustained rate of more than once every 10 minutes. When you update the secret + * value, Secrets Manager creates a new version of the secret. Secrets Manager keeps 100 of the most recent versions, + * but it keeps *all* secret versions created in the last 24 hours. If you call `PutSecretValue` more than once every 10 + * minutes, you will create more versions than Secrets Manager removes, and you will reach the quota for secret + * versions. * * You can specify the staging labels to attach to the new version in `VersionStages`. If you don't include * `VersionStages`, then Secrets Manager automatically moves the staging label `AWSCURRENT` to this version. If this @@ -444,6 +445,7 @@ public function putSecretValue($input): PutSecretValueResponse * KmsKeyId?: string|null, * SecretBinary?: string|null, * SecretString?: string|null, + * Type?: string|null, * '@region'?: string|null, * }|UpdateSecretRequest $input * diff --git a/src/Service/SecretsManager/src/ValueObject/ExternalSecretRotationMetadataItem.php b/src/Service/SecretsManager/src/ValueObject/ExternalSecretRotationMetadataItem.php new file mode 100644 index 000000000..e9ce82960 --- /dev/null +++ b/src/Service/SecretsManager/src/ValueObject/ExternalSecretRotationMetadataItem.php @@ -0,0 +1,59 @@ +key = $input['Key'] ?? null; + $this->value = $input['Value'] ?? null; + } + + /** + * @param array{ + * Key?: string|null, + * Value?: string|null, + * }|ExternalSecretRotationMetadataItem $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getValue(): ?string + { + return $this->value; + } +} diff --git a/src/Service/SecretsManager/src/ValueObject/SecretListEntry.php b/src/Service/SecretsManager/src/ValueObject/SecretListEntry.php index 89cc82550..ebf0ce4f8 100644 --- a/src/Service/SecretsManager/src/ValueObject/SecretListEntry.php +++ b/src/Service/SecretsManager/src/ValueObject/SecretListEntry.php @@ -24,6 +24,16 @@ final class SecretListEntry */ private $name; + /** + * The exact string that identifies the third-party partner that holds the external secret. For more information, see + * Managed external secret partners [^1]. + * + * [^1]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/mes-partners.html + * + * @var string|null + */ + private $type; + /** * The user-provided description of the secret. * @@ -63,6 +73,27 @@ final class SecretListEntry */ private $rotationRules; + /** + * The metadata needed to successfully rotate a managed external secret. A list of key value pairs in JSON format + * specified by the partner. For more information about the required information, see Managed external secrets partners + * [^1]. + * + * [^1]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/mes-partners.html + * + * @var ExternalSecretRotationMetadataItem[]|null + */ + private $externalSecretRotationMetadata; + + /** + * The role that Secrets Manager assumes to call APIs required to perform the rotation. For more information about the + * required information, see Managed external secrets partners [^1]. + * + * [^1]: https://docs.aws.amazon.com/secretsmanager/latest/userguide/mes-partners.html + * + * @var string|null + */ + private $externalSecretRotationRoleArn; + /** * The most recent date and time that the Secrets Manager rotation process was successfully completed. This value is * null if the secret hasn't ever rotated. @@ -152,11 +183,14 @@ final class SecretListEntry * @param array{ * ARN?: string|null, * Name?: string|null, + * Type?: string|null, * Description?: string|null, * KmsKeyId?: string|null, * RotationEnabled?: bool|null, * RotationLambdaARN?: string|null, * RotationRules?: RotationRulesType|array|null, + * ExternalSecretRotationMetadata?: array|null, + * ExternalSecretRotationRoleArn?: string|null, * LastRotatedDate?: \DateTimeImmutable|null, * LastChangedDate?: \DateTimeImmutable|null, * LastAccessedDate?: \DateTimeImmutable|null, @@ -173,11 +207,14 @@ public function __construct(array $input) { $this->arn = $input['ARN'] ?? null; $this->name = $input['Name'] ?? null; + $this->type = $input['Type'] ?? null; $this->description = $input['Description'] ?? null; $this->kmsKeyId = $input['KmsKeyId'] ?? null; $this->rotationEnabled = $input['RotationEnabled'] ?? null; $this->rotationLambdaArn = $input['RotationLambdaARN'] ?? null; $this->rotationRules = isset($input['RotationRules']) ? RotationRulesType::create($input['RotationRules']) : null; + $this->externalSecretRotationMetadata = isset($input['ExternalSecretRotationMetadata']) ? array_map([ExternalSecretRotationMetadataItem::class, 'create'], $input['ExternalSecretRotationMetadata']) : null; + $this->externalSecretRotationRoleArn = $input['ExternalSecretRotationRoleArn'] ?? null; $this->lastRotatedDate = $input['LastRotatedDate'] ?? null; $this->lastChangedDate = $input['LastChangedDate'] ?? null; $this->lastAccessedDate = $input['LastAccessedDate'] ?? null; @@ -194,11 +231,14 @@ public function __construct(array $input) * @param array{ * ARN?: string|null, * Name?: string|null, + * Type?: string|null, * Description?: string|null, * KmsKeyId?: string|null, * RotationEnabled?: bool|null, * RotationLambdaARN?: string|null, * RotationRules?: RotationRulesType|array|null, + * ExternalSecretRotationMetadata?: array|null, + * ExternalSecretRotationRoleArn?: string|null, * LastRotatedDate?: \DateTimeImmutable|null, * LastChangedDate?: \DateTimeImmutable|null, * LastAccessedDate?: \DateTimeImmutable|null, @@ -236,6 +276,19 @@ public function getDescription(): ?string return $this->description; } + /** + * @return ExternalSecretRotationMetadataItem[] + */ + public function getExternalSecretRotationMetadata(): array + { + return $this->externalSecretRotationMetadata ?? []; + } + + public function getExternalSecretRotationRoleArn(): ?string + { + return $this->externalSecretRotationRoleArn; + } + public function getKmsKeyId(): ?string { return $this->kmsKeyId; @@ -306,4 +359,9 @@ public function getTags(): array { return $this->tags ?? []; } + + public function getType(): ?string + { + return $this->type; + } }