Repository: cloudtools/troposphere
Pull request #2133 (2023-03-17 13:05:11)

Updates from spec version 116.0.0
Autogenerated by maintenance action

If tests are stuck on https://github.com/peter-evans/create-pull-request/issues/48:
["Manually close pull requests and immediately reopen them. This will enable `on: pull_request` workflows to run and be added as checks."](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#triggering-further-workflow-runs)


Patch:
diff --git a/troposphere/athena.py b/troposphere/athena.py
index bb8bbed5..f44ea449 100644
--- a/troposphere/athena.py
+++ b/troposphere/athena.py
@@ -58,6 +58,16 @@ class PreparedStatement(AWSObject):
     }
 
 
+class CustomerContentEncryptionConfiguration(AWSProperty):
+    """
+    `CustomerContentEncryptionConfiguration <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-athena-workgroup-customercontentencryptionconfiguration.html>`__
+    """
+
+    props: PropsDictType = {
+        "KmsKey": (str, True),
+    }
+
+
 class EngineVersion(AWSProperty):
     """
     `EngineVersion <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-athena-workgroup-engineversion.html>`__
@@ -69,6 +79,16 @@ class EngineVersion(AWSProperty):
     }
 
 
+class AclConfiguration(AWSProperty):
+    """
+    `AclConfiguration <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-athena-workgroup-aclconfiguration.html>`__
+    """
+
+    props: PropsDictType = {
+        "S3AclOption": (str, True),
+    }
+
+
 class EncryptionConfiguration(AWSProperty):
     """
     `EncryptionConfiguration <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-athena-workgroup-encryptionconfiguration.html>`__
@@ -86,7 +106,9 @@ class ResultConfiguration(AWSProperty):
     """
 
     props: PropsDictType = {
+        "AclConfiguration": (AclConfiguration, False),
         "EncryptionConfiguration": (EncryptionConfiguration, False),
+        "ExpectedBucketOwner": (str, False),
         "OutputLocation": (str, False),
     }
 
@@ -97,9 +119,15 @@ class WorkGroupConfiguration(AWSProperty):
     """
 
     props: PropsDictType = {
+        "AdditionalConfiguration": (str, False),
         "BytesScannedCutoffPerQuery": (integer, False),
+        "CustomerContentEncryptionConfiguration": (
+            CustomerContentEncryptionConfiguration,
+            False,
+        ),
         "EnforceWorkGroupConfiguration": (boolean, False),
         "EngineVersion": (EngineVersion, False),
+        "ExecutionRole": (str, False),
         "PublishCloudWatchMetricsEnabled": (boolean, False),
         "RequesterPaysEnabled": (boolean, False),
         "ResultConfiguration": (ResultConfiguration, False),
diff --git a/troposphere/cassandra.py b/troposphere/cassandra.py
index 85de164e..2f79e458 100644
--- a/troposphere/cassandra.py
+++ b/troposphere/cassandra.py
@@ -91,6 +91,7 @@ class Table(AWSObject):
 
     props: PropsDictType = {
         "BillingMode": (BillingMode, False),
+        "ClientSideTimestampsEnabled": (boolean, False),
         "ClusteringKeyColumns": ([ClusteringKeyColumn], False),
         "DefaultTimeToLive": (integer, False),
         "EncryptionSpecification": (EncryptionSpecification, False),
diff --git a/troposphere/chatbot.py b/troposphere/chatbot.py
index 11c984ce..a770d6f3 100644
--- a/troposphere/chatbot.py
+++ b/troposphere/chatbot.py
@@ -11,6 +11,26 @@ from .validators import boolean
 from .validators.chatbot import validate_logginglevel
 
 
+class MicrosoftTeamsChannelConfiguration(AWSObject):
+    """
+    `MicrosoftTeamsChannelConfiguration <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-chatbot-microsoftteamschannelconfiguration.html>`__
+    """
+
+    resource_type = "AWS::Chatbot::MicrosoftTeamsChannelConfiguration"
+
+    props: PropsDictType = {
+        "ConfigurationName": (str, True),
+        "GuardrailPolicies": ([str], False),
+        "IamRoleArn": (str, True),
+        "LoggingLevel": (str, False),
+        "SnsTopicArns": ([str], False),
+        "TeamId": (str, True),
+        "TeamsChannelId": (str, True),
+        "TeamsTenantId": (str, True),
+        "UserRoleRequired": (boolean, False),
+    }
+
+
 class SlackChannelConfiguration(AWSObject):
     """
     `SlackChannelConfiguration <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-chatbot-slackchannelconfiguration.html>`__
diff --git a/troposphere/elasticloadbalancingv2.py b/troposphere/elasticloadbalancingv2.py
index d827d948..802bb9a9 100644
--- a/troposphere/elasticloadbalancingv2.py
+++ b/troposphere/elasticloadbalancingv2.py
@@ -328,7 +328,7 @@ class ListenerRule(AWSObject):
     props: PropsDictType = {
         "Actions": ([ListenerRuleAction], True),
         "Conditions": ([Condition], True),
-        "ListenerArn": (str, True),
+        "ListenerArn": (str, False),
         "Priority": (integer, True),
     }
 
diff --git a/troposphere/mediapackage.py b/troposphere/mediapackage.py
index e699e305..6fa1b8ac 100644
--- a/troposphere/mediapackage.py
+++ b/troposphere/mediapackage.py
@@ -105,10 +105,7 @@ class EncryptionContractConfiguration(AWSProperty):
     `EncryptionContractConfiguration <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediapackage-packagingconfiguration-encryptioncontractconfiguration.html>`__
     """
 
-    props: PropsDictType = {
-        "PresetSpeke20Audio": (str, True),
-        "PresetSpeke20Video": (str, True),
-    }
+    props: PropsDictType = {}
 
 
 class OriginEndpointSpekeKeyProvider(AWSProperty):
diff --git a/troposphere/rds.py b/troposphere/rds.py
index 54738151..833f98f0 100644
--- a/troposphere/rds.py
+++ b/troposphere/rds.py
@@ -7,7 +7,7 @@
 
 
 from . import AWSObject, AWSProperty, PropsDictType, Tags
-from .validators import boolean, double, integer
+from .validators import boolean, integer
 from .validators.rds import (
     validate_backtrack_window,
     validate_backup_retention_period,
@@ -21,6 +21,8 @@ from .validators.rds import (
     validate_network_port,
     validate_str_or_int,
     validate_tags_or_list,
+    validate_v2_capacity,
+    validate_v2_max_capacity,
 )
 
 
@@ -67,8 +69,8 @@ class ServerlessV2ScalingConfiguration(AWSProperty):
     """
 
     props: PropsDictType = {
-        "MaxCapacity": (double, False),
-        "MinCapacity": (double, False),
+        "MaxCapacity": (validate_v2_max_capacity, False),
+        "MinCapacity": (validate_v2_capacity, False),
     }
 
 
diff --git a/troposphere/rum.py b/troposphere/rum.py
index 71052116..430c466f 100644
--- a/troposphere/rum.py
+++ b/troposphere/rum.py
@@ -19,6 +19,7 @@ class MetricDefinition(AWSProperty):
         "DimensionKeys": (dict, False),
         "EventPattern": (str, False),
         "Name": (str, True),
+        "Namespace": (str, False),
         "UnitLabel": (str, False),
         "ValueKey": (str, False),
     }
diff --git a/troposphere/s3.py b/troposphere/s3.py
index 4fd5cc90..d1855b54 100644
--- a/troposphere/s3.py
+++ b/troposphere/s3.py
@@ -775,6 +775,7 @@ class Region(AWSProperty):
 
     props: PropsDictType = {
         "Bucket": (str, True),
+        "BucketAccountId": (str, False),
     }
 
 
diff --git a/troposphere/sagemaker.py b/troposphere/sagemaker.py
index 915b4f3f..b1161d5c 100644
--- a/troposphere/sagemaker.py
+++ b/troposphere/sagemaker.py
@@ -665,7 +665,7 @@ class AsyncInferenceConfig(AWSProperty):
 
 class CaptureContentTypeHeader(AWSProperty):
     """
-    `CaptureContentTypeHeader <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-endpointconfig-datacaptureconfig-capturecontenttypeheader.html>`__
+    `CaptureContentTypeHeader <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-capturecontenttypeheader.html>`__
     """
 
     props: PropsDictType = {
@@ -944,6 +944,109 @@ class ImageVersion(AWSObject):
     }
 
 
+class DataStorageConfig(AWSProperty):
+    """
+    `DataStorageConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-datastorageconfig.html>`__
+    """
+
+    props: PropsDictType = {
+        "ContentType": (CaptureContentTypeHeader, False),
+        "Destination": (str, True),
+        "KmsKey": (str, False),
+    }
+
+
+class InferenceExperimentSchedule(AWSProperty):
+    """
+    `InferenceExperimentSchedule <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-inferenceexperimentschedule.html>`__
+    """
+
+    props: PropsDictType = {
+        "EndTime": (str, False),
+        "StartTime": (str, False),
+    }
+
+
+class RealTimeInferenceConfig(AWSProperty):
+    """
+    `RealTimeInferenceConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-realtimeinferenceconfig.html>`__
+    """
+
+    props: PropsDictType = {
+        "InstanceCount": (integer, True),
+        "InstanceType": (str, True),
+    }
+
+
+class ModelInfrastructureConfig(AWSProperty):
+    """
+    `ModelInfrastructureConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-modelinfrastructureconfig.html>`__
+    """
+
+    props: PropsDictType = {
+        "InfrastructureType": (str, True),
+        "RealTimeInferenceConfig": (RealTimeInferenceConfig, True),
+    }
+
+
+class ModelVariantConfig(AWSProperty):
+    """
+    `ModelVariantConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-modelvariantconfig.html>`__
+    """
+
+    props: PropsDictType = {
+        "InfrastructureConfig": (ModelInfrastructureConfig, True),
+        "ModelName": (str, True),
+        "VariantName": (str, True),
+    }
+
+
+class ShadowModelVariantConfig(AWSProperty):
+    """
+    `ShadowModelVariantConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-shadowmodelvariantconfig.html>`__
+    """
+
+    props: PropsDictType = {
+        "SamplingPercentage": (integer, True),
+        "ShadowModelVariantName": (str, True),
+    }
+
+
+class ShadowModeConfig(AWSProperty):
+    """
+    `ShadowModeConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-shadowmodeconfig.html>`__
+    """
+
+    props: PropsDictType = {
+        "ShadowModelVariants": ([ShadowModelVariantConfig], True),
+        "SourceModelVariantName": (str, True),
+    }
+
+
+class InferenceExperiment(AWSObject):
+    """
+    `InferenceExperiment <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-inferenceexperiment.html>`__
+    """
+
+    resource_type = "AWS::SageMaker::InferenceExperiment"
+
+    props: PropsDictType = {
+        "DataStorageConfig": (DataStorageConfig, False),
+        "Description": (str, False),
+        "DesiredState": (str, False),
+        "EndpointName": (str, True),
+        "KmsKey": (str, False),
+        "ModelVariants": ([ModelVariantConfig], True),
+        "Name": (str, True),
+        "RoleArn": (str, True),
+        "Schedule": (InferenceExperimentSchedule, False),
+        "ShadowModeConfig": (ShadowModeConfig, False),
+        "StatusReason": (str, False),
+        "Tags": (Tags, False),
+        "Type": (str, True),
+    }
+
+
 class RepositoryAuthConfig(AWSProperty):
     """
     `RepositoryAuthConfig <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-model-containerdefinition-imageconfig-repositoryauthconfig.html>`__
@@ -2292,6 +2395,18 @@ class Workteam(AWSObject):
     }
 
 
+class EndpointMetadata(AWSProperty):
+    """
+    `EndpointMetadata <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-inferenceexperiment-endpointmetadata.html>`__
+    """
+
+    props: PropsDictType = {
+        "EndpointConfigName": (str, False),
+        "EndpointName": (str, True),
+        "EndpointStatus": (str, False),
+    }
+
+
 class RSessionAppSettings(AWSProperty):
     """
     `RSessionAppSettings <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-domain-rsessionappsettings.html>`__
diff --git a/troposphere/ssmcontacts.py b/troposphere/ssmcontacts.py
index 00d3bb56..78d579ad 100644
--- a/troposphere/ssmcontacts.py
+++ b/troposphere/ssmcontacts.py
@@ -64,7 +64,7 @@ class Contact(AWSObject):
     props: PropsDictType = {
         "Alias": (str, True),
         "DisplayName": (str, True),
-        "Plan": ([Stage], True),
+        "Plan": ([Stage], False),
         "Type": (str, True),
     }
 
diff --git a/troposphere/validators/rds.py b/troposphere/validators/rds.py
index 2b2c7610..cc02c6d7 100644
--- a/troposphere/validators/rds.py
+++ b/troposphere/validators/rds.py
@@ -262,6 +262,49 @@ def validate_capacity(capacity):
     return capacity
 
 
+def validate_v2_capacity(capacity):
+    """
+    Validate ServerlessV2ScalingConfiguration capacity for serverless DBCluster
+    Property: ServerlessV2ScalingConfiguration.MinCapacity
+    """
+    if capacity < 0.5:
+        raise ValueError(
+            "ServerlessV2ScalingConfiguration capacity {} cannot be smaller than 0.5.".format(
+                capacity
+            )
+        )
+    if capacity > 128:
+        raise ValueError(
+            "ServerlessV2ScalingConfiguration capacity {} cannot be larger than 128.".format(
+                capacity
+            )
+        )
+
+    if capacity * 10 % 5 != 0:
+        raise ValueError(
+            "ServerlessV2ScalingConfiguration capacity {} cannot be only specific in half-step increments.".format(
+                capacity
+            )
+        )
+
+    return capacity
+
+
+def validate_v2_max_capacity(capacity):
+    """
+    Validate ServerlessV2ScalingConfiguration max capacity for serverless DBCluster
+    Property: ServerlessV2ScalingConfiguration.MaxCapacity
+    """
+    if capacity < 1:
+        raise ValueError(
+            "ServerlessV2ScalingConfiguration max capacity {} cannot be smaller than 1.".format(
+                capacity
+            )
+        )
+
+    return validate_v2_capacity(capacity)
+
+
 def validate_dbinstance(self) -> None:
     """
     Class: DBInstance


Test patch:
diff --git a/tests/test_rds.py b/tests/test_rds.py
index 45dd5f82..98aa599b 100644
--- a/tests/test_rds.py
+++ b/tests/test_rds.py
@@ -341,3 +341,16 @@ class TestRDSValidators(unittest.TestCase):
 
         with self.assertRaises(ValueError):
             vrds.validate_capacity(100001)
+
+    def test_v2_validate_capacity(self):
+        vrds.validate_v2_capacity(64)
+        vrds.validate_v2_capacity(0.5)
+
+        with self.assertRaises(ValueError):
+            vrds.validate_v2_capacity(129)
+
+        with self.assertRaises(ValueError):
+            vrds.validate_v2_capacity(1.1)
+
+        with self.assertRaises(ValueError):
+            vrds.validate_v2_max_capacity(0.5)