'''
# Amazon Redshift Construct Library

<!--BEGIN STABILITY BANNER-->---


![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)

> All classes with the `Cfn` prefix in this module ([CFN Resources](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) are always stable and safe to use.

![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)

> The APIs of higher level constructs in this module are experimental and under active development.
> They are subject to non-backward compatible changes or removal in any future version. These are
> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
> announced in the release notes. This means that while you may use them, you may need to update
> your source code when upgrading to a newer version of this package.

---
<!--END STABILITY BANNER-->

## Starting a Redshift Cluster Database

To set up a Redshift cluster, define a `Cluster`. It will be launched in a VPC.
You can specify a VPC, otherwise one will be created. The nodes are always launched in private subnets and are encrypted by default.

```python
import aws_cdk.aws_ec2 as ec2


vpc = ec2.Vpc(self, "Vpc")
cluster = Cluster(self, "Redshift",
    master_user=Login(
        master_username="admin"
    ),
    vpc=vpc
)
```

By default, the master password will be generated and stored in AWS Secrets Manager.

A default database named `default_db` will be created in the cluster. To change the name of this database set the `defaultDatabaseName` attribute in the constructor properties.

By default, the cluster will not be publicly accessible.
Depending on your use case, you can make the cluster publicly accessible with the `publiclyAccessible` property.

## Connecting

To control who can access the cluster, use the `.connections` attribute. Redshift Clusters have
a default port, so you don't need to specify the port:

```python
cluster.connections.allow_default_port_from_any_ipv4("Open to the world")
```

The endpoint to access your database cluster will be available as the `.clusterEndpoint` attribute:

```python
cluster.cluster_endpoint.socket_address
```

## Rotating credentials

When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically:

```python
cluster.add_rotation_single_user()
```

The multi user rotation scheme is also available:

```python
import aws_cdk.aws_secretsmanager as secretsmanager


cluster.add_rotation_multi_user("MyUser",
    secret=secretsmanager.Secret.from_secret_name_v2(self, "Imported Secret", "my-secret")
)
```

## Database Resources

This module allows for the creation of non-CloudFormation database resources such as users
and tables. This allows you to manage identities, permissions, and stateful resources
within your Redshift cluster from your CDK application.

Because these resources are not available in CloudFormation, this library leverages
[custom
resources](https://docs.aws.amazon.com/cdk/api/latest/docs/custom-resources-readme.html)
to manage them. In addition to the IAM permissions required to make Redshift service
calls, the execution role for the custom resource handler requires database credentials to
create resources within the cluster.

These database credentials can be supplied explicitly through the `adminUser` properties
of the various database resource constructs. Alternatively, the credentials can be
automatically pulled from the Redshift cluster's default administrator
credentials. However, this option is only available if the password for the credentials
was generated by the CDK application (ie., no value vas provided for [the `masterPassword`
property](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-redshift.Login.html#masterpasswordspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan)
of
[`Cluster.masterUser`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-redshift.Cluster.html#masteruserspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan)).

### Creating Users

Create a user within a Redshift cluster database by instantiating a `User` construct. This
will generate a username and password, store the credentials in a [AWS Secrets Manager
`Secret`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-secretsmanager.Secret.html),
and make a query to the Redshift cluster to create a new database user with the
credentials.

```python
User(self, "User",
    cluster=cluster,
    database_name="databaseName"
)
```

By default, the user credentials are encrypted with your AWS account's default Secrets
Manager encryption key. You can specify the encryption key used for this purpose by
supplying a key in the `encryptionKey` property.

```python
import aws_cdk.aws_kms as kms


encryption_key = kms.Key(self, "Key")
User(self, "User",
    encryption_key=encryption_key,
    cluster=cluster,
    database_name="databaseName"
)
```

By default, a username is automatically generated from the user construct ID and its path
in the construct tree. You can specify a particular username by providing a value for the
`username` property. Usernames must be valid identifiers; see: [Names and
identifiers](https://docs.aws.amazon.com/redshift/latest/dg/r_names.html) in the *Amazon
Redshift Database Developer Guide*.

```python
User(self, "User",
    username="myuser",
    cluster=cluster,
    database_name="databaseName"
)
```

The user password is generated by AWS Secrets Manager using the default configuration
found in
[`secretsmanager.SecretStringGenerator`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-secretsmanager.SecretStringGenerator.html),
except with password length `30` and some SQL-incompliant characters excluded. The
plaintext for the password will never be present in the CDK application; instead, a
[CloudFormation Dynamic
Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html)
will be used wherever the password value is required.

### Creating Tables

Create a table within a Redshift cluster database by instantiating a `Table`
construct. This will make a query to the Redshift cluster to create a new database table
with the supplied schema.

```python
Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name="databaseName"
)
```

The table can be configured to have distStyle attribute and a distKey column:

```python
Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)", dist_key=True), Column(name="col2", data_type="float")
    ],
    cluster=cluster,
    database_name="databaseName",
    dist_style=TableDistStyle.KEY
)
```

The table can also be configured to have sortStyle attribute and sortKey columns:

```python
Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)", sort_key=True), Column(name="col2", data_type="float", sort_key=True)
    ],
    cluster=cluster,
    database_name="databaseName",
    sort_style=TableSortStyle.COMPOUND
)
```

### Granting Privileges

You can give a user privileges to perform certain actions on a table by using the
`Table.grant()` method.

```python
user = User(self, "User",
    cluster=cluster,
    database_name="databaseName"
)
table = Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name="databaseName"
)

table.grant(user, TableAction.DROP, TableAction.SELECT)
```

Take care when managing privileges via the CDK, as attempting to manage a user's
privileges on the same table in multiple CDK applications could lead to accidentally
overriding these permissions. Consider the following two CDK applications which both refer
to the same user and table. In application 1, the resources are created and the user is
given `INSERT` permissions on the table:

```python
database_name = "databaseName"
username = "myuser"
table_name = "mytable"

user = User(self, "User",
    username=username,
    cluster=cluster,
    database_name=database_name
)
table = Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name=database_name
)
table.grant(user, TableAction.INSERT)
```

In application 2, the resources are imported and the user is given `INSERT` permissions on
the table:

```python
database_name = "databaseName"
username = "myuser"
table_name = "mytable"

user = User.from_user_attributes(self, "User",
    username=username,
    password=SecretValue.plain_text("NOT_FOR_PRODUCTION"),
    cluster=cluster,
    database_name=database_name
)
table = Table.from_table_attributes(self, "Table",
    table_name=table_name,
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name="databaseName"
)
table.grant(user, TableAction.INSERT)
```

Both applications attempt to grant the user the appropriate privilege on the table by
submitting a `GRANT USER` SQL query to the Redshift cluster. Note that the latter of these
two calls will have no effect since the user has already been granted the privilege.

Now, if application 1 were to remove the call to `grant`, a `REVOKE USER` SQL query is
submitted to the Redshift cluster. In general, application 1 does not know that
application 2 has also granted this permission and thus cannot decide not to issue the
revocation. This leads to the undesirable state where application 2 still contains the
call to `grant` but the user does not have the specified permission.

Note that this does not occur when duplicate privileges are granted within the same
application, as such privileges are de-duplicated before any SQL query is submitted.
'''
import abc
import builtins
import datetime
import enum
import typing

import jsii
import publication
import typing_extensions

from ._jsii import *

import aws_cdk.aws_ec2
import aws_cdk.aws_iam
import aws_cdk.aws_kms
import aws_cdk.aws_s3
import aws_cdk.aws_secretsmanager
import aws_cdk.core
import constructs


@jsii.implements(aws_cdk.core.IInspectable)
class CfnCluster(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnCluster",
):
    '''A CloudFormation ``AWS::Redshift::Cluster``.

    :cloudformationResource: AWS::Redshift::Cluster
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_cluster = redshift.CfnCluster(self, "MyCfnCluster",
            cluster_type="clusterType",
            db_name="dbName",
            master_username="masterUsername",
            master_user_password="masterUserPassword",
            node_type="nodeType",
        
            # the properties below are optional
            allow_version_upgrade=False,
            aqua_configuration_status="aquaConfigurationStatus",
            automated_snapshot_retention_period=123,
            availability_zone="availabilityZone",
            availability_zone_relocation=False,
            availability_zone_relocation_status="availabilityZoneRelocationStatus",
            classic=False,
            cluster_identifier="clusterIdentifier",
            cluster_parameter_group_name="clusterParameterGroupName",
            cluster_security_groups=["clusterSecurityGroups"],
            cluster_subnet_group_name="clusterSubnetGroupName",
            cluster_version="clusterVersion",
            defer_maintenance=False,
            defer_maintenance_duration=123,
            defer_maintenance_end_time="deferMaintenanceEndTime",
            defer_maintenance_start_time="deferMaintenanceStartTime",
            destination_region="destinationRegion",
            elastic_ip="elasticIp",
            encrypted=False,
            enhanced_vpc_routing=False,
            hsm_client_certificate_identifier="hsmClientCertificateIdentifier",
            hsm_configuration_identifier="hsmConfigurationIdentifier",
            iam_roles=["iamRoles"],
            kms_key_id="kmsKeyId",
            logging_properties=redshift.CfnCluster.LoggingPropertiesProperty(
                bucket_name="bucketName",
        
                # the properties below are optional
                s3_key_prefix="s3KeyPrefix"
            ),
            maintenance_track_name="maintenanceTrackName",
            manual_snapshot_retention_period=123,
            number_of_nodes=123,
            owner_account="ownerAccount",
            port=123,
            preferred_maintenance_window="preferredMaintenanceWindow",
            publicly_accessible=False,
            resource_action="resourceAction",
            revision_target="revisionTarget",
            rotate_encryption_key=False,
            snapshot_cluster_identifier="snapshotClusterIdentifier",
            snapshot_copy_grant_name="snapshotCopyGrantName",
            snapshot_copy_manual=False,
            snapshot_copy_retention_period=123,
            snapshot_identifier="snapshotIdentifier",
            tags=[CfnTag(
                key="key",
                value="value"
            )],
            vpc_security_group_ids=["vpcSecurityGroupIds"]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        allow_version_upgrade: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        aqua_configuration_status: typing.Optional[builtins.str] = None,
        automated_snapshot_retention_period: typing.Optional[jsii.Number] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        availability_zone_relocation: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        availability_zone_relocation_status: typing.Optional[builtins.str] = None,
        classic: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        cluster_identifier: typing.Optional[builtins.str] = None,
        cluster_parameter_group_name: typing.Optional[builtins.str] = None,
        cluster_security_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
        cluster_subnet_group_name: typing.Optional[builtins.str] = None,
        cluster_type: builtins.str,
        cluster_version: typing.Optional[builtins.str] = None,
        db_name: builtins.str,
        defer_maintenance: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        defer_maintenance_duration: typing.Optional[jsii.Number] = None,
        defer_maintenance_end_time: typing.Optional[builtins.str] = None,
        defer_maintenance_start_time: typing.Optional[builtins.str] = None,
        destination_region: typing.Optional[builtins.str] = None,
        elastic_ip: typing.Optional[builtins.str] = None,
        encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        enhanced_vpc_routing: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        hsm_client_certificate_identifier: typing.Optional[builtins.str] = None,
        hsm_configuration_identifier: typing.Optional[builtins.str] = None,
        iam_roles: typing.Optional[typing.Sequence[builtins.str]] = None,
        kms_key_id: typing.Optional[builtins.str] = None,
        logging_properties: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnCluster.LoggingPropertiesProperty"]] = None,
        maintenance_track_name: typing.Optional[builtins.str] = None,
        manual_snapshot_retention_period: typing.Optional[jsii.Number] = None,
        master_username: builtins.str,
        master_user_password: builtins.str,
        node_type: builtins.str,
        number_of_nodes: typing.Optional[jsii.Number] = None,
        owner_account: typing.Optional[builtins.str] = None,
        port: typing.Optional[jsii.Number] = None,
        preferred_maintenance_window: typing.Optional[builtins.str] = None,
        publicly_accessible: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        resource_action: typing.Optional[builtins.str] = None,
        revision_target: typing.Optional[builtins.str] = None,
        rotate_encryption_key: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        snapshot_cluster_identifier: typing.Optional[builtins.str] = None,
        snapshot_copy_grant_name: typing.Optional[builtins.str] = None,
        snapshot_copy_manual: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        snapshot_copy_retention_period: typing.Optional[jsii.Number] = None,
        snapshot_identifier: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
        vpc_security_group_ids: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::Cluster``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param allow_version_upgrade: ``AWS::Redshift::Cluster.AllowVersionUpgrade``.
        :param aqua_configuration_status: ``AWS::Redshift::Cluster.AquaConfigurationStatus``.
        :param automated_snapshot_retention_period: ``AWS::Redshift::Cluster.AutomatedSnapshotRetentionPeriod``.
        :param availability_zone: ``AWS::Redshift::Cluster.AvailabilityZone``.
        :param availability_zone_relocation: ``AWS::Redshift::Cluster.AvailabilityZoneRelocation``.
        :param availability_zone_relocation_status: ``AWS::Redshift::Cluster.AvailabilityZoneRelocationStatus``.
        :param classic: ``AWS::Redshift::Cluster.Classic``.
        :param cluster_identifier: ``AWS::Redshift::Cluster.ClusterIdentifier``.
        :param cluster_parameter_group_name: ``AWS::Redshift::Cluster.ClusterParameterGroupName``.
        :param cluster_security_groups: ``AWS::Redshift::Cluster.ClusterSecurityGroups``.
        :param cluster_subnet_group_name: ``AWS::Redshift::Cluster.ClusterSubnetGroupName``.
        :param cluster_type: ``AWS::Redshift::Cluster.ClusterType``.
        :param cluster_version: ``AWS::Redshift::Cluster.ClusterVersion``.
        :param db_name: ``AWS::Redshift::Cluster.DBName``.
        :param defer_maintenance: ``AWS::Redshift::Cluster.DeferMaintenance``.
        :param defer_maintenance_duration: ``AWS::Redshift::Cluster.DeferMaintenanceDuration``.
        :param defer_maintenance_end_time: ``AWS::Redshift::Cluster.DeferMaintenanceEndTime``.
        :param defer_maintenance_start_time: ``AWS::Redshift::Cluster.DeferMaintenanceStartTime``.
        :param destination_region: ``AWS::Redshift::Cluster.DestinationRegion``.
        :param elastic_ip: ``AWS::Redshift::Cluster.ElasticIp``.
        :param encrypted: ``AWS::Redshift::Cluster.Encrypted``.
        :param enhanced_vpc_routing: ``AWS::Redshift::Cluster.EnhancedVpcRouting``.
        :param hsm_client_certificate_identifier: ``AWS::Redshift::Cluster.HsmClientCertificateIdentifier``.
        :param hsm_configuration_identifier: ``AWS::Redshift::Cluster.HsmConfigurationIdentifier``.
        :param iam_roles: ``AWS::Redshift::Cluster.IamRoles``.
        :param kms_key_id: ``AWS::Redshift::Cluster.KmsKeyId``.
        :param logging_properties: ``AWS::Redshift::Cluster.LoggingProperties``.
        :param maintenance_track_name: ``AWS::Redshift::Cluster.MaintenanceTrackName``.
        :param manual_snapshot_retention_period: ``AWS::Redshift::Cluster.ManualSnapshotRetentionPeriod``.
        :param master_username: ``AWS::Redshift::Cluster.MasterUsername``.
        :param master_user_password: ``AWS::Redshift::Cluster.MasterUserPassword``.
        :param node_type: ``AWS::Redshift::Cluster.NodeType``.
        :param number_of_nodes: ``AWS::Redshift::Cluster.NumberOfNodes``.
        :param owner_account: ``AWS::Redshift::Cluster.OwnerAccount``.
        :param port: ``AWS::Redshift::Cluster.Port``.
        :param preferred_maintenance_window: ``AWS::Redshift::Cluster.PreferredMaintenanceWindow``.
        :param publicly_accessible: ``AWS::Redshift::Cluster.PubliclyAccessible``.
        :param resource_action: ``AWS::Redshift::Cluster.ResourceAction``.
        :param revision_target: ``AWS::Redshift::Cluster.RevisionTarget``.
        :param rotate_encryption_key: ``AWS::Redshift::Cluster.RotateEncryptionKey``.
        :param snapshot_cluster_identifier: ``AWS::Redshift::Cluster.SnapshotClusterIdentifier``.
        :param snapshot_copy_grant_name: ``AWS::Redshift::Cluster.SnapshotCopyGrantName``.
        :param snapshot_copy_manual: ``AWS::Redshift::Cluster.SnapshotCopyManual``.
        :param snapshot_copy_retention_period: ``AWS::Redshift::Cluster.SnapshotCopyRetentionPeriod``.
        :param snapshot_identifier: ``AWS::Redshift::Cluster.SnapshotIdentifier``.
        :param tags: ``AWS::Redshift::Cluster.Tags``.
        :param vpc_security_group_ids: ``AWS::Redshift::Cluster.VpcSecurityGroupIds``.
        '''
        props = CfnClusterProps(
            allow_version_upgrade=allow_version_upgrade,
            aqua_configuration_status=aqua_configuration_status,
            automated_snapshot_retention_period=automated_snapshot_retention_period,
            availability_zone=availability_zone,
            availability_zone_relocation=availability_zone_relocation,
            availability_zone_relocation_status=availability_zone_relocation_status,
            classic=classic,
            cluster_identifier=cluster_identifier,
            cluster_parameter_group_name=cluster_parameter_group_name,
            cluster_security_groups=cluster_security_groups,
            cluster_subnet_group_name=cluster_subnet_group_name,
            cluster_type=cluster_type,
            cluster_version=cluster_version,
            db_name=db_name,
            defer_maintenance=defer_maintenance,
            defer_maintenance_duration=defer_maintenance_duration,
            defer_maintenance_end_time=defer_maintenance_end_time,
            defer_maintenance_start_time=defer_maintenance_start_time,
            destination_region=destination_region,
            elastic_ip=elastic_ip,
            encrypted=encrypted,
            enhanced_vpc_routing=enhanced_vpc_routing,
            hsm_client_certificate_identifier=hsm_client_certificate_identifier,
            hsm_configuration_identifier=hsm_configuration_identifier,
            iam_roles=iam_roles,
            kms_key_id=kms_key_id,
            logging_properties=logging_properties,
            maintenance_track_name=maintenance_track_name,
            manual_snapshot_retention_period=manual_snapshot_retention_period,
            master_username=master_username,
            master_user_password=master_user_password,
            node_type=node_type,
            number_of_nodes=number_of_nodes,
            owner_account=owner_account,
            port=port,
            preferred_maintenance_window=preferred_maintenance_window,
            publicly_accessible=publicly_accessible,
            resource_action=resource_action,
            revision_target=revision_target,
            rotate_encryption_key=rotate_encryption_key,
            snapshot_cluster_identifier=snapshot_cluster_identifier,
            snapshot_copy_grant_name=snapshot_copy_grant_name,
            snapshot_copy_manual=snapshot_copy_manual,
            snapshot_copy_retention_period=snapshot_copy_retention_period,
            snapshot_identifier=snapshot_identifier,
            tags=tags,
            vpc_security_group_ids=vpc_security_group_ids,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allowVersionUpgrade")
    def allow_version_upgrade(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.AllowVersionUpgrade``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-allowversionupgrade
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "allowVersionUpgrade"))

    @allow_version_upgrade.setter
    def allow_version_upgrade(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "allowVersionUpgrade", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="aquaConfigurationStatus")
    def aqua_configuration_status(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.AquaConfigurationStatus``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-aquaconfigurationstatus
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "aquaConfigurationStatus"))

    @aqua_configuration_status.setter
    def aqua_configuration_status(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "aquaConfigurationStatus", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDeferMaintenanceIdentifier")
    def attr_defer_maintenance_identifier(self) -> builtins.str:
        '''
        :cloudformationAttribute: DeferMaintenanceIdentifier
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrDeferMaintenanceIdentifier"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrEndpointAddress")
    def attr_endpoint_address(self) -> builtins.str:
        '''
        :cloudformationAttribute: Endpoint.Address
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrEndpointAddress"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrEndpointPort")
    def attr_endpoint_port(self) -> builtins.str:
        '''
        :cloudformationAttribute: Endpoint.Port
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrEndpointPort"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="automatedSnapshotRetentionPeriod")
    def automated_snapshot_retention_period(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.AutomatedSnapshotRetentionPeriod``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-automatedsnapshotretentionperiod
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "automatedSnapshotRetentionPeriod"))

    @automated_snapshot_retention_period.setter
    def automated_snapshot_retention_period(
        self,
        value: typing.Optional[jsii.Number],
    ) -> None:
        jsii.set(self, "automatedSnapshotRetentionPeriod", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzone
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "availabilityZone"))

    @availability_zone.setter
    def availability_zone(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "availabilityZone", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZoneRelocation")
    def availability_zone_relocation(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.AvailabilityZoneRelocation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzonerelocation
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "availabilityZoneRelocation"))

    @availability_zone_relocation.setter
    def availability_zone_relocation(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "availabilityZoneRelocation", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZoneRelocationStatus")
    def availability_zone_relocation_status(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.AvailabilityZoneRelocationStatus``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzonerelocationstatus
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "availabilityZoneRelocationStatus"))

    @availability_zone_relocation_status.setter
    def availability_zone_relocation_status(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "availabilityZoneRelocationStatus", value)

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="classic")
    def classic(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.Classic``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-classic
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "classic"))

    @classic.setter
    def classic(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "classic", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterIdentifier")
    def cluster_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clusteridentifier
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "clusterIdentifier"))

    @cluster_identifier.setter
    def cluster_identifier(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "clusterIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterParameterGroupName")
    def cluster_parameter_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterParameterGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clusterparametergroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "clusterParameterGroupName"))

    @cluster_parameter_group_name.setter
    def cluster_parameter_group_name(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "clusterParameterGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterSecurityGroups")
    def cluster_security_groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::Cluster.ClusterSecurityGroups``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clustersecuritygroups
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "clusterSecurityGroups"))

    @cluster_security_groups.setter
    def cluster_security_groups(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "clusterSecurityGroups", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterSubnetGroupName")
    def cluster_subnet_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterSubnetGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clustersubnetgroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "clusterSubnetGroupName"))

    @cluster_subnet_group_name.setter
    def cluster_subnet_group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "clusterSubnetGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterType")
    def cluster_type(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.ClusterType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clustertype
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterType"))

    @cluster_type.setter
    def cluster_type(self, value: builtins.str) -> None:
        jsii.set(self, "clusterType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterVersion")
    def cluster_version(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterVersion``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clusterversion
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "clusterVersion"))

    @cluster_version.setter
    def cluster_version(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "clusterVersion", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dbName")
    def db_name(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.DBName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-dbname
        '''
        return typing.cast(builtins.str, jsii.get(self, "dbName"))

    @db_name.setter
    def db_name(self, value: builtins.str) -> None:
        jsii.set(self, "dbName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deferMaintenance")
    def defer_maintenance(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.DeferMaintenance``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenance
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "deferMaintenance"))

    @defer_maintenance.setter
    def defer_maintenance(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "deferMaintenance", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deferMaintenanceDuration")
    def defer_maintenance_duration(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.DeferMaintenanceDuration``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenanceduration
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "deferMaintenanceDuration"))

    @defer_maintenance_duration.setter
    def defer_maintenance_duration(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "deferMaintenanceDuration", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deferMaintenanceEndTime")
    def defer_maintenance_end_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.DeferMaintenanceEndTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenanceendtime
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "deferMaintenanceEndTime"))

    @defer_maintenance_end_time.setter
    def defer_maintenance_end_time(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "deferMaintenanceEndTime", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deferMaintenanceStartTime")
    def defer_maintenance_start_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.DeferMaintenanceStartTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenancestarttime
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "deferMaintenanceStartTime"))

    @defer_maintenance_start_time.setter
    def defer_maintenance_start_time(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "deferMaintenanceStartTime", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationRegion")
    def destination_region(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.DestinationRegion``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-destinationregion
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationRegion"))

    @destination_region.setter
    def destination_region(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "destinationRegion", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elasticIp")
    def elastic_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ElasticIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-elasticip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "elasticIp"))

    @elastic_ip.setter
    def elastic_ip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "elasticIp", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="encrypted")
    def encrypted(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.Encrypted``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-encrypted
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "encrypted"))

    @encrypted.setter
    def encrypted(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "encrypted", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="enhancedVpcRouting")
    def enhanced_vpc_routing(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.EnhancedVpcRouting``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-enhancedvpcrouting
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "enhancedVpcRouting"))

    @enhanced_vpc_routing.setter
    def enhanced_vpc_routing(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "enhancedVpcRouting", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hsmClientCertificateIdentifier")
    def hsm_client_certificate_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.HsmClientCertificateIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-hsmclientcertificateidentifier
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "hsmClientCertificateIdentifier"))

    @hsm_client_certificate_identifier.setter
    def hsm_client_certificate_identifier(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "hsmClientCertificateIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hsmConfigurationIdentifier")
    def hsm_configuration_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.HsmConfigurationIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-hsmconfigurationidentifier
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "hsmConfigurationIdentifier"))

    @hsm_configuration_identifier.setter
    def hsm_configuration_identifier(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "hsmConfigurationIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="iamRoles")
    def iam_roles(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::Cluster.IamRoles``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-iamroles
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "iamRoles"))

    @iam_roles.setter
    def iam_roles(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "iamRoles", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="kmsKeyId")
    def kms_key_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.KmsKeyId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-kmskeyid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "kmsKeyId"))

    @kms_key_id.setter
    def kms_key_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "kmsKeyId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="loggingProperties")
    def logging_properties(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnCluster.LoggingPropertiesProperty"]]:
        '''``AWS::Redshift::Cluster.LoggingProperties``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-loggingproperties
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnCluster.LoggingPropertiesProperty"]], jsii.get(self, "loggingProperties"))

    @logging_properties.setter
    def logging_properties(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnCluster.LoggingPropertiesProperty"]],
    ) -> None:
        jsii.set(self, "loggingProperties", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="maintenanceTrackName")
    def maintenance_track_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.MaintenanceTrackName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-maintenancetrackname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "maintenanceTrackName"))

    @maintenance_track_name.setter
    def maintenance_track_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "maintenanceTrackName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="manualSnapshotRetentionPeriod")
    def manual_snapshot_retention_period(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.ManualSnapshotRetentionPeriod``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-manualsnapshotretentionperiod
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "manualSnapshotRetentionPeriod"))

    @manual_snapshot_retention_period.setter
    def manual_snapshot_retention_period(
        self,
        value: typing.Optional[jsii.Number],
    ) -> None:
        jsii.set(self, "manualSnapshotRetentionPeriod", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="masterUsername")
    def master_username(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.MasterUsername``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-masterusername
        '''
        return typing.cast(builtins.str, jsii.get(self, "masterUsername"))

    @master_username.setter
    def master_username(self, value: builtins.str) -> None:
        jsii.set(self, "masterUsername", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="masterUserPassword")
    def master_user_password(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.MasterUserPassword``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-masteruserpassword
        '''
        return typing.cast(builtins.str, jsii.get(self, "masterUserPassword"))

    @master_user_password.setter
    def master_user_password(self, value: builtins.str) -> None:
        jsii.set(self, "masterUserPassword", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="nodeType")
    def node_type(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.NodeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-nodetype
        '''
        return typing.cast(builtins.str, jsii.get(self, "nodeType"))

    @node_type.setter
    def node_type(self, value: builtins.str) -> None:
        jsii.set(self, "nodeType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="numberOfNodes")
    def number_of_nodes(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.NumberOfNodes``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-numberofnodes
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "numberOfNodes"))

    @number_of_nodes.setter
    def number_of_nodes(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "numberOfNodes", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ownerAccount")
    def owner_account(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.OwnerAccount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-owneraccount
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "ownerAccount"))

    @owner_account.setter
    def owner_account(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "ownerAccount", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="port")
    def port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.Port``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-port
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "port"))

    @port.setter
    def port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "port", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="preferredMaintenanceWindow")
    def preferred_maintenance_window(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.PreferredMaintenanceWindow``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-preferredmaintenancewindow
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "preferredMaintenanceWindow"))

    @preferred_maintenance_window.setter
    def preferred_maintenance_window(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "preferredMaintenanceWindow", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publiclyAccessible")
    def publicly_accessible(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.PubliclyAccessible``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-publiclyaccessible
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "publiclyAccessible"))

    @publicly_accessible.setter
    def publicly_accessible(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "publiclyAccessible", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceAction")
    def resource_action(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ResourceAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-resourceaction
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "resourceAction"))

    @resource_action.setter
    def resource_action(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "resourceAction", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="revisionTarget")
    def revision_target(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.RevisionTarget``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-revisiontarget
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "revisionTarget"))

    @revision_target.setter
    def revision_target(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "revisionTarget", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="rotateEncryptionKey")
    def rotate_encryption_key(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.RotateEncryptionKey``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-rotateencryptionkey
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "rotateEncryptionKey"))

    @rotate_encryption_key.setter
    def rotate_encryption_key(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "rotateEncryptionKey", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snapshotClusterIdentifier")
    def snapshot_cluster_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.SnapshotClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotclusteridentifier
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "snapshotClusterIdentifier"))

    @snapshot_cluster_identifier.setter
    def snapshot_cluster_identifier(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "snapshotClusterIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snapshotCopyGrantName")
    def snapshot_copy_grant_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.SnapshotCopyGrantName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotcopygrantname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "snapshotCopyGrantName"))

    @snapshot_copy_grant_name.setter
    def snapshot_copy_grant_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "snapshotCopyGrantName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snapshotCopyManual")
    def snapshot_copy_manual(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.SnapshotCopyManual``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotcopymanual
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "snapshotCopyManual"))

    @snapshot_copy_manual.setter
    def snapshot_copy_manual(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "snapshotCopyManual", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snapshotCopyRetentionPeriod")
    def snapshot_copy_retention_period(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.SnapshotCopyRetentionPeriod``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotcopyretentionperiod
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "snapshotCopyRetentionPeriod"))

    @snapshot_copy_retention_period.setter
    def snapshot_copy_retention_period(
        self,
        value: typing.Optional[jsii.Number],
    ) -> None:
        jsii.set(self, "snapshotCopyRetentionPeriod", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snapshotIdentifier")
    def snapshot_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.SnapshotIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotidentifier
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "snapshotIdentifier"))

    @snapshot_identifier.setter
    def snapshot_identifier(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "snapshotIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::Redshift::Cluster.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcSecurityGroupIds")
    def vpc_security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::Cluster.VpcSecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-vpcsecuritygroupids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "vpcSecurityGroupIds"))

    @vpc_security_group_ids.setter
    def vpc_security_group_ids(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "vpcSecurityGroupIds", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnCluster.EndpointProperty",
        jsii_struct_bases=[],
        name_mapping={"address": "address", "port": "port"},
    )
    class EndpointProperty:
        def __init__(
            self,
            *,
            address: typing.Optional[builtins.str] = None,
            port: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param address: ``CfnCluster.EndpointProperty.Address``.
            :param port: ``CfnCluster.EndpointProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-endpoint.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                endpoint_property = redshift.CfnCluster.EndpointProperty(
                    address="address",
                    port="port"
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if address is not None:
                self._values["address"] = address
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def address(self) -> typing.Optional[builtins.str]:
            '''``CfnCluster.EndpointProperty.Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-endpoint.html#cfn-redshift-cluster-endpoint-address
            '''
            result = self._values.get("address")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def port(self) -> typing.Optional[builtins.str]:
            '''``CfnCluster.EndpointProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-endpoint.html#cfn-redshift-cluster-endpoint-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EndpointProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnCluster.LoggingPropertiesProperty",
        jsii_struct_bases=[],
        name_mapping={"bucket_name": "bucketName", "s3_key_prefix": "s3KeyPrefix"},
    )
    class LoggingPropertiesProperty:
        def __init__(
            self,
            *,
            bucket_name: builtins.str,
            s3_key_prefix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param bucket_name: ``CfnCluster.LoggingPropertiesProperty.BucketName``.
            :param s3_key_prefix: ``CfnCluster.LoggingPropertiesProperty.S3KeyPrefix``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-loggingproperties.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                logging_properties_property = redshift.CfnCluster.LoggingPropertiesProperty(
                    bucket_name="bucketName",
                
                    # the properties below are optional
                    s3_key_prefix="s3KeyPrefix"
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "bucket_name": bucket_name,
            }
            if s3_key_prefix is not None:
                self._values["s3_key_prefix"] = s3_key_prefix

        @builtins.property
        def bucket_name(self) -> builtins.str:
            '''``CfnCluster.LoggingPropertiesProperty.BucketName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-loggingproperties.html#cfn-redshift-cluster-loggingproperties-bucketname
            '''
            result = self._values.get("bucket_name")
            assert result is not None, "Required property 'bucket_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def s3_key_prefix(self) -> typing.Optional[builtins.str]:
            '''``CfnCluster.LoggingPropertiesProperty.S3KeyPrefix``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-cluster-loggingproperties.html#cfn-redshift-cluster-loggingproperties-s3keyprefix
            '''
            result = self._values.get("s3_key_prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoggingPropertiesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClusterParameterGroup(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnClusterParameterGroup",
):
    '''A CloudFormation ``AWS::Redshift::ClusterParameterGroup``.

    :cloudformationResource: AWS::Redshift::ClusterParameterGroup
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_cluster_parameter_group = redshift.CfnClusterParameterGroup(self, "MyCfnClusterParameterGroup",
            description="description",
            parameter_group_family="parameterGroupFamily",
        
            # the properties below are optional
            parameters=[redshift.CfnClusterParameterGroup.ParameterProperty(
                parameter_name="parameterName",
                parameter_value="parameterValue"
            )],
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        description: builtins.str,
        parameter_group_family: builtins.str,
        parameters: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnClusterParameterGroup.ParameterProperty"]]]] = None,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::ClusterParameterGroup``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param description: ``AWS::Redshift::ClusterParameterGroup.Description``.
        :param parameter_group_family: ``AWS::Redshift::ClusterParameterGroup.ParameterGroupFamily``.
        :param parameters: ``AWS::Redshift::ClusterParameterGroup.Parameters``.
        :param tags: ``AWS::Redshift::ClusterParameterGroup.Tags``.
        '''
        props = CfnClusterParameterGroupProps(
            description=description,
            parameter_group_family=parameter_group_family,
            parameters=parameters,
            tags=tags,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> builtins.str:
        '''``AWS::Redshift::ClusterParameterGroup.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-description
        '''
        return typing.cast(builtins.str, jsii.get(self, "description"))

    @description.setter
    def description(self, value: builtins.str) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="parameterGroupFamily")
    def parameter_group_family(self) -> builtins.str:
        '''``AWS::Redshift::ClusterParameterGroup.ParameterGroupFamily``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-parametergroupfamily
        '''
        return typing.cast(builtins.str, jsii.get(self, "parameterGroupFamily"))

    @parameter_group_family.setter
    def parameter_group_family(self, value: builtins.str) -> None:
        jsii.set(self, "parameterGroupFamily", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="parameters")
    def parameters(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClusterParameterGroup.ParameterProperty"]]]]:
        '''``AWS::Redshift::ClusterParameterGroup.Parameters``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-parameters
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClusterParameterGroup.ParameterProperty"]]]], jsii.get(self, "parameters"))

    @parameters.setter
    def parameters(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClusterParameterGroup.ParameterProperty"]]]],
    ) -> None:
        jsii.set(self, "parameters", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::Redshift::ClusterParameterGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnClusterParameterGroup.ParameterProperty",
        jsii_struct_bases=[],
        name_mapping={
            "parameter_name": "parameterName",
            "parameter_value": "parameterValue",
        },
    )
    class ParameterProperty:
        def __init__(
            self,
            *,
            parameter_name: builtins.str,
            parameter_value: builtins.str,
        ) -> None:
            '''
            :param parameter_name: ``CfnClusterParameterGroup.ParameterProperty.ParameterName``.
            :param parameter_value: ``CfnClusterParameterGroup.ParameterProperty.ParameterValue``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-property-redshift-clusterparametergroup-parameter.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                parameter_property = redshift.CfnClusterParameterGroup.ParameterProperty(
                    parameter_name="parameterName",
                    parameter_value="parameterValue"
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "parameter_name": parameter_name,
                "parameter_value": parameter_value,
            }

        @builtins.property
        def parameter_name(self) -> builtins.str:
            '''``CfnClusterParameterGroup.ParameterProperty.ParameterName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-property-redshift-clusterparametergroup-parameter.html#cfn-redshift-clusterparametergroup-parameter-parametername
            '''
            result = self._values.get("parameter_name")
            assert result is not None, "Required property 'parameter_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def parameter_value(self) -> builtins.str:
            '''``CfnClusterParameterGroup.ParameterProperty.ParameterValue``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-property-redshift-clusterparametergroup-parameter.html#cfn-redshift-clusterparametergroup-parameter-parametervalue
            '''
            result = self._values.get("parameter_value")
            assert result is not None, "Required property 'parameter_value' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ParameterProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnClusterParameterGroupProps",
    jsii_struct_bases=[],
    name_mapping={
        "description": "description",
        "parameter_group_family": "parameterGroupFamily",
        "parameters": "parameters",
        "tags": "tags",
    },
)
class CfnClusterParameterGroupProps:
    def __init__(
        self,
        *,
        description: builtins.str,
        parameter_group_family: builtins.str,
        parameters: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, CfnClusterParameterGroup.ParameterProperty]]]] = None,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::ClusterParameterGroup``.

        :param description: ``AWS::Redshift::ClusterParameterGroup.Description``.
        :param parameter_group_family: ``AWS::Redshift::ClusterParameterGroup.ParameterGroupFamily``.
        :param parameters: ``AWS::Redshift::ClusterParameterGroup.Parameters``.
        :param tags: ``AWS::Redshift::ClusterParameterGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_cluster_parameter_group_props = redshift.CfnClusterParameterGroupProps(
                description="description",
                parameter_group_family="parameterGroupFamily",
            
                # the properties below are optional
                parameters=[redshift.CfnClusterParameterGroup.ParameterProperty(
                    parameter_name="parameterName",
                    parameter_value="parameterValue"
                )],
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "description": description,
            "parameter_group_family": parameter_group_family,
        }
        if parameters is not None:
            self._values["parameters"] = parameters
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def description(self) -> builtins.str:
        '''``AWS::Redshift::ClusterParameterGroup.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-description
        '''
        result = self._values.get("description")
        assert result is not None, "Required property 'description' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def parameter_group_family(self) -> builtins.str:
        '''``AWS::Redshift::ClusterParameterGroup.ParameterGroupFamily``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-parametergroupfamily
        '''
        result = self._values.get("parameter_group_family")
        assert result is not None, "Required property 'parameter_group_family' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def parameters(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnClusterParameterGroup.ParameterProperty]]]]:
        '''``AWS::Redshift::ClusterParameterGroup.Parameters``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-parameters
        '''
        result = self._values.get("parameters")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnClusterParameterGroup.ParameterProperty]]]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::Redshift::ClusterParameterGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html#cfn-redshift-clusterparametergroup-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClusterParameterGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnClusterProps",
    jsii_struct_bases=[],
    name_mapping={
        "allow_version_upgrade": "allowVersionUpgrade",
        "aqua_configuration_status": "aquaConfigurationStatus",
        "automated_snapshot_retention_period": "automatedSnapshotRetentionPeriod",
        "availability_zone": "availabilityZone",
        "availability_zone_relocation": "availabilityZoneRelocation",
        "availability_zone_relocation_status": "availabilityZoneRelocationStatus",
        "classic": "classic",
        "cluster_identifier": "clusterIdentifier",
        "cluster_parameter_group_name": "clusterParameterGroupName",
        "cluster_security_groups": "clusterSecurityGroups",
        "cluster_subnet_group_name": "clusterSubnetGroupName",
        "cluster_type": "clusterType",
        "cluster_version": "clusterVersion",
        "db_name": "dbName",
        "defer_maintenance": "deferMaintenance",
        "defer_maintenance_duration": "deferMaintenanceDuration",
        "defer_maintenance_end_time": "deferMaintenanceEndTime",
        "defer_maintenance_start_time": "deferMaintenanceStartTime",
        "destination_region": "destinationRegion",
        "elastic_ip": "elasticIp",
        "encrypted": "encrypted",
        "enhanced_vpc_routing": "enhancedVpcRouting",
        "hsm_client_certificate_identifier": "hsmClientCertificateIdentifier",
        "hsm_configuration_identifier": "hsmConfigurationIdentifier",
        "iam_roles": "iamRoles",
        "kms_key_id": "kmsKeyId",
        "logging_properties": "loggingProperties",
        "maintenance_track_name": "maintenanceTrackName",
        "manual_snapshot_retention_period": "manualSnapshotRetentionPeriod",
        "master_username": "masterUsername",
        "master_user_password": "masterUserPassword",
        "node_type": "nodeType",
        "number_of_nodes": "numberOfNodes",
        "owner_account": "ownerAccount",
        "port": "port",
        "preferred_maintenance_window": "preferredMaintenanceWindow",
        "publicly_accessible": "publiclyAccessible",
        "resource_action": "resourceAction",
        "revision_target": "revisionTarget",
        "rotate_encryption_key": "rotateEncryptionKey",
        "snapshot_cluster_identifier": "snapshotClusterIdentifier",
        "snapshot_copy_grant_name": "snapshotCopyGrantName",
        "snapshot_copy_manual": "snapshotCopyManual",
        "snapshot_copy_retention_period": "snapshotCopyRetentionPeriod",
        "snapshot_identifier": "snapshotIdentifier",
        "tags": "tags",
        "vpc_security_group_ids": "vpcSecurityGroupIds",
    },
)
class CfnClusterProps:
    def __init__(
        self,
        *,
        allow_version_upgrade: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        aqua_configuration_status: typing.Optional[builtins.str] = None,
        automated_snapshot_retention_period: typing.Optional[jsii.Number] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        availability_zone_relocation: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        availability_zone_relocation_status: typing.Optional[builtins.str] = None,
        classic: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        cluster_identifier: typing.Optional[builtins.str] = None,
        cluster_parameter_group_name: typing.Optional[builtins.str] = None,
        cluster_security_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
        cluster_subnet_group_name: typing.Optional[builtins.str] = None,
        cluster_type: builtins.str,
        cluster_version: typing.Optional[builtins.str] = None,
        db_name: builtins.str,
        defer_maintenance: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        defer_maintenance_duration: typing.Optional[jsii.Number] = None,
        defer_maintenance_end_time: typing.Optional[builtins.str] = None,
        defer_maintenance_start_time: typing.Optional[builtins.str] = None,
        destination_region: typing.Optional[builtins.str] = None,
        elastic_ip: typing.Optional[builtins.str] = None,
        encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        enhanced_vpc_routing: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        hsm_client_certificate_identifier: typing.Optional[builtins.str] = None,
        hsm_configuration_identifier: typing.Optional[builtins.str] = None,
        iam_roles: typing.Optional[typing.Sequence[builtins.str]] = None,
        kms_key_id: typing.Optional[builtins.str] = None,
        logging_properties: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnCluster.LoggingPropertiesProperty]] = None,
        maintenance_track_name: typing.Optional[builtins.str] = None,
        manual_snapshot_retention_period: typing.Optional[jsii.Number] = None,
        master_username: builtins.str,
        master_user_password: builtins.str,
        node_type: builtins.str,
        number_of_nodes: typing.Optional[jsii.Number] = None,
        owner_account: typing.Optional[builtins.str] = None,
        port: typing.Optional[jsii.Number] = None,
        preferred_maintenance_window: typing.Optional[builtins.str] = None,
        publicly_accessible: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        resource_action: typing.Optional[builtins.str] = None,
        revision_target: typing.Optional[builtins.str] = None,
        rotate_encryption_key: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        snapshot_cluster_identifier: typing.Optional[builtins.str] = None,
        snapshot_copy_grant_name: typing.Optional[builtins.str] = None,
        snapshot_copy_manual: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        snapshot_copy_retention_period: typing.Optional[jsii.Number] = None,
        snapshot_identifier: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
        vpc_security_group_ids: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::Cluster``.

        :param allow_version_upgrade: ``AWS::Redshift::Cluster.AllowVersionUpgrade``.
        :param aqua_configuration_status: ``AWS::Redshift::Cluster.AquaConfigurationStatus``.
        :param automated_snapshot_retention_period: ``AWS::Redshift::Cluster.AutomatedSnapshotRetentionPeriod``.
        :param availability_zone: ``AWS::Redshift::Cluster.AvailabilityZone``.
        :param availability_zone_relocation: ``AWS::Redshift::Cluster.AvailabilityZoneRelocation``.
        :param availability_zone_relocation_status: ``AWS::Redshift::Cluster.AvailabilityZoneRelocationStatus``.
        :param classic: ``AWS::Redshift::Cluster.Classic``.
        :param cluster_identifier: ``AWS::Redshift::Cluster.ClusterIdentifier``.
        :param cluster_parameter_group_name: ``AWS::Redshift::Cluster.ClusterParameterGroupName``.
        :param cluster_security_groups: ``AWS::Redshift::Cluster.ClusterSecurityGroups``.
        :param cluster_subnet_group_name: ``AWS::Redshift::Cluster.ClusterSubnetGroupName``.
        :param cluster_type: ``AWS::Redshift::Cluster.ClusterType``.
        :param cluster_version: ``AWS::Redshift::Cluster.ClusterVersion``.
        :param db_name: ``AWS::Redshift::Cluster.DBName``.
        :param defer_maintenance: ``AWS::Redshift::Cluster.DeferMaintenance``.
        :param defer_maintenance_duration: ``AWS::Redshift::Cluster.DeferMaintenanceDuration``.
        :param defer_maintenance_end_time: ``AWS::Redshift::Cluster.DeferMaintenanceEndTime``.
        :param defer_maintenance_start_time: ``AWS::Redshift::Cluster.DeferMaintenanceStartTime``.
        :param destination_region: ``AWS::Redshift::Cluster.DestinationRegion``.
        :param elastic_ip: ``AWS::Redshift::Cluster.ElasticIp``.
        :param encrypted: ``AWS::Redshift::Cluster.Encrypted``.
        :param enhanced_vpc_routing: ``AWS::Redshift::Cluster.EnhancedVpcRouting``.
        :param hsm_client_certificate_identifier: ``AWS::Redshift::Cluster.HsmClientCertificateIdentifier``.
        :param hsm_configuration_identifier: ``AWS::Redshift::Cluster.HsmConfigurationIdentifier``.
        :param iam_roles: ``AWS::Redshift::Cluster.IamRoles``.
        :param kms_key_id: ``AWS::Redshift::Cluster.KmsKeyId``.
        :param logging_properties: ``AWS::Redshift::Cluster.LoggingProperties``.
        :param maintenance_track_name: ``AWS::Redshift::Cluster.MaintenanceTrackName``.
        :param manual_snapshot_retention_period: ``AWS::Redshift::Cluster.ManualSnapshotRetentionPeriod``.
        :param master_username: ``AWS::Redshift::Cluster.MasterUsername``.
        :param master_user_password: ``AWS::Redshift::Cluster.MasterUserPassword``.
        :param node_type: ``AWS::Redshift::Cluster.NodeType``.
        :param number_of_nodes: ``AWS::Redshift::Cluster.NumberOfNodes``.
        :param owner_account: ``AWS::Redshift::Cluster.OwnerAccount``.
        :param port: ``AWS::Redshift::Cluster.Port``.
        :param preferred_maintenance_window: ``AWS::Redshift::Cluster.PreferredMaintenanceWindow``.
        :param publicly_accessible: ``AWS::Redshift::Cluster.PubliclyAccessible``.
        :param resource_action: ``AWS::Redshift::Cluster.ResourceAction``.
        :param revision_target: ``AWS::Redshift::Cluster.RevisionTarget``.
        :param rotate_encryption_key: ``AWS::Redshift::Cluster.RotateEncryptionKey``.
        :param snapshot_cluster_identifier: ``AWS::Redshift::Cluster.SnapshotClusterIdentifier``.
        :param snapshot_copy_grant_name: ``AWS::Redshift::Cluster.SnapshotCopyGrantName``.
        :param snapshot_copy_manual: ``AWS::Redshift::Cluster.SnapshotCopyManual``.
        :param snapshot_copy_retention_period: ``AWS::Redshift::Cluster.SnapshotCopyRetentionPeriod``.
        :param snapshot_identifier: ``AWS::Redshift::Cluster.SnapshotIdentifier``.
        :param tags: ``AWS::Redshift::Cluster.Tags``.
        :param vpc_security_group_ids: ``AWS::Redshift::Cluster.VpcSecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_cluster_props = redshift.CfnClusterProps(
                cluster_type="clusterType",
                db_name="dbName",
                master_username="masterUsername",
                master_user_password="masterUserPassword",
                node_type="nodeType",
            
                # the properties below are optional
                allow_version_upgrade=False,
                aqua_configuration_status="aquaConfigurationStatus",
                automated_snapshot_retention_period=123,
                availability_zone="availabilityZone",
                availability_zone_relocation=False,
                availability_zone_relocation_status="availabilityZoneRelocationStatus",
                classic=False,
                cluster_identifier="clusterIdentifier",
                cluster_parameter_group_name="clusterParameterGroupName",
                cluster_security_groups=["clusterSecurityGroups"],
                cluster_subnet_group_name="clusterSubnetGroupName",
                cluster_version="clusterVersion",
                defer_maintenance=False,
                defer_maintenance_duration=123,
                defer_maintenance_end_time="deferMaintenanceEndTime",
                defer_maintenance_start_time="deferMaintenanceStartTime",
                destination_region="destinationRegion",
                elastic_ip="elasticIp",
                encrypted=False,
                enhanced_vpc_routing=False,
                hsm_client_certificate_identifier="hsmClientCertificateIdentifier",
                hsm_configuration_identifier="hsmConfigurationIdentifier",
                iam_roles=["iamRoles"],
                kms_key_id="kmsKeyId",
                logging_properties=redshift.CfnCluster.LoggingPropertiesProperty(
                    bucket_name="bucketName",
            
                    # the properties below are optional
                    s3_key_prefix="s3KeyPrefix"
                ),
                maintenance_track_name="maintenanceTrackName",
                manual_snapshot_retention_period=123,
                number_of_nodes=123,
                owner_account="ownerAccount",
                port=123,
                preferred_maintenance_window="preferredMaintenanceWindow",
                publicly_accessible=False,
                resource_action="resourceAction",
                revision_target="revisionTarget",
                rotate_encryption_key=False,
                snapshot_cluster_identifier="snapshotClusterIdentifier",
                snapshot_copy_grant_name="snapshotCopyGrantName",
                snapshot_copy_manual=False,
                snapshot_copy_retention_period=123,
                snapshot_identifier="snapshotIdentifier",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )],
                vpc_security_group_ids=["vpcSecurityGroupIds"]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster_type": cluster_type,
            "db_name": db_name,
            "master_username": master_username,
            "master_user_password": master_user_password,
            "node_type": node_type,
        }
        if allow_version_upgrade is not None:
            self._values["allow_version_upgrade"] = allow_version_upgrade
        if aqua_configuration_status is not None:
            self._values["aqua_configuration_status"] = aqua_configuration_status
        if automated_snapshot_retention_period is not None:
            self._values["automated_snapshot_retention_period"] = automated_snapshot_retention_period
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if availability_zone_relocation is not None:
            self._values["availability_zone_relocation"] = availability_zone_relocation
        if availability_zone_relocation_status is not None:
            self._values["availability_zone_relocation_status"] = availability_zone_relocation_status
        if classic is not None:
            self._values["classic"] = classic
        if cluster_identifier is not None:
            self._values["cluster_identifier"] = cluster_identifier
        if cluster_parameter_group_name is not None:
            self._values["cluster_parameter_group_name"] = cluster_parameter_group_name
        if cluster_security_groups is not None:
            self._values["cluster_security_groups"] = cluster_security_groups
        if cluster_subnet_group_name is not None:
            self._values["cluster_subnet_group_name"] = cluster_subnet_group_name
        if cluster_version is not None:
            self._values["cluster_version"] = cluster_version
        if defer_maintenance is not None:
            self._values["defer_maintenance"] = defer_maintenance
        if defer_maintenance_duration is not None:
            self._values["defer_maintenance_duration"] = defer_maintenance_duration
        if defer_maintenance_end_time is not None:
            self._values["defer_maintenance_end_time"] = defer_maintenance_end_time
        if defer_maintenance_start_time is not None:
            self._values["defer_maintenance_start_time"] = defer_maintenance_start_time
        if destination_region is not None:
            self._values["destination_region"] = destination_region
        if elastic_ip is not None:
            self._values["elastic_ip"] = elastic_ip
        if encrypted is not None:
            self._values["encrypted"] = encrypted
        if enhanced_vpc_routing is not None:
            self._values["enhanced_vpc_routing"] = enhanced_vpc_routing
        if hsm_client_certificate_identifier is not None:
            self._values["hsm_client_certificate_identifier"] = hsm_client_certificate_identifier
        if hsm_configuration_identifier is not None:
            self._values["hsm_configuration_identifier"] = hsm_configuration_identifier
        if iam_roles is not None:
            self._values["iam_roles"] = iam_roles
        if kms_key_id is not None:
            self._values["kms_key_id"] = kms_key_id
        if logging_properties is not None:
            self._values["logging_properties"] = logging_properties
        if maintenance_track_name is not None:
            self._values["maintenance_track_name"] = maintenance_track_name
        if manual_snapshot_retention_period is not None:
            self._values["manual_snapshot_retention_period"] = manual_snapshot_retention_period
        if number_of_nodes is not None:
            self._values["number_of_nodes"] = number_of_nodes
        if owner_account is not None:
            self._values["owner_account"] = owner_account
        if port is not None:
            self._values["port"] = port
        if preferred_maintenance_window is not None:
            self._values["preferred_maintenance_window"] = preferred_maintenance_window
        if publicly_accessible is not None:
            self._values["publicly_accessible"] = publicly_accessible
        if resource_action is not None:
            self._values["resource_action"] = resource_action
        if revision_target is not None:
            self._values["revision_target"] = revision_target
        if rotate_encryption_key is not None:
            self._values["rotate_encryption_key"] = rotate_encryption_key
        if snapshot_cluster_identifier is not None:
            self._values["snapshot_cluster_identifier"] = snapshot_cluster_identifier
        if snapshot_copy_grant_name is not None:
            self._values["snapshot_copy_grant_name"] = snapshot_copy_grant_name
        if snapshot_copy_manual is not None:
            self._values["snapshot_copy_manual"] = snapshot_copy_manual
        if snapshot_copy_retention_period is not None:
            self._values["snapshot_copy_retention_period"] = snapshot_copy_retention_period
        if snapshot_identifier is not None:
            self._values["snapshot_identifier"] = snapshot_identifier
        if tags is not None:
            self._values["tags"] = tags
        if vpc_security_group_ids is not None:
            self._values["vpc_security_group_ids"] = vpc_security_group_ids

    @builtins.property
    def allow_version_upgrade(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.AllowVersionUpgrade``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-allowversionupgrade
        '''
        result = self._values.get("allow_version_upgrade")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def aqua_configuration_status(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.AquaConfigurationStatus``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-aquaconfigurationstatus
        '''
        result = self._values.get("aqua_configuration_status")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def automated_snapshot_retention_period(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.AutomatedSnapshotRetentionPeriod``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-automatedsnapshotretentionperiod
        '''
        result = self._values.get("automated_snapshot_retention_period")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzone
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def availability_zone_relocation(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.AvailabilityZoneRelocation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzonerelocation
        '''
        result = self._values.get("availability_zone_relocation")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def availability_zone_relocation_status(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.AvailabilityZoneRelocationStatus``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzonerelocationstatus
        '''
        result = self._values.get("availability_zone_relocation_status")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def classic(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.Classic``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-classic
        '''
        result = self._values.get("classic")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def cluster_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clusteridentifier
        '''
        result = self._values.get("cluster_identifier")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cluster_parameter_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterParameterGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clusterparametergroupname
        '''
        result = self._values.get("cluster_parameter_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cluster_security_groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::Cluster.ClusterSecurityGroups``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clustersecuritygroups
        '''
        result = self._values.get("cluster_security_groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def cluster_subnet_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterSubnetGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clustersubnetgroupname
        '''
        result = self._values.get("cluster_subnet_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cluster_type(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.ClusterType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clustertype
        '''
        result = self._values.get("cluster_type")
        assert result is not None, "Required property 'cluster_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cluster_version(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ClusterVersion``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-clusterversion
        '''
        result = self._values.get("cluster_version")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def db_name(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.DBName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-dbname
        '''
        result = self._values.get("db_name")
        assert result is not None, "Required property 'db_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def defer_maintenance(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.DeferMaintenance``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenance
        '''
        result = self._values.get("defer_maintenance")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def defer_maintenance_duration(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.DeferMaintenanceDuration``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenanceduration
        '''
        result = self._values.get("defer_maintenance_duration")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def defer_maintenance_end_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.DeferMaintenanceEndTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenanceendtime
        '''
        result = self._values.get("defer_maintenance_end_time")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def defer_maintenance_start_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.DeferMaintenanceStartTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-defermaintenancestarttime
        '''
        result = self._values.get("defer_maintenance_start_time")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_region(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.DestinationRegion``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-destinationregion
        '''
        result = self._values.get("destination_region")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def elastic_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ElasticIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-elasticip
        '''
        result = self._values.get("elastic_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def encrypted(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.Encrypted``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-encrypted
        '''
        result = self._values.get("encrypted")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def enhanced_vpc_routing(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.EnhancedVpcRouting``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-enhancedvpcrouting
        '''
        result = self._values.get("enhanced_vpc_routing")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def hsm_client_certificate_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.HsmClientCertificateIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-hsmclientcertificateidentifier
        '''
        result = self._values.get("hsm_client_certificate_identifier")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def hsm_configuration_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.HsmConfigurationIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-hsmconfigurationidentifier
        '''
        result = self._values.get("hsm_configuration_identifier")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def iam_roles(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::Cluster.IamRoles``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-iamroles
        '''
        result = self._values.get("iam_roles")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def kms_key_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.KmsKeyId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-kmskeyid
        '''
        result = self._values.get("kms_key_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def logging_properties(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnCluster.LoggingPropertiesProperty]]:
        '''``AWS::Redshift::Cluster.LoggingProperties``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-loggingproperties
        '''
        result = self._values.get("logging_properties")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnCluster.LoggingPropertiesProperty]], result)

    @builtins.property
    def maintenance_track_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.MaintenanceTrackName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-maintenancetrackname
        '''
        result = self._values.get("maintenance_track_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def manual_snapshot_retention_period(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.ManualSnapshotRetentionPeriod``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-manualsnapshotretentionperiod
        '''
        result = self._values.get("manual_snapshot_retention_period")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def master_username(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.MasterUsername``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-masterusername
        '''
        result = self._values.get("master_username")
        assert result is not None, "Required property 'master_username' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def master_user_password(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.MasterUserPassword``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-masteruserpassword
        '''
        result = self._values.get("master_user_password")
        assert result is not None, "Required property 'master_user_password' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def node_type(self) -> builtins.str:
        '''``AWS::Redshift::Cluster.NodeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-nodetype
        '''
        result = self._values.get("node_type")
        assert result is not None, "Required property 'node_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def number_of_nodes(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.NumberOfNodes``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-numberofnodes
        '''
        result = self._values.get("number_of_nodes")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def owner_account(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.OwnerAccount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-owneraccount
        '''
        result = self._values.get("owner_account")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.Port``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-port
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def preferred_maintenance_window(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.PreferredMaintenanceWindow``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-preferredmaintenancewindow
        '''
        result = self._values.get("preferred_maintenance_window")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def publicly_accessible(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.PubliclyAccessible``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-publiclyaccessible
        '''
        result = self._values.get("publicly_accessible")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def resource_action(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.ResourceAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-resourceaction
        '''
        result = self._values.get("resource_action")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def revision_target(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.RevisionTarget``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-revisiontarget
        '''
        result = self._values.get("revision_target")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def rotate_encryption_key(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.RotateEncryptionKey``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-rotateencryptionkey
        '''
        result = self._values.get("rotate_encryption_key")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def snapshot_cluster_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.SnapshotClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotclusteridentifier
        '''
        result = self._values.get("snapshot_cluster_identifier")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def snapshot_copy_grant_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.SnapshotCopyGrantName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotcopygrantname
        '''
        result = self._values.get("snapshot_copy_grant_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def snapshot_copy_manual(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::Cluster.SnapshotCopyManual``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotcopymanual
        '''
        result = self._values.get("snapshot_copy_manual")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def snapshot_copy_retention_period(self) -> typing.Optional[jsii.Number]:
        '''``AWS::Redshift::Cluster.SnapshotCopyRetentionPeriod``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotcopyretentionperiod
        '''
        result = self._values.get("snapshot_copy_retention_period")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def snapshot_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::Cluster.SnapshotIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-snapshotidentifier
        '''
        result = self._values.get("snapshot_identifier")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::Redshift::Cluster.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def vpc_security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::Cluster.VpcSecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-vpcsecuritygroupids
        '''
        result = self._values.get("vpc_security_group_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClusterProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClusterSecurityGroup(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnClusterSecurityGroup",
):
    '''A CloudFormation ``AWS::Redshift::ClusterSecurityGroup``.

    :cloudformationResource: AWS::Redshift::ClusterSecurityGroup
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_cluster_security_group = redshift.CfnClusterSecurityGroup(self, "MyCfnClusterSecurityGroup",
            description="description",
        
            # the properties below are optional
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        description: builtins.str,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::ClusterSecurityGroup``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param description: ``AWS::Redshift::ClusterSecurityGroup.Description``.
        :param tags: ``AWS::Redshift::ClusterSecurityGroup.Tags``.
        '''
        props = CfnClusterSecurityGroupProps(description=description, tags=tags)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> builtins.str:
        '''``AWS::Redshift::ClusterSecurityGroup.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html#cfn-redshift-clustersecuritygroup-description
        '''
        return typing.cast(builtins.str, jsii.get(self, "description"))

    @description.setter
    def description(self, value: builtins.str) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::Redshift::ClusterSecurityGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html#cfn-redshift-clustersecuritygroup-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClusterSecurityGroupIngress(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnClusterSecurityGroupIngress",
):
    '''A CloudFormation ``AWS::Redshift::ClusterSecurityGroupIngress``.

    :cloudformationResource: AWS::Redshift::ClusterSecurityGroupIngress
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_cluster_security_group_ingress = redshift.CfnClusterSecurityGroupIngress(self, "MyCfnClusterSecurityGroupIngress",
            cluster_security_group_name="clusterSecurityGroupName",
        
            # the properties below are optional
            cidrip="cidrip",
            ec2_security_group_name="ec2SecurityGroupName",
            ec2_security_group_owner_id="ec2SecurityGroupOwnerId"
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        cidrip: typing.Optional[builtins.str] = None,
        cluster_security_group_name: builtins.str,
        ec2_security_group_name: typing.Optional[builtins.str] = None,
        ec2_security_group_owner_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::ClusterSecurityGroupIngress``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param cidrip: ``AWS::Redshift::ClusterSecurityGroupIngress.CIDRIP``.
        :param cluster_security_group_name: ``AWS::Redshift::ClusterSecurityGroupIngress.ClusterSecurityGroupName``.
        :param ec2_security_group_name: ``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupName``.
        :param ec2_security_group_owner_id: ``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupOwnerId``.
        '''
        props = CfnClusterSecurityGroupIngressProps(
            cidrip=cidrip,
            cluster_security_group_name=cluster_security_group_name,
            ec2_security_group_name=ec2_security_group_name,
            ec2_security_group_owner_id=ec2_security_group_owner_id,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrip")
    def cidrip(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.CIDRIP``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-cidrip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrip"))

    @cidrip.setter
    def cidrip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrip", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterSecurityGroupName")
    def cluster_security_group_name(self) -> builtins.str:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.ClusterSecurityGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-clustersecuritygroupname
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterSecurityGroupName"))

    @cluster_security_group_name.setter
    def cluster_security_group_name(self, value: builtins.str) -> None:
        jsii.set(self, "clusterSecurityGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ec2SecurityGroupName")
    def ec2_security_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-ec2securitygroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "ec2SecurityGroupName"))

    @ec2_security_group_name.setter
    def ec2_security_group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "ec2SecurityGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ec2SecurityGroupOwnerId")
    def ec2_security_group_owner_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-ec2securitygroupownerid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "ec2SecurityGroupOwnerId"))

    @ec2_security_group_owner_id.setter
    def ec2_security_group_owner_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "ec2SecurityGroupOwnerId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnClusterSecurityGroupIngressProps",
    jsii_struct_bases=[],
    name_mapping={
        "cidrip": "cidrip",
        "cluster_security_group_name": "clusterSecurityGroupName",
        "ec2_security_group_name": "ec2SecurityGroupName",
        "ec2_security_group_owner_id": "ec2SecurityGroupOwnerId",
    },
)
class CfnClusterSecurityGroupIngressProps:
    def __init__(
        self,
        *,
        cidrip: typing.Optional[builtins.str] = None,
        cluster_security_group_name: builtins.str,
        ec2_security_group_name: typing.Optional[builtins.str] = None,
        ec2_security_group_owner_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::ClusterSecurityGroupIngress``.

        :param cidrip: ``AWS::Redshift::ClusterSecurityGroupIngress.CIDRIP``.
        :param cluster_security_group_name: ``AWS::Redshift::ClusterSecurityGroupIngress.ClusterSecurityGroupName``.
        :param ec2_security_group_name: ``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupName``.
        :param ec2_security_group_owner_id: ``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_cluster_security_group_ingress_props = redshift.CfnClusterSecurityGroupIngressProps(
                cluster_security_group_name="clusterSecurityGroupName",
            
                # the properties below are optional
                cidrip="cidrip",
                ec2_security_group_name="ec2SecurityGroupName",
                ec2_security_group_owner_id="ec2SecurityGroupOwnerId"
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster_security_group_name": cluster_security_group_name,
        }
        if cidrip is not None:
            self._values["cidrip"] = cidrip
        if ec2_security_group_name is not None:
            self._values["ec2_security_group_name"] = ec2_security_group_name
        if ec2_security_group_owner_id is not None:
            self._values["ec2_security_group_owner_id"] = ec2_security_group_owner_id

    @builtins.property
    def cidrip(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.CIDRIP``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-cidrip
        '''
        result = self._values.get("cidrip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cluster_security_group_name(self) -> builtins.str:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.ClusterSecurityGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-clustersecuritygroupname
        '''
        result = self._values.get("cluster_security_group_name")
        assert result is not None, "Required property 'cluster_security_group_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def ec2_security_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-ec2securitygroupname
        '''
        result = self._values.get("ec2_security_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ec2_security_group_owner_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ClusterSecurityGroupIngress.EC2SecurityGroupOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html#cfn-redshift-clustersecuritygroupingress-ec2securitygroupownerid
        '''
        result = self._values.get("ec2_security_group_owner_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClusterSecurityGroupIngressProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnClusterSecurityGroupProps",
    jsii_struct_bases=[],
    name_mapping={"description": "description", "tags": "tags"},
)
class CfnClusterSecurityGroupProps:
    def __init__(
        self,
        *,
        description: builtins.str,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::ClusterSecurityGroup``.

        :param description: ``AWS::Redshift::ClusterSecurityGroup.Description``.
        :param tags: ``AWS::Redshift::ClusterSecurityGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_cluster_security_group_props = redshift.CfnClusterSecurityGroupProps(
                description="description",
            
                # the properties below are optional
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "description": description,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def description(self) -> builtins.str:
        '''``AWS::Redshift::ClusterSecurityGroup.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html#cfn-redshift-clustersecuritygroup-description
        '''
        result = self._values.get("description")
        assert result is not None, "Required property 'description' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::Redshift::ClusterSecurityGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html#cfn-redshift-clustersecuritygroup-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClusterSecurityGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClusterSubnetGroup(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnClusterSubnetGroup",
):
    '''A CloudFormation ``AWS::Redshift::ClusterSubnetGroup``.

    :cloudformationResource: AWS::Redshift::ClusterSubnetGroup
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_cluster_subnet_group = redshift.CfnClusterSubnetGroup(self, "MyCfnClusterSubnetGroup",
            description="description",
            subnet_ids=["subnetIds"],
        
            # the properties below are optional
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        description: builtins.str,
        subnet_ids: typing.Sequence[builtins.str],
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::ClusterSubnetGroup``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param description: ``AWS::Redshift::ClusterSubnetGroup.Description``.
        :param subnet_ids: ``AWS::Redshift::ClusterSubnetGroup.SubnetIds``.
        :param tags: ``AWS::Redshift::ClusterSubnetGroup.Tags``.
        '''
        props = CfnClusterSubnetGroupProps(
            description=description, subnet_ids=subnet_ids, tags=tags
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> builtins.str:
        '''``AWS::Redshift::ClusterSubnetGroup.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html#cfn-redshift-clustersubnetgroup-description
        '''
        return typing.cast(builtins.str, jsii.get(self, "description"))

    @description.setter
    def description(self, value: builtins.str) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetIds")
    def subnet_ids(self) -> typing.List[builtins.str]:
        '''``AWS::Redshift::ClusterSubnetGroup.SubnetIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html#cfn-redshift-clustersubnetgroup-subnetids
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "subnetIds"))

    @subnet_ids.setter
    def subnet_ids(self, value: typing.List[builtins.str]) -> None:
        jsii.set(self, "subnetIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::Redshift::ClusterSubnetGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html#cfn-redshift-clustersubnetgroup-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnClusterSubnetGroupProps",
    jsii_struct_bases=[],
    name_mapping={
        "description": "description",
        "subnet_ids": "subnetIds",
        "tags": "tags",
    },
)
class CfnClusterSubnetGroupProps:
    def __init__(
        self,
        *,
        description: builtins.str,
        subnet_ids: typing.Sequence[builtins.str],
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::ClusterSubnetGroup``.

        :param description: ``AWS::Redshift::ClusterSubnetGroup.Description``.
        :param subnet_ids: ``AWS::Redshift::ClusterSubnetGroup.SubnetIds``.
        :param tags: ``AWS::Redshift::ClusterSubnetGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_cluster_subnet_group_props = redshift.CfnClusterSubnetGroupProps(
                description="description",
                subnet_ids=["subnetIds"],
            
                # the properties below are optional
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "description": description,
            "subnet_ids": subnet_ids,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def description(self) -> builtins.str:
        '''``AWS::Redshift::ClusterSubnetGroup.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html#cfn-redshift-clustersubnetgroup-description
        '''
        result = self._values.get("description")
        assert result is not None, "Required property 'description' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_ids(self) -> typing.List[builtins.str]:
        '''``AWS::Redshift::ClusterSubnetGroup.SubnetIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html#cfn-redshift-clustersubnetgroup-subnetids
        '''
        result = self._values.get("subnet_ids")
        assert result is not None, "Required property 'subnet_ids' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::Redshift::ClusterSubnetGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html#cfn-redshift-clustersubnetgroup-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClusterSubnetGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEndpointAccess(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnEndpointAccess",
):
    '''A CloudFormation ``AWS::Redshift::EndpointAccess``.

    :cloudformationResource: AWS::Redshift::EndpointAccess
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_endpoint_access = redshift.CfnEndpointAccess(self, "MyCfnEndpointAccess",
            endpoint_name="endpointName",
            vpc_security_group_ids=["vpcSecurityGroupIds"],
        
            # the properties below are optional
            cluster_identifier="clusterIdentifier",
            resource_owner="resourceOwner",
            subnet_group_name="subnetGroupName"
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        cluster_identifier: typing.Optional[builtins.str] = None,
        endpoint_name: builtins.str,
        resource_owner: typing.Optional[builtins.str] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        vpc_security_group_ids: typing.Sequence[builtins.str],
    ) -> None:
        '''Create a new ``AWS::Redshift::EndpointAccess``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param cluster_identifier: ``AWS::Redshift::EndpointAccess.ClusterIdentifier``.
        :param endpoint_name: ``AWS::Redshift::EndpointAccess.EndpointName``.
        :param resource_owner: ``AWS::Redshift::EndpointAccess.ResourceOwner``.
        :param subnet_group_name: ``AWS::Redshift::EndpointAccess.SubnetGroupName``.
        :param vpc_security_group_ids: ``AWS::Redshift::EndpointAccess.VpcSecurityGroupIds``.
        '''
        props = CfnEndpointAccessProps(
            cluster_identifier=cluster_identifier,
            endpoint_name=endpoint_name,
            resource_owner=resource_owner,
            subnet_group_name=subnet_group_name,
            vpc_security_group_ids=vpc_security_group_ids,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAddress")
    def attr_address(self) -> builtins.str:
        '''
        :cloudformationAttribute: Address
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAddress"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrEndpointCreateTime")
    def attr_endpoint_create_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: EndpointCreateTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrEndpointCreateTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrEndpointStatus")
    def attr_endpoint_status(self) -> builtins.str:
        '''
        :cloudformationAttribute: EndpointStatus
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrEndpointStatus"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPort")
    def attr_port(self) -> jsii.Number:
        '''
        :cloudformationAttribute: Port
        '''
        return typing.cast(jsii.Number, jsii.get(self, "attrPort"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrVpcSecurityGroups")
    def attr_vpc_security_groups(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: VpcSecurityGroups
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrVpcSecurityGroups"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterIdentifier")
    def cluster_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.ClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-clusteridentifier
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "clusterIdentifier"))

    @cluster_identifier.setter
    def cluster_identifier(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "clusterIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="endpointName")
    def endpoint_name(self) -> builtins.str:
        '''``AWS::Redshift::EndpointAccess.EndpointName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-endpointname
        '''
        return typing.cast(builtins.str, jsii.get(self, "endpointName"))

    @endpoint_name.setter
    def endpoint_name(self, value: builtins.str) -> None:
        jsii.set(self, "endpointName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceOwner")
    def resource_owner(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.ResourceOwner``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-resourceowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "resourceOwner"))

    @resource_owner.setter
    def resource_owner(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "resourceOwner", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetGroupName")
    def subnet_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.SubnetGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-subnetgroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "subnetGroupName"))

    @subnet_group_name.setter
    def subnet_group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "subnetGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcSecurityGroupIds")
    def vpc_security_group_ids(self) -> typing.List[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.VpcSecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-vpcsecuritygroupids
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcSecurityGroupIds"))

    @vpc_security_group_ids.setter
    def vpc_security_group_ids(self, value: typing.List[builtins.str]) -> None:
        jsii.set(self, "vpcSecurityGroupIds", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnEndpointAccess.VpcSecurityGroupProperty",
        jsii_struct_bases=[],
        name_mapping={
            "status": "status",
            "vpc_security_group_id": "vpcSecurityGroupId",
        },
    )
    class VpcSecurityGroupProperty:
        def __init__(
            self,
            *,
            status: typing.Optional[builtins.str] = None,
            vpc_security_group_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param status: ``CfnEndpointAccess.VpcSecurityGroupProperty.Status``.
            :param vpc_security_group_id: ``CfnEndpointAccess.VpcSecurityGroupProperty.VpcSecurityGroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                vpc_security_group_property = redshift.CfnEndpointAccess.VpcSecurityGroupProperty(
                    status="status",
                    vpc_security_group_id="vpcSecurityGroupId"
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if status is not None:
                self._values["status"] = status
            if vpc_security_group_id is not None:
                self._values["vpc_security_group_id"] = vpc_security_group_id

        @builtins.property
        def status(self) -> typing.Optional[builtins.str]:
            '''``CfnEndpointAccess.VpcSecurityGroupProperty.Status``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html#cfn-redshift-endpointaccess-vpcsecuritygroup-status
            '''
            result = self._values.get("status")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def vpc_security_group_id(self) -> typing.Optional[builtins.str]:
            '''``CfnEndpointAccess.VpcSecurityGroupProperty.VpcSecurityGroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html#cfn-redshift-endpointaccess-vpcsecuritygroup-vpcsecuritygroupid
            '''
            result = self._values.get("vpc_security_group_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VpcSecurityGroupProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnEndpointAccessProps",
    jsii_struct_bases=[],
    name_mapping={
        "cluster_identifier": "clusterIdentifier",
        "endpoint_name": "endpointName",
        "resource_owner": "resourceOwner",
        "subnet_group_name": "subnetGroupName",
        "vpc_security_group_ids": "vpcSecurityGroupIds",
    },
)
class CfnEndpointAccessProps:
    def __init__(
        self,
        *,
        cluster_identifier: typing.Optional[builtins.str] = None,
        endpoint_name: builtins.str,
        resource_owner: typing.Optional[builtins.str] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        vpc_security_group_ids: typing.Sequence[builtins.str],
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::EndpointAccess``.

        :param cluster_identifier: ``AWS::Redshift::EndpointAccess.ClusterIdentifier``.
        :param endpoint_name: ``AWS::Redshift::EndpointAccess.EndpointName``.
        :param resource_owner: ``AWS::Redshift::EndpointAccess.ResourceOwner``.
        :param subnet_group_name: ``AWS::Redshift::EndpointAccess.SubnetGroupName``.
        :param vpc_security_group_ids: ``AWS::Redshift::EndpointAccess.VpcSecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_endpoint_access_props = redshift.CfnEndpointAccessProps(
                endpoint_name="endpointName",
                vpc_security_group_ids=["vpcSecurityGroupIds"],
            
                # the properties below are optional
                cluster_identifier="clusterIdentifier",
                resource_owner="resourceOwner",
                subnet_group_name="subnetGroupName"
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "endpoint_name": endpoint_name,
            "vpc_security_group_ids": vpc_security_group_ids,
        }
        if cluster_identifier is not None:
            self._values["cluster_identifier"] = cluster_identifier
        if resource_owner is not None:
            self._values["resource_owner"] = resource_owner
        if subnet_group_name is not None:
            self._values["subnet_group_name"] = subnet_group_name

    @builtins.property
    def cluster_identifier(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.ClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-clusteridentifier
        '''
        result = self._values.get("cluster_identifier")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def endpoint_name(self) -> builtins.str:
        '''``AWS::Redshift::EndpointAccess.EndpointName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-endpointname
        '''
        result = self._values.get("endpoint_name")
        assert result is not None, "Required property 'endpoint_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def resource_owner(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.ResourceOwner``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-resourceowner
        '''
        result = self._values.get("resource_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subnet_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.SubnetGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-subnetgroupname
        '''
        result = self._values.get("subnet_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpc_security_group_ids(self) -> typing.List[builtins.str]:
        '''``AWS::Redshift::EndpointAccess.VpcSecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-vpcsecuritygroupids
        '''
        result = self._values.get("vpc_security_group_ids")
        assert result is not None, "Required property 'vpc_security_group_ids' is missing"
        return typing.cast(typing.List[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEndpointAccessProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEndpointAuthorization(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnEndpointAuthorization",
):
    '''A CloudFormation ``AWS::Redshift::EndpointAuthorization``.

    :cloudformationResource: AWS::Redshift::EndpointAuthorization
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_endpoint_authorization = redshift.CfnEndpointAuthorization(self, "MyCfnEndpointAuthorization",
            account="account",
            cluster_identifier="clusterIdentifier",
        
            # the properties below are optional
            force=False,
            vpc_ids=["vpcIds"]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        account: builtins.str,
        cluster_identifier: builtins.str,
        force: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        vpc_ids: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::EndpointAuthorization``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param account: ``AWS::Redshift::EndpointAuthorization.Account``.
        :param cluster_identifier: ``AWS::Redshift::EndpointAuthorization.ClusterIdentifier``.
        :param force: ``AWS::Redshift::EndpointAuthorization.Force``.
        :param vpc_ids: ``AWS::Redshift::EndpointAuthorization.VpcIds``.
        '''
        props = CfnEndpointAuthorizationProps(
            account=account,
            cluster_identifier=cluster_identifier,
            force=force,
            vpc_ids=vpc_ids,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="account")
    def account(self) -> builtins.str:
        '''``AWS::Redshift::EndpointAuthorization.Account``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-account
        '''
        return typing.cast(builtins.str, jsii.get(self, "account"))

    @account.setter
    def account(self, value: builtins.str) -> None:
        jsii.set(self, "account", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAllowedAllVpCs")
    def attr_allowed_all_vp_cs(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: AllowedAllVPCs
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrAllowedAllVpCs"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAllowedVpCs")
    def attr_allowed_vp_cs(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: AllowedVPCs
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrAllowedVpCs"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAuthorizeTime")
    def attr_authorize_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: AuthorizeTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAuthorizeTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrClusterStatus")
    def attr_cluster_status(self) -> builtins.str:
        '''
        :cloudformationAttribute: ClusterStatus
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrClusterStatus"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrEndpointCount")
    def attr_endpoint_count(self) -> jsii.Number:
        '''
        :cloudformationAttribute: EndpointCount
        '''
        return typing.cast(jsii.Number, jsii.get(self, "attrEndpointCount"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGrantee")
    def attr_grantee(self) -> builtins.str:
        '''
        :cloudformationAttribute: Grantee
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrGrantee"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGrantor")
    def attr_grantor(self) -> builtins.str:
        '''
        :cloudformationAttribute: Grantor
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrGrantor"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrStatus")
    def attr_status(self) -> builtins.str:
        '''
        :cloudformationAttribute: Status
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrStatus"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterIdentifier")
    def cluster_identifier(self) -> builtins.str:
        '''``AWS::Redshift::EndpointAuthorization.ClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-clusteridentifier
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterIdentifier"))

    @cluster_identifier.setter
    def cluster_identifier(self, value: builtins.str) -> None:
        jsii.set(self, "clusterIdentifier", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="force")
    def force(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::EndpointAuthorization.Force``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-force
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "force"))

    @force.setter
    def force(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "force", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcIds")
    def vpc_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::EndpointAuthorization.VpcIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-vpcids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "vpcIds"))

    @vpc_ids.setter
    def vpc_ids(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "vpcIds", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnEndpointAuthorizationProps",
    jsii_struct_bases=[],
    name_mapping={
        "account": "account",
        "cluster_identifier": "clusterIdentifier",
        "force": "force",
        "vpc_ids": "vpcIds",
    },
)
class CfnEndpointAuthorizationProps:
    def __init__(
        self,
        *,
        account: builtins.str,
        cluster_identifier: builtins.str,
        force: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        vpc_ids: typing.Optional[typing.Sequence[builtins.str]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::EndpointAuthorization``.

        :param account: ``AWS::Redshift::EndpointAuthorization.Account``.
        :param cluster_identifier: ``AWS::Redshift::EndpointAuthorization.ClusterIdentifier``.
        :param force: ``AWS::Redshift::EndpointAuthorization.Force``.
        :param vpc_ids: ``AWS::Redshift::EndpointAuthorization.VpcIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_endpoint_authorization_props = redshift.CfnEndpointAuthorizationProps(
                account="account",
                cluster_identifier="clusterIdentifier",
            
                # the properties below are optional
                force=False,
                vpc_ids=["vpcIds"]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "account": account,
            "cluster_identifier": cluster_identifier,
        }
        if force is not None:
            self._values["force"] = force
        if vpc_ids is not None:
            self._values["vpc_ids"] = vpc_ids

    @builtins.property
    def account(self) -> builtins.str:
        '''``AWS::Redshift::EndpointAuthorization.Account``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-account
        '''
        result = self._values.get("account")
        assert result is not None, "Required property 'account' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cluster_identifier(self) -> builtins.str:
        '''``AWS::Redshift::EndpointAuthorization.ClusterIdentifier``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-clusteridentifier
        '''
        result = self._values.get("cluster_identifier")
        assert result is not None, "Required property 'cluster_identifier' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def force(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::EndpointAuthorization.Force``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-force
        '''
        result = self._values.get("force")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def vpc_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::EndpointAuthorization.VpcIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-vpcids
        '''
        result = self._values.get("vpc_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEndpointAuthorizationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEventSubscription(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnEventSubscription",
):
    '''A CloudFormation ``AWS::Redshift::EventSubscription``.

    :cloudformationResource: AWS::Redshift::EventSubscription
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_event_subscription = redshift.CfnEventSubscription(self, "MyCfnEventSubscription",
            subscription_name="subscriptionName",
        
            # the properties below are optional
            enabled=False,
            event_categories=["eventCategories"],
            severity="severity",
            sns_topic_arn="snsTopicArn",
            source_ids=["sourceIds"],
            source_type="sourceType",
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        event_categories: typing.Optional[typing.Sequence[builtins.str]] = None,
        severity: typing.Optional[builtins.str] = None,
        sns_topic_arn: typing.Optional[builtins.str] = None,
        source_ids: typing.Optional[typing.Sequence[builtins.str]] = None,
        source_type: typing.Optional[builtins.str] = None,
        subscription_name: builtins.str,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::EventSubscription``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param enabled: ``AWS::Redshift::EventSubscription.Enabled``.
        :param event_categories: ``AWS::Redshift::EventSubscription.EventCategories``.
        :param severity: ``AWS::Redshift::EventSubscription.Severity``.
        :param sns_topic_arn: ``AWS::Redshift::EventSubscription.SnsTopicArn``.
        :param source_ids: ``AWS::Redshift::EventSubscription.SourceIds``.
        :param source_type: ``AWS::Redshift::EventSubscription.SourceType``.
        :param subscription_name: ``AWS::Redshift::EventSubscription.SubscriptionName``.
        :param tags: ``AWS::Redshift::EventSubscription.Tags``.
        '''
        props = CfnEventSubscriptionProps(
            enabled=enabled,
            event_categories=event_categories,
            severity=severity,
            sns_topic_arn=sns_topic_arn,
            source_ids=source_ids,
            source_type=source_type,
            subscription_name=subscription_name,
            tags=tags,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCustomerAwsId")
    def attr_customer_aws_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: CustomerAwsId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCustomerAwsId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCustSubscriptionId")
    def attr_cust_subscription_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: CustSubscriptionId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCustSubscriptionId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrEventCategoriesList")
    def attr_event_categories_list(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: EventCategoriesList
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrEventCategoriesList"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSourceIdsList")
    def attr_source_ids_list(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: SourceIdsList
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrSourceIdsList"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrStatus")
    def attr_status(self) -> builtins.str:
        '''
        :cloudformationAttribute: Status
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrStatus"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSubscriptionCreationTime")
    def attr_subscription_creation_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: SubscriptionCreationTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrSubscriptionCreationTime"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="enabled")
    def enabled(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::EventSubscription.Enabled``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-enabled
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "enabled"))

    @enabled.setter
    def enabled(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "enabled", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="eventCategories")
    def event_categories(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::EventSubscription.EventCategories``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-eventcategories
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "eventCategories"))

    @event_categories.setter
    def event_categories(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "eventCategories", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="severity")
    def severity(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EventSubscription.Severity``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-severity
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "severity"))

    @severity.setter
    def severity(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "severity", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snsTopicArn")
    def sns_topic_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EventSubscription.SnsTopicArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-snstopicarn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "snsTopicArn"))

    @sns_topic_arn.setter
    def sns_topic_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "snsTopicArn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceIds")
    def source_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::EventSubscription.SourceIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourceids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "sourceIds"))

    @source_ids.setter
    def source_ids(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "sourceIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceType")
    def source_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EventSubscription.SourceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourcetype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "sourceType"))

    @source_type.setter
    def source_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "sourceType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subscriptionName")
    def subscription_name(self) -> builtins.str:
        '''``AWS::Redshift::EventSubscription.SubscriptionName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-subscriptionname
        '''
        return typing.cast(builtins.str, jsii.get(self, "subscriptionName"))

    @subscription_name.setter
    def subscription_name(self, value: builtins.str) -> None:
        jsii.set(self, "subscriptionName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::Redshift::EventSubscription.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnEventSubscriptionProps",
    jsii_struct_bases=[],
    name_mapping={
        "enabled": "enabled",
        "event_categories": "eventCategories",
        "severity": "severity",
        "sns_topic_arn": "snsTopicArn",
        "source_ids": "sourceIds",
        "source_type": "sourceType",
        "subscription_name": "subscriptionName",
        "tags": "tags",
    },
)
class CfnEventSubscriptionProps:
    def __init__(
        self,
        *,
        enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        event_categories: typing.Optional[typing.Sequence[builtins.str]] = None,
        severity: typing.Optional[builtins.str] = None,
        sns_topic_arn: typing.Optional[builtins.str] = None,
        source_ids: typing.Optional[typing.Sequence[builtins.str]] = None,
        source_type: typing.Optional[builtins.str] = None,
        subscription_name: builtins.str,
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::EventSubscription``.

        :param enabled: ``AWS::Redshift::EventSubscription.Enabled``.
        :param event_categories: ``AWS::Redshift::EventSubscription.EventCategories``.
        :param severity: ``AWS::Redshift::EventSubscription.Severity``.
        :param sns_topic_arn: ``AWS::Redshift::EventSubscription.SnsTopicArn``.
        :param source_ids: ``AWS::Redshift::EventSubscription.SourceIds``.
        :param source_type: ``AWS::Redshift::EventSubscription.SourceType``.
        :param subscription_name: ``AWS::Redshift::EventSubscription.SubscriptionName``.
        :param tags: ``AWS::Redshift::EventSubscription.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_event_subscription_props = redshift.CfnEventSubscriptionProps(
                subscription_name="subscriptionName",
            
                # the properties below are optional
                enabled=False,
                event_categories=["eventCategories"],
                severity="severity",
                sns_topic_arn="snsTopicArn",
                source_ids=["sourceIds"],
                source_type="sourceType",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "subscription_name": subscription_name,
        }
        if enabled is not None:
            self._values["enabled"] = enabled
        if event_categories is not None:
            self._values["event_categories"] = event_categories
        if severity is not None:
            self._values["severity"] = severity
        if sns_topic_arn is not None:
            self._values["sns_topic_arn"] = sns_topic_arn
        if source_ids is not None:
            self._values["source_ids"] = source_ids
        if source_type is not None:
            self._values["source_type"] = source_type
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def enabled(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::EventSubscription.Enabled``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-enabled
        '''
        result = self._values.get("enabled")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def event_categories(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::EventSubscription.EventCategories``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-eventcategories
        '''
        result = self._values.get("event_categories")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def severity(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EventSubscription.Severity``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-severity
        '''
        result = self._values.get("severity")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def sns_topic_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EventSubscription.SnsTopicArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-snstopicarn
        '''
        result = self._values.get("sns_topic_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def source_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::Redshift::EventSubscription.SourceIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourceids
        '''
        result = self._values.get("source_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def source_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::EventSubscription.SourceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourcetype
        '''
        result = self._values.get("source_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subscription_name(self) -> builtins.str:
        '''``AWS::Redshift::EventSubscription.SubscriptionName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-subscriptionname
        '''
        result = self._values.get("subscription_name")
        assert result is not None, "Required property 'subscription_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::Redshift::EventSubscription.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEventSubscriptionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnScheduledAction(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.CfnScheduledAction",
):
    '''A CloudFormation ``AWS::Redshift::ScheduledAction``.

    :cloudformationResource: AWS::Redshift::ScheduledAction
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cfn_scheduled_action = redshift.CfnScheduledAction(self, "MyCfnScheduledAction",
            scheduled_action_name="scheduledActionName",
        
            # the properties below are optional
            enable=False,
            end_time="endTime",
            iam_role="iamRole",
            schedule="schedule",
            scheduled_action_description="scheduledActionDescription",
            start_time="startTime",
            target_action=redshift.CfnScheduledAction.ScheduledActionTypeProperty(
                pause_cluster=redshift.CfnScheduledAction.PauseClusterMessageProperty(
                    cluster_identifier="clusterIdentifier"
                ),
                resize_cluster=redshift.CfnScheduledAction.ResizeClusterMessageProperty(
                    cluster_identifier="clusterIdentifier",
        
                    # the properties below are optional
                    classic=False,
                    cluster_type="clusterType",
                    node_type="nodeType",
                    number_of_nodes=123
                ),
                resume_cluster=redshift.CfnScheduledAction.ResumeClusterMessageProperty(
                    cluster_identifier="clusterIdentifier"
                )
            )
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        enable: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        end_time: typing.Optional[builtins.str] = None,
        iam_role: typing.Optional[builtins.str] = None,
        schedule: typing.Optional[builtins.str] = None,
        scheduled_action_description: typing.Optional[builtins.str] = None,
        scheduled_action_name: builtins.str,
        start_time: typing.Optional[builtins.str] = None,
        target_action: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ScheduledActionTypeProperty"]] = None,
    ) -> None:
        '''Create a new ``AWS::Redshift::ScheduledAction``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param enable: ``AWS::Redshift::ScheduledAction.Enable``.
        :param end_time: ``AWS::Redshift::ScheduledAction.EndTime``.
        :param iam_role: ``AWS::Redshift::ScheduledAction.IamRole``.
        :param schedule: ``AWS::Redshift::ScheduledAction.Schedule``.
        :param scheduled_action_description: ``AWS::Redshift::ScheduledAction.ScheduledActionDescription``.
        :param scheduled_action_name: ``AWS::Redshift::ScheduledAction.ScheduledActionName``.
        :param start_time: ``AWS::Redshift::ScheduledAction.StartTime``.
        :param target_action: ``AWS::Redshift::ScheduledAction.TargetAction``.
        '''
        props = CfnScheduledActionProps(
            enable=enable,
            end_time=end_time,
            iam_role=iam_role,
            schedule=schedule,
            scheduled_action_description=scheduled_action_description,
            scheduled_action_name=scheduled_action_name,
            start_time=start_time,
            target_action=target_action,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNextInvocations")
    def attr_next_invocations(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: NextInvocations
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrNextInvocations"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrState")
    def attr_state(self) -> builtins.str:
        '''
        :cloudformationAttribute: State
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrState"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="enable")
    def enable(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::ScheduledAction.Enable``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-enable
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "enable"))

    @enable.setter
    def enable(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "enable", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="endTime")
    def end_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.EndTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-endtime
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "endTime"))

    @end_time.setter
    def end_time(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "endTime", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="iamRole")
    def iam_role(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.IamRole``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-iamrole
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "iamRole"))

    @iam_role.setter
    def iam_role(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "iamRole", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="schedule")
    def schedule(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.Schedule``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-schedule
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "schedule"))

    @schedule.setter
    def schedule(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "schedule", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="scheduledActionDescription")
    def scheduled_action_description(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.ScheduledActionDescription``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactiondescription
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "scheduledActionDescription"))

    @scheduled_action_description.setter
    def scheduled_action_description(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "scheduledActionDescription", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="scheduledActionName")
    def scheduled_action_name(self) -> builtins.str:
        '''``AWS::Redshift::ScheduledAction.ScheduledActionName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactionname
        '''
        return typing.cast(builtins.str, jsii.get(self, "scheduledActionName"))

    @scheduled_action_name.setter
    def scheduled_action_name(self, value: builtins.str) -> None:
        jsii.set(self, "scheduledActionName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="startTime")
    def start_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.StartTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-starttime
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "startTime"))

    @start_time.setter
    def start_time(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "startTime", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="targetAction")
    def target_action(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ScheduledActionTypeProperty"]]:
        '''``AWS::Redshift::ScheduledAction.TargetAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-targetaction
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ScheduledActionTypeProperty"]], jsii.get(self, "targetAction"))

    @target_action.setter
    def target_action(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ScheduledActionTypeProperty"]],
    ) -> None:
        jsii.set(self, "targetAction", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnScheduledAction.PauseClusterMessageProperty",
        jsii_struct_bases=[],
        name_mapping={"cluster_identifier": "clusterIdentifier"},
    )
    class PauseClusterMessageProperty:
        def __init__(self, *, cluster_identifier: builtins.str) -> None:
            '''
            :param cluster_identifier: ``CfnScheduledAction.PauseClusterMessageProperty.ClusterIdentifier``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-pauseclustermessage.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                pause_cluster_message_property = redshift.CfnScheduledAction.PauseClusterMessageProperty(
                    cluster_identifier="clusterIdentifier"
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cluster_identifier": cluster_identifier,
            }

        @builtins.property
        def cluster_identifier(self) -> builtins.str:
            '''``CfnScheduledAction.PauseClusterMessageProperty.ClusterIdentifier``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-pauseclustermessage.html#cfn-redshift-scheduledaction-pauseclustermessage-clusteridentifier
            '''
            result = self._values.get("cluster_identifier")
            assert result is not None, "Required property 'cluster_identifier' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PauseClusterMessageProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnScheduledAction.ResizeClusterMessageProperty",
        jsii_struct_bases=[],
        name_mapping={
            "classic": "classic",
            "cluster_identifier": "clusterIdentifier",
            "cluster_type": "clusterType",
            "node_type": "nodeType",
            "number_of_nodes": "numberOfNodes",
        },
    )
    class ResizeClusterMessageProperty:
        def __init__(
            self,
            *,
            classic: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            cluster_identifier: builtins.str,
            cluster_type: typing.Optional[builtins.str] = None,
            node_type: typing.Optional[builtins.str] = None,
            number_of_nodes: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param classic: ``CfnScheduledAction.ResizeClusterMessageProperty.Classic``.
            :param cluster_identifier: ``CfnScheduledAction.ResizeClusterMessageProperty.ClusterIdentifier``.
            :param cluster_type: ``CfnScheduledAction.ResizeClusterMessageProperty.ClusterType``.
            :param node_type: ``CfnScheduledAction.ResizeClusterMessageProperty.NodeType``.
            :param number_of_nodes: ``CfnScheduledAction.ResizeClusterMessageProperty.NumberOfNodes``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                resize_cluster_message_property = redshift.CfnScheduledAction.ResizeClusterMessageProperty(
                    cluster_identifier="clusterIdentifier",
                
                    # the properties below are optional
                    classic=False,
                    cluster_type="clusterType",
                    node_type="nodeType",
                    number_of_nodes=123
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cluster_identifier": cluster_identifier,
            }
            if classic is not None:
                self._values["classic"] = classic
            if cluster_type is not None:
                self._values["cluster_type"] = cluster_type
            if node_type is not None:
                self._values["node_type"] = node_type
            if number_of_nodes is not None:
                self._values["number_of_nodes"] = number_of_nodes

        @builtins.property
        def classic(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnScheduledAction.ResizeClusterMessageProperty.Classic``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-classic
            '''
            result = self._values.get("classic")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def cluster_identifier(self) -> builtins.str:
            '''``CfnScheduledAction.ResizeClusterMessageProperty.ClusterIdentifier``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-clusteridentifier
            '''
            result = self._values.get("cluster_identifier")
            assert result is not None, "Required property 'cluster_identifier' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def cluster_type(self) -> typing.Optional[builtins.str]:
            '''``CfnScheduledAction.ResizeClusterMessageProperty.ClusterType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-clustertype
            '''
            result = self._values.get("cluster_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def node_type(self) -> typing.Optional[builtins.str]:
            '''``CfnScheduledAction.ResizeClusterMessageProperty.NodeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-nodetype
            '''
            result = self._values.get("node_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def number_of_nodes(self) -> typing.Optional[jsii.Number]:
            '''``CfnScheduledAction.ResizeClusterMessageProperty.NumberOfNodes``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-numberofnodes
            '''
            result = self._values.get("number_of_nodes")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ResizeClusterMessageProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnScheduledAction.ResumeClusterMessageProperty",
        jsii_struct_bases=[],
        name_mapping={"cluster_identifier": "clusterIdentifier"},
    )
    class ResumeClusterMessageProperty:
        def __init__(self, *, cluster_identifier: builtins.str) -> None:
            '''
            :param cluster_identifier: ``CfnScheduledAction.ResumeClusterMessageProperty.ClusterIdentifier``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resumeclustermessage.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                resume_cluster_message_property = redshift.CfnScheduledAction.ResumeClusterMessageProperty(
                    cluster_identifier="clusterIdentifier"
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cluster_identifier": cluster_identifier,
            }

        @builtins.property
        def cluster_identifier(self) -> builtins.str:
            '''``CfnScheduledAction.ResumeClusterMessageProperty.ClusterIdentifier``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resumeclustermessage.html#cfn-redshift-scheduledaction-resumeclustermessage-clusteridentifier
            '''
            result = self._values.get("cluster_identifier")
            assert result is not None, "Required property 'cluster_identifier' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ResumeClusterMessageProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-redshift.CfnScheduledAction.ScheduledActionTypeProperty",
        jsii_struct_bases=[],
        name_mapping={
            "pause_cluster": "pauseCluster",
            "resize_cluster": "resizeCluster",
            "resume_cluster": "resumeCluster",
        },
    )
    class ScheduledActionTypeProperty:
        def __init__(
            self,
            *,
            pause_cluster: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.PauseClusterMessageProperty"]] = None,
            resize_cluster: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ResizeClusterMessageProperty"]] = None,
            resume_cluster: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ResumeClusterMessageProperty"]] = None,
        ) -> None:
            '''
            :param pause_cluster: ``CfnScheduledAction.ScheduledActionTypeProperty.PauseCluster``.
            :param resize_cluster: ``CfnScheduledAction.ScheduledActionTypeProperty.ResizeCluster``.
            :param resume_cluster: ``CfnScheduledAction.ScheduledActionTypeProperty.ResumeCluster``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_redshift as redshift
                
                scheduled_action_type_property = redshift.CfnScheduledAction.ScheduledActionTypeProperty(
                    pause_cluster=redshift.CfnScheduledAction.PauseClusterMessageProperty(
                        cluster_identifier="clusterIdentifier"
                    ),
                    resize_cluster=redshift.CfnScheduledAction.ResizeClusterMessageProperty(
                        cluster_identifier="clusterIdentifier",
                
                        # the properties below are optional
                        classic=False,
                        cluster_type="clusterType",
                        node_type="nodeType",
                        number_of_nodes=123
                    ),
                    resume_cluster=redshift.CfnScheduledAction.ResumeClusterMessageProperty(
                        cluster_identifier="clusterIdentifier"
                    )
                )
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if pause_cluster is not None:
                self._values["pause_cluster"] = pause_cluster
            if resize_cluster is not None:
                self._values["resize_cluster"] = resize_cluster
            if resume_cluster is not None:
                self._values["resume_cluster"] = resume_cluster

        @builtins.property
        def pause_cluster(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.PauseClusterMessageProperty"]]:
            '''``CfnScheduledAction.ScheduledActionTypeProperty.PauseCluster``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-pausecluster
            '''
            result = self._values.get("pause_cluster")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.PauseClusterMessageProperty"]], result)

        @builtins.property
        def resize_cluster(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ResizeClusterMessageProperty"]]:
            '''``CfnScheduledAction.ScheduledActionTypeProperty.ResizeCluster``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-resizecluster
            '''
            result = self._values.get("resize_cluster")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ResizeClusterMessageProperty"]], result)

        @builtins.property
        def resume_cluster(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ResumeClusterMessageProperty"]]:
            '''``CfnScheduledAction.ScheduledActionTypeProperty.ResumeCluster``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-resumecluster
            '''
            result = self._values.get("resume_cluster")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnScheduledAction.ResumeClusterMessageProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ScheduledActionTypeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.CfnScheduledActionProps",
    jsii_struct_bases=[],
    name_mapping={
        "enable": "enable",
        "end_time": "endTime",
        "iam_role": "iamRole",
        "schedule": "schedule",
        "scheduled_action_description": "scheduledActionDescription",
        "scheduled_action_name": "scheduledActionName",
        "start_time": "startTime",
        "target_action": "targetAction",
    },
)
class CfnScheduledActionProps:
    def __init__(
        self,
        *,
        enable: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        end_time: typing.Optional[builtins.str] = None,
        iam_role: typing.Optional[builtins.str] = None,
        schedule: typing.Optional[builtins.str] = None,
        scheduled_action_description: typing.Optional[builtins.str] = None,
        scheduled_action_name: builtins.str,
        start_time: typing.Optional[builtins.str] = None,
        target_action: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnScheduledAction.ScheduledActionTypeProperty]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::Redshift::ScheduledAction``.

        :param enable: ``AWS::Redshift::ScheduledAction.Enable``.
        :param end_time: ``AWS::Redshift::ScheduledAction.EndTime``.
        :param iam_role: ``AWS::Redshift::ScheduledAction.IamRole``.
        :param schedule: ``AWS::Redshift::ScheduledAction.Schedule``.
        :param scheduled_action_description: ``AWS::Redshift::ScheduledAction.ScheduledActionDescription``.
        :param scheduled_action_name: ``AWS::Redshift::ScheduledAction.ScheduledActionName``.
        :param start_time: ``AWS::Redshift::ScheduledAction.StartTime``.
        :param target_action: ``AWS::Redshift::ScheduledAction.TargetAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cfn_scheduled_action_props = redshift.CfnScheduledActionProps(
                scheduled_action_name="scheduledActionName",
            
                # the properties below are optional
                enable=False,
                end_time="endTime",
                iam_role="iamRole",
                schedule="schedule",
                scheduled_action_description="scheduledActionDescription",
                start_time="startTime",
                target_action=redshift.CfnScheduledAction.ScheduledActionTypeProperty(
                    pause_cluster=redshift.CfnScheduledAction.PauseClusterMessageProperty(
                        cluster_identifier="clusterIdentifier"
                    ),
                    resize_cluster=redshift.CfnScheduledAction.ResizeClusterMessageProperty(
                        cluster_identifier="clusterIdentifier",
            
                        # the properties below are optional
                        classic=False,
                        cluster_type="clusterType",
                        node_type="nodeType",
                        number_of_nodes=123
                    ),
                    resume_cluster=redshift.CfnScheduledAction.ResumeClusterMessageProperty(
                        cluster_identifier="clusterIdentifier"
                    )
                )
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "scheduled_action_name": scheduled_action_name,
        }
        if enable is not None:
            self._values["enable"] = enable
        if end_time is not None:
            self._values["end_time"] = end_time
        if iam_role is not None:
            self._values["iam_role"] = iam_role
        if schedule is not None:
            self._values["schedule"] = schedule
        if scheduled_action_description is not None:
            self._values["scheduled_action_description"] = scheduled_action_description
        if start_time is not None:
            self._values["start_time"] = start_time
        if target_action is not None:
            self._values["target_action"] = target_action

    @builtins.property
    def enable(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::Redshift::ScheduledAction.Enable``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-enable
        '''
        result = self._values.get("enable")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def end_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.EndTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-endtime
        '''
        result = self._values.get("end_time")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def iam_role(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.IamRole``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-iamrole
        '''
        result = self._values.get("iam_role")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def schedule(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.Schedule``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-schedule
        '''
        result = self._values.get("schedule")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def scheduled_action_description(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.ScheduledActionDescription``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactiondescription
        '''
        result = self._values.get("scheduled_action_description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def scheduled_action_name(self) -> builtins.str:
        '''``AWS::Redshift::ScheduledAction.ScheduledActionName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactionname
        '''
        result = self._values.get("scheduled_action_name")
        assert result is not None, "Required property 'scheduled_action_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def start_time(self) -> typing.Optional[builtins.str]:
        '''``AWS::Redshift::ScheduledAction.StartTime``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-starttime
        '''
        result = self._values.get("start_time")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def target_action(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnScheduledAction.ScheduledActionTypeProperty]]:
        '''``AWS::Redshift::ScheduledAction.TargetAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-targetaction
        '''
        result = self._values.get("target_action")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnScheduledAction.ScheduledActionTypeProperty]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnScheduledActionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.ClusterAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "cluster_endpoint_address": "clusterEndpointAddress",
        "cluster_endpoint_port": "clusterEndpointPort",
        "cluster_name": "clusterName",
        "security_groups": "securityGroups",
    },
)
class ClusterAttributes:
    def __init__(
        self,
        *,
        cluster_endpoint_address: builtins.str,
        cluster_endpoint_port: jsii.Number,
        cluster_name: builtins.str,
        security_groups: typing.Optional[typing.Sequence[aws_cdk.aws_ec2.ISecurityGroup]] = None,
    ) -> None:
        '''(experimental) Properties that describe an existing cluster instance.

        :param cluster_endpoint_address: (experimental) Cluster endpoint address.
        :param cluster_endpoint_port: (experimental) Cluster endpoint port.
        :param cluster_name: (experimental) Identifier for the cluster.
        :param security_groups: (experimental) The security groups of the redshift cluster. Default: no security groups will be attached to the import

        :stability: experimental

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_ec2 as ec2
            import aws_cdk.aws_redshift as redshift
            
            # security_group is of type SecurityGroup
            
            cluster_attributes = redshift.ClusterAttributes(
                cluster_endpoint_address="clusterEndpointAddress",
                cluster_endpoint_port=123,
                cluster_name="clusterName",
            
                # the properties below are optional
                security_groups=[security_group]
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster_endpoint_address": cluster_endpoint_address,
            "cluster_endpoint_port": cluster_endpoint_port,
            "cluster_name": cluster_name,
        }
        if security_groups is not None:
            self._values["security_groups"] = security_groups

    @builtins.property
    def cluster_endpoint_address(self) -> builtins.str:
        '''(experimental) Cluster endpoint address.

        :stability: experimental
        '''
        result = self._values.get("cluster_endpoint_address")
        assert result is not None, "Required property 'cluster_endpoint_address' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cluster_endpoint_port(self) -> jsii.Number:
        '''(experimental) Cluster endpoint port.

        :stability: experimental
        '''
        result = self._values.get("cluster_endpoint_port")
        assert result is not None, "Required property 'cluster_endpoint_port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def cluster_name(self) -> builtins.str:
        '''(experimental) Identifier for the cluster.

        :stability: experimental
        '''
        result = self._values.get("cluster_name")
        assert result is not None, "Required property 'cluster_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def security_groups(
        self,
    ) -> typing.Optional[typing.List[aws_cdk.aws_ec2.ISecurityGroup]]:
        '''(experimental) The security groups of the redshift cluster.

        :default: no security groups will be attached to the import

        :stability: experimental
        '''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List[aws_cdk.aws_ec2.ISecurityGroup]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ClusterAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.ClusterParameterGroupProps",
    jsii_struct_bases=[],
    name_mapping={"description": "description", "parameters": "parameters"},
)
class ClusterParameterGroupProps:
    def __init__(
        self,
        *,
        description: typing.Optional[builtins.str] = None,
        parameters: typing.Mapping[builtins.str, builtins.str],
    ) -> None:
        '''(experimental) Properties for a parameter group.

        :param description: (experimental) Description for this parameter group. Default: a CDK generated description
        :param parameters: (experimental) The parameters in this parameter group.

        :stability: experimental

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            cluster_parameter_group_props = redshift.ClusterParameterGroupProps(
                parameters={
                    "parameters_key": "parameters"
                },
            
                # the properties below are optional
                description="description"
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "parameters": parameters,
        }
        if description is not None:
            self._values["description"] = description

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''(experimental) Description for this parameter group.

        :default: a CDK generated description

        :stability: experimental
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def parameters(self) -> typing.Mapping[builtins.str, builtins.str]:
        '''(experimental) The parameters in this parameter group.

        :stability: experimental
        '''
        result = self._values.get("parameters")
        assert result is not None, "Required property 'parameters' is missing"
        return typing.cast(typing.Mapping[builtins.str, builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ClusterParameterGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.ClusterProps",
    jsii_struct_bases=[],
    name_mapping={
        "master_user": "masterUser",
        "vpc": "vpc",
        "cluster_name": "clusterName",
        "cluster_type": "clusterType",
        "default_database_name": "defaultDatabaseName",
        "encrypted": "encrypted",
        "encryption_key": "encryptionKey",
        "logging_bucket": "loggingBucket",
        "logging_key_prefix": "loggingKeyPrefix",
        "node_type": "nodeType",
        "number_of_nodes": "numberOfNodes",
        "parameter_group": "parameterGroup",
        "port": "port",
        "preferred_maintenance_window": "preferredMaintenanceWindow",
        "publicly_accessible": "publiclyAccessible",
        "removal_policy": "removalPolicy",
        "roles": "roles",
        "security_groups": "securityGroups",
        "subnet_group": "subnetGroup",
        "vpc_subnets": "vpcSubnets",
    },
)
class ClusterProps:
    def __init__(
        self,
        *,
        master_user: "Login",
        vpc: aws_cdk.aws_ec2.IVpc,
        cluster_name: typing.Optional[builtins.str] = None,
        cluster_type: typing.Optional["ClusterType"] = None,
        default_database_name: typing.Optional[builtins.str] = None,
        encrypted: typing.Optional[builtins.bool] = None,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        logging_bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
        logging_key_prefix: typing.Optional[builtins.str] = None,
        node_type: typing.Optional["NodeType"] = None,
        number_of_nodes: typing.Optional[jsii.Number] = None,
        parameter_group: typing.Optional["IClusterParameterGroup"] = None,
        port: typing.Optional[jsii.Number] = None,
        preferred_maintenance_window: typing.Optional[builtins.str] = None,
        publicly_accessible: typing.Optional[builtins.bool] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        roles: typing.Optional[typing.Sequence[aws_cdk.aws_iam.IRole]] = None,
        security_groups: typing.Optional[typing.Sequence[aws_cdk.aws_ec2.ISecurityGroup]] = None,
        subnet_group: typing.Optional["IClusterSubnetGroup"] = None,
        vpc_subnets: typing.Optional[aws_cdk.aws_ec2.SubnetSelection] = None,
    ) -> None:
        '''(experimental) Properties for a new database cluster.

        :param master_user: (experimental) Username and password for the administrative user.
        :param vpc: (experimental) The VPC to place the cluster in.
        :param cluster_name: (experimental) An optional identifier for the cluster. Default: - A name is automatically generated.
        :param cluster_type: (experimental) Settings for the individual instances that are launched. Default: {@link ClusterType.MULTI_NODE}
        :param default_database_name: (experimental) Name of a database which is automatically created inside the cluster. Default: - default_db
        :param encrypted: (experimental) Whether to enable encryption of data at rest in the cluster. Default: true
        :param encryption_key: (experimental) The KMS key to use for encryption of data at rest. Default: - AWS-managed key, if encryption at rest is enabled
        :param logging_bucket: (experimental) Bucket to send logs to. Logging information includes queries and connection attempts, for the specified Amazon Redshift cluster. Default: - No Logs
        :param logging_key_prefix: (experimental) Prefix used for logging. Default: - no prefix
        :param node_type: (experimental) The node type to be provisioned for the cluster. Default: {@link NodeType.DC2_LARGE}
        :param number_of_nodes: (experimental) Number of compute nodes in the cluster. Only specify this property for multi-node clusters. Value must be at least 2 and no more than 100. Default: - 2 if ``clusterType`` is ClusterType.MULTI_NODE, undefined otherwise
        :param parameter_group: (experimental) Additional parameters to pass to the database engine https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html. Default: - No parameter group.
        :param port: (experimental) What port to listen on. Default: - The default for the engine is used.
        :param preferred_maintenance_window: (experimental) A preferred maintenance window day/time range. Should be specified as a range ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). Example: 'Sun:23:45-Mon:00:15' Default: - 30-minute window selected at random from an 8-hour block of time for each AWS Region, occurring on a random day of the week.
        :param publicly_accessible: (experimental) Whether to make cluster publicly accessible. Default: false
        :param removal_policy: (experimental) The removal policy to apply when the cluster and its instances are removed from the stack or replaced during an update. Default: RemovalPolicy.RETAIN
        :param roles: (experimental) A list of AWS Identity and Access Management (IAM) role that can be used by the cluster to access other AWS services. Specify a maximum of 10 roles. Default: - No role is attached to the cluster.
        :param security_groups: (experimental) Security group. Default: - a new security group is created.
        :param subnet_group: (experimental) A cluster subnet group to use with this cluster. Default: - a new subnet group will be created.
        :param vpc_subnets: (experimental) Where to place the instances within the VPC. Default: - private subnets

        :stability: experimental

        Example::

            import aws_cdk.aws_ec2 as ec2
            
            
            vpc = ec2.Vpc(self, "Vpc")
            cluster = Cluster(self, "Redshift",
                master_user=Login(
                    master_username="admin"
                ),
                vpc=vpc
            )
        '''
        if isinstance(master_user, dict):
            master_user = Login(**master_user)
        if isinstance(vpc_subnets, dict):
            vpc_subnets = aws_cdk.aws_ec2.SubnetSelection(**vpc_subnets)
        self._values: typing.Dict[str, typing.Any] = {
            "master_user": master_user,
            "vpc": vpc,
        }
        if cluster_name is not None:
            self._values["cluster_name"] = cluster_name
        if cluster_type is not None:
            self._values["cluster_type"] = cluster_type
        if default_database_name is not None:
            self._values["default_database_name"] = default_database_name
        if encrypted is not None:
            self._values["encrypted"] = encrypted
        if encryption_key is not None:
            self._values["encryption_key"] = encryption_key
        if logging_bucket is not None:
            self._values["logging_bucket"] = logging_bucket
        if logging_key_prefix is not None:
            self._values["logging_key_prefix"] = logging_key_prefix
        if node_type is not None:
            self._values["node_type"] = node_type
        if number_of_nodes is not None:
            self._values["number_of_nodes"] = number_of_nodes
        if parameter_group is not None:
            self._values["parameter_group"] = parameter_group
        if port is not None:
            self._values["port"] = port
        if preferred_maintenance_window is not None:
            self._values["preferred_maintenance_window"] = preferred_maintenance_window
        if publicly_accessible is not None:
            self._values["publicly_accessible"] = publicly_accessible
        if removal_policy is not None:
            self._values["removal_policy"] = removal_policy
        if roles is not None:
            self._values["roles"] = roles
        if security_groups is not None:
            self._values["security_groups"] = security_groups
        if subnet_group is not None:
            self._values["subnet_group"] = subnet_group
        if vpc_subnets is not None:
            self._values["vpc_subnets"] = vpc_subnets

    @builtins.property
    def master_user(self) -> "Login":
        '''(experimental) Username and password for the administrative user.

        :stability: experimental
        '''
        result = self._values.get("master_user")
        assert result is not None, "Required property 'master_user' is missing"
        return typing.cast("Login", result)

    @builtins.property
    def vpc(self) -> aws_cdk.aws_ec2.IVpc:
        '''(experimental) The VPC to place the cluster in.

        :stability: experimental
        '''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(aws_cdk.aws_ec2.IVpc, result)

    @builtins.property
    def cluster_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) An optional identifier for the cluster.

        :default: - A name is automatically generated.

        :stability: experimental
        '''
        result = self._values.get("cluster_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cluster_type(self) -> typing.Optional["ClusterType"]:
        '''(experimental) Settings for the individual instances that are launched.

        :default: {@link ClusterType.MULTI_NODE}

        :stability: experimental
        '''
        result = self._values.get("cluster_type")
        return typing.cast(typing.Optional["ClusterType"], result)

    @builtins.property
    def default_database_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) Name of a database which is automatically created inside the cluster.

        :default: - default_db

        :stability: experimental
        '''
        result = self._values.get("default_database_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def encrypted(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Whether to enable encryption of data at rest in the cluster.

        :default: true

        :stability: experimental
        '''
        result = self._values.get("encrypted")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''(experimental) The KMS key to use for encryption of data at rest.

        :default: - AWS-managed key, if encryption at rest is enabled

        :stability: experimental
        '''
        result = self._values.get("encryption_key")
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], result)

    @builtins.property
    def logging_bucket(self) -> typing.Optional[aws_cdk.aws_s3.IBucket]:
        '''(experimental) Bucket to send logs to.

        Logging information includes queries and connection attempts, for the specified Amazon Redshift cluster.

        :default: - No Logs

        :stability: experimental
        '''
        result = self._values.get("logging_bucket")
        return typing.cast(typing.Optional[aws_cdk.aws_s3.IBucket], result)

    @builtins.property
    def logging_key_prefix(self) -> typing.Optional[builtins.str]:
        '''(experimental) Prefix used for logging.

        :default: - no prefix

        :stability: experimental
        '''
        result = self._values.get("logging_key_prefix")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def node_type(self) -> typing.Optional["NodeType"]:
        '''(experimental) The node type to be provisioned for the cluster.

        :default: {@link NodeType.DC2_LARGE}

        :stability: experimental
        '''
        result = self._values.get("node_type")
        return typing.cast(typing.Optional["NodeType"], result)

    @builtins.property
    def number_of_nodes(self) -> typing.Optional[jsii.Number]:
        '''(experimental) Number of compute nodes in the cluster. Only specify this property for multi-node clusters.

        Value must be at least 2 and no more than 100.

        :default: - 2 if ``clusterType`` is ClusterType.MULTI_NODE, undefined otherwise

        :stability: experimental
        '''
        result = self._values.get("number_of_nodes")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def parameter_group(self) -> typing.Optional["IClusterParameterGroup"]:
        '''(experimental) Additional parameters to pass to the database engine https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html.

        :default: - No parameter group.

        :stability: experimental
        '''
        result = self._values.get("parameter_group")
        return typing.cast(typing.Optional["IClusterParameterGroup"], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''(experimental) What port to listen on.

        :default: - The default for the engine is used.

        :stability: experimental
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def preferred_maintenance_window(self) -> typing.Optional[builtins.str]:
        '''(experimental) A preferred maintenance window day/time range. Should be specified as a range ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC).

        Example: 'Sun:23:45-Mon:00:15'

        :default:

        - 30-minute window selected at random from an 8-hour block of time for
        each AWS Region, occurring on a random day of the week.

        :see: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_UpgradeDBInstance.Maintenance.html#Concepts.DBMaintenance
        :stability: experimental
        '''
        result = self._values.get("preferred_maintenance_window")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def publicly_accessible(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Whether to make cluster publicly accessible.

        :default: false

        :stability: experimental
        '''
        result = self._values.get("publicly_accessible")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def removal_policy(self) -> typing.Optional[aws_cdk.core.RemovalPolicy]:
        '''(experimental) The removal policy to apply when the cluster and its instances are removed from the stack or replaced during an update.

        :default: RemovalPolicy.RETAIN

        :stability: experimental
        '''
        result = self._values.get("removal_policy")
        return typing.cast(typing.Optional[aws_cdk.core.RemovalPolicy], result)

    @builtins.property
    def roles(self) -> typing.Optional[typing.List[aws_cdk.aws_iam.IRole]]:
        '''(experimental) A list of AWS Identity and Access Management (IAM) role that can be used by the cluster to access other AWS services.

        Specify a maximum of 10 roles.

        :default: - No role is attached to the cluster.

        :stability: experimental
        '''
        result = self._values.get("roles")
        return typing.cast(typing.Optional[typing.List[aws_cdk.aws_iam.IRole]], result)

    @builtins.property
    def security_groups(
        self,
    ) -> typing.Optional[typing.List[aws_cdk.aws_ec2.ISecurityGroup]]:
        '''(experimental) Security group.

        :default: - a new security group is created.

        :stability: experimental
        '''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List[aws_cdk.aws_ec2.ISecurityGroup]], result)

    @builtins.property
    def subnet_group(self) -> typing.Optional["IClusterSubnetGroup"]:
        '''(experimental) A cluster subnet group to use with this cluster.

        :default: - a new subnet group will be created.

        :stability: experimental
        '''
        result = self._values.get("subnet_group")
        return typing.cast(typing.Optional["IClusterSubnetGroup"], result)

    @builtins.property
    def vpc_subnets(self) -> typing.Optional[aws_cdk.aws_ec2.SubnetSelection]:
        '''(experimental) Where to place the instances within the VPC.

        :default: - private subnets

        :stability: experimental
        '''
        result = self._values.get("vpc_subnets")
        return typing.cast(typing.Optional[aws_cdk.aws_ec2.SubnetSelection], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ClusterProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.ClusterSubnetGroupProps",
    jsii_struct_bases=[],
    name_mapping={
        "description": "description",
        "removal_policy": "removalPolicy",
        "vpc": "vpc",
        "vpc_subnets": "vpcSubnets",
    },
)
class ClusterSubnetGroupProps:
    def __init__(
        self,
        *,
        description: builtins.str,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        vpc: aws_cdk.aws_ec2.IVpc,
        vpc_subnets: typing.Optional[aws_cdk.aws_ec2.SubnetSelection] = None,
    ) -> None:
        '''(experimental) Properties for creating a ClusterSubnetGroup.

        :param description: (experimental) Description of the subnet group.
        :param removal_policy: (experimental) The removal policy to apply when the subnet group are removed from the stack or replaced during an update. Default: RemovalPolicy.RETAIN
        :param vpc: (experimental) The VPC to place the subnet group in.
        :param vpc_subnets: (experimental) Which subnets within the VPC to associate with this group. Default: - private subnets

        :stability: experimental

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_ec2 as ec2
            import aws_cdk.aws_redshift as redshift
            import aws_cdk.core as cdk
            
            # subnet is of type Subnet
            # subnet_filter is of type SubnetFilter
            # vpc is of type Vpc
            
            cluster_subnet_group_props = redshift.ClusterSubnetGroupProps(
                description="description",
                vpc=vpc,
            
                # the properties below are optional
                removal_policy=cdk.RemovalPolicy.DESTROY,
                vpc_subnets=ec2.SubnetSelection(
                    availability_zones=["availabilityZones"],
                    one_per_az=False,
                    subnet_filters=[subnet_filter],
                    subnet_group_name="subnetGroupName",
                    subnet_name="subnetName",
                    subnets=[subnet],
                    subnet_type=ec2.SubnetType.ISOLATED
                )
            )
        '''
        if isinstance(vpc_subnets, dict):
            vpc_subnets = aws_cdk.aws_ec2.SubnetSelection(**vpc_subnets)
        self._values: typing.Dict[str, typing.Any] = {
            "description": description,
            "vpc": vpc,
        }
        if removal_policy is not None:
            self._values["removal_policy"] = removal_policy
        if vpc_subnets is not None:
            self._values["vpc_subnets"] = vpc_subnets

    @builtins.property
    def description(self) -> builtins.str:
        '''(experimental) Description of the subnet group.

        :stability: experimental
        '''
        result = self._values.get("description")
        assert result is not None, "Required property 'description' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def removal_policy(self) -> typing.Optional[aws_cdk.core.RemovalPolicy]:
        '''(experimental) The removal policy to apply when the subnet group are removed from the stack or replaced during an update.

        :default: RemovalPolicy.RETAIN

        :stability: experimental
        '''
        result = self._values.get("removal_policy")
        return typing.cast(typing.Optional[aws_cdk.core.RemovalPolicy], result)

    @builtins.property
    def vpc(self) -> aws_cdk.aws_ec2.IVpc:
        '''(experimental) The VPC to place the subnet group in.

        :stability: experimental
        '''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(aws_cdk.aws_ec2.IVpc, result)

    @builtins.property
    def vpc_subnets(self) -> typing.Optional[aws_cdk.aws_ec2.SubnetSelection]:
        '''(experimental) Which subnets within the VPC to associate with this group.

        :default: - private subnets

        :stability: experimental
        '''
        result = self._values.get("vpc_subnets")
        return typing.cast(typing.Optional[aws_cdk.aws_ec2.SubnetSelection], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ClusterSubnetGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-redshift.ClusterType")
class ClusterType(enum.Enum):
    '''(experimental) What cluster type to use.

    Used by {@link ClusterProps.clusterType}

    :stability: experimental
    '''

    SINGLE_NODE = "SINGLE_NODE"
    '''(experimental) single-node cluster, the {@link ClusterProps.numberOfNodes} parameter is not required.

    :stability: experimental
    '''
    MULTI_NODE = "MULTI_NODE"
    '''(experimental) multi-node cluster, set the amount of nodes using {@link ClusterProps.numberOfNodes} parameter.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.Column",
    jsii_struct_bases=[],
    name_mapping={
        "data_type": "dataType",
        "dist_key": "distKey",
        "name": "name",
        "sort_key": "sortKey",
    },
)
class Column:
    def __init__(
        self,
        *,
        data_type: builtins.str,
        dist_key: typing.Optional[builtins.bool] = None,
        name: builtins.str,
        sort_key: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''(experimental) A column in a Redshift table.

        :param data_type: (experimental) The data type of the column.
        :param dist_key: (experimental) Boolean value that indicates whether the column is to be configured as DISTKEY. Default: - column is not DISTKEY
        :param name: (experimental) The name of the column.
        :param sort_key: (experimental) Boolean value that indicates whether the column is to be configured as SORTKEY. Default: - column is not a SORTKEY

        :stability: experimental

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            
            column = redshift.Column(
                data_type="dataType",
                name="name",
            
                # the properties below are optional
                dist_key=False,
                sort_key=False
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "data_type": data_type,
            "name": name,
        }
        if dist_key is not None:
            self._values["dist_key"] = dist_key
        if sort_key is not None:
            self._values["sort_key"] = sort_key

    @builtins.property
    def data_type(self) -> builtins.str:
        '''(experimental) The data type of the column.

        :stability: experimental
        '''
        result = self._values.get("data_type")
        assert result is not None, "Required property 'data_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def dist_key(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Boolean value that indicates whether the column is to be configured as DISTKEY.

        :default: - column is not DISTKEY

        :stability: experimental
        '''
        result = self._values.get("dist_key")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def name(self) -> builtins.str:
        '''(experimental) The name of the column.

        :stability: experimental
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def sort_key(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Boolean value that indicates whether the column is to be configured as SORTKEY.

        :default: - column is not a SORTKEY

        :stability: experimental
        '''
        result = self._values.get("sort_key")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Column(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.DatabaseOptions",
    jsii_struct_bases=[],
    name_mapping={
        "admin_user": "adminUser",
        "cluster": "cluster",
        "database_name": "databaseName",
    },
)
class DatabaseOptions:
    def __init__(
        self,
        *,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: "ICluster",
        database_name: builtins.str,
    ) -> None:
        '''(experimental) Properties for accessing a Redshift database.

        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.

        :stability: experimental

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_redshift as redshift
            import aws_cdk.aws_secretsmanager as secretsmanager
            
            # cluster is of type Cluster
            # secret is of type Secret
            
            database_options = redshift.DatabaseOptions(
                cluster=cluster,
                database_name="databaseName",
            
                # the properties below are optional
                admin_user=secret
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster": cluster,
            "database_name": database_name,
        }
        if admin_user is not None:
            self._values["admin_user"] = admin_user

    @builtins.property
    def admin_user(self) -> typing.Optional[aws_cdk.aws_secretsmanager.ISecret]:
        '''(experimental) The secret containing credentials to a Redshift user with administrator privileges.

        Secret JSON schema: ``{ username: string; password: string }``.

        :default: - the admin secret is taken from the cluster

        :stability: experimental
        '''
        result = self._values.get("admin_user")
        return typing.cast(typing.Optional[aws_cdk.aws_secretsmanager.ISecret], result)

    @builtins.property
    def cluster(self) -> "ICluster":
        '''(experimental) The cluster containing the database.

        :stability: experimental
        '''
        result = self._values.get("cluster")
        assert result is not None, "Required property 'cluster' is missing"
        return typing.cast("ICluster", result)

    @builtins.property
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database.

        :stability: experimental
        '''
        result = self._values.get("database_name")
        assert result is not None, "Required property 'database_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DatabaseOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class DatabaseSecret(
    aws_cdk.aws_secretsmanager.Secret,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.DatabaseSecret",
):
    '''(experimental) A database secret.

    :stability: experimental
    :resource: AWS::SecretsManager::Secret

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_kms as kms
        import aws_cdk.aws_redshift as redshift
        
        # key is of type Key
        
        database_secret = redshift.DatabaseSecret(self, "MyDatabaseSecret",
            username="username",
        
            # the properties below are optional
            encryption_key=key
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        username: builtins.str,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param encryption_key: (experimental) The KMS key to use to encrypt the secret. Default: default master key
        :param username: (experimental) The username.

        :stability: experimental
        '''
        props = DatabaseSecretProps(encryption_key=encryption_key, username=username)

        jsii.create(self.__class__, self, [scope, id, props])


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.DatabaseSecretProps",
    jsii_struct_bases=[],
    name_mapping={"encryption_key": "encryptionKey", "username": "username"},
)
class DatabaseSecretProps:
    def __init__(
        self,
        *,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        username: builtins.str,
    ) -> None:
        '''(experimental) Construction properties for a DatabaseSecret.

        :param encryption_key: (experimental) The KMS key to use to encrypt the secret. Default: default master key
        :param username: (experimental) The username.

        :stability: experimental

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_kms as kms
            import aws_cdk.aws_redshift as redshift
            
            # key is of type Key
            
            database_secret_props = redshift.DatabaseSecretProps(
                username="username",
            
                # the properties below are optional
                encryption_key=key
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "username": username,
        }
        if encryption_key is not None:
            self._values["encryption_key"] = encryption_key

    @builtins.property
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''(experimental) The KMS key to use to encrypt the secret.

        :default: default master key

        :stability: experimental
        '''
        result = self._values.get("encryption_key")
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], result)

    @builtins.property
    def username(self) -> builtins.str:
        '''(experimental) The username.

        :stability: experimental
        '''
        result = self._values.get("username")
        assert result is not None, "Required property 'username' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DatabaseSecretProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class Endpoint(metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-redshift.Endpoint"):
    '''(experimental) Connection endpoint of a redshift cluster.

    Consists of a combination of hostname and port.

    :stability: experimental

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        endpoint = redshift.Endpoint("address", 123)
    '''

    def __init__(self, address: builtins.str, port: jsii.Number) -> None:
        '''
        :param address: -
        :param port: -

        :stability: experimental
        '''
        jsii.create(self.__class__, self, [address, port])

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hostname")
    def hostname(self) -> builtins.str:
        '''(experimental) The hostname of the endpoint.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "hostname"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="port")
    def port(self) -> jsii.Number:
        '''(experimental) The port of the endpoint.

        :stability: experimental
        '''
        return typing.cast(jsii.Number, jsii.get(self, "port"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="socketAddress")
    def socket_address(self) -> builtins.str:
        '''(experimental) The combination of "HOSTNAME:PORT" for this endpoint.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "socketAddress"))


@jsii.interface(jsii_type="@aws-cdk/aws-redshift.ICluster")
class ICluster(
    aws_cdk.core.IResource,
    aws_cdk.aws_ec2.IConnectable,
    aws_cdk.aws_secretsmanager.ISecretAttachmentTarget,
    typing_extensions.Protocol,
):
    '''(experimental) Create a Redshift Cluster with a given number of nodes.

    Implemented by {@link Cluster} via {@link ClusterBase}.

    :stability: experimental
    '''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterEndpoint")
    def cluster_endpoint(self) -> Endpoint:
        '''(experimental) The endpoint to use for read/write operations.

        :stability: experimental
        :attribute: EndpointAddress,EndpointPort
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterName")
    def cluster_name(self) -> builtins.str:
        '''(experimental) Name of the cluster.

        :stability: experimental
        :attribute: ClusterName
        '''
        ...


class _IClusterProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
    jsii.proxy_for(aws_cdk.aws_ec2.IConnectable), # type: ignore[misc]
    jsii.proxy_for(aws_cdk.aws_secretsmanager.ISecretAttachmentTarget), # type: ignore[misc]
):
    '''(experimental) Create a Redshift Cluster with a given number of nodes.

    Implemented by {@link Cluster} via {@link ClusterBase}.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-redshift.ICluster"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterEndpoint")
    def cluster_endpoint(self) -> Endpoint:
        '''(experimental) The endpoint to use for read/write operations.

        :stability: experimental
        :attribute: EndpointAddress,EndpointPort
        '''
        return typing.cast(Endpoint, jsii.get(self, "clusterEndpoint"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterName")
    def cluster_name(self) -> builtins.str:
        '''(experimental) Name of the cluster.

        :stability: experimental
        :attribute: ClusterName
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, ICluster).__jsii_proxy_class__ = lambda : _IClusterProxy


@jsii.interface(jsii_type="@aws-cdk/aws-redshift.IClusterParameterGroup")
class IClusterParameterGroup(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) A parameter group.

    :stability: experimental
    '''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterParameterGroupName")
    def cluster_parameter_group_name(self) -> builtins.str:
        '''(experimental) The name of this parameter group.

        :stability: experimental
        :attribute: true
        '''
        ...


class _IClusterParameterGroupProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) A parameter group.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-redshift.IClusterParameterGroup"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterParameterGroupName")
    def cluster_parameter_group_name(self) -> builtins.str:
        '''(experimental) The name of this parameter group.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterParameterGroupName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IClusterParameterGroup).__jsii_proxy_class__ = lambda : _IClusterParameterGroupProxy


@jsii.interface(jsii_type="@aws-cdk/aws-redshift.IClusterSubnetGroup")
class IClusterSubnetGroup(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) Interface for a cluster subnet group.

    :stability: experimental
    '''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterSubnetGroupName")
    def cluster_subnet_group_name(self) -> builtins.str:
        '''(experimental) The name of the cluster subnet group.

        :stability: experimental
        :attribute: true
        '''
        ...


class _IClusterSubnetGroupProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) Interface for a cluster subnet group.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-redshift.IClusterSubnetGroup"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterSubnetGroupName")
    def cluster_subnet_group_name(self) -> builtins.str:
        '''(experimental) The name of the cluster subnet group.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterSubnetGroupName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IClusterSubnetGroup).__jsii_proxy_class__ = lambda : _IClusterSubnetGroupProxy


@jsii.interface(jsii_type="@aws-cdk/aws-redshift.ITable")
class ITable(aws_cdk.core.IConstruct, typing_extensions.Protocol):
    '''(experimental) Represents a table in a Redshift database.

    :stability: experimental
    '''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cluster")
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseName")
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tableColumns")
    def table_columns(self) -> typing.List[Column]:
        '''(experimental) The columns of the table.

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tableName")
    def table_name(self) -> builtins.str:
        '''(experimental) Name of the table.

        :stability: experimental
        '''
        ...

    @jsii.member(jsii_name="grant")
    def grant(self, user: "IUser", *actions: "TableAction") -> None:
        '''(experimental) Grant a user privilege to access this table.

        :param user: -
        :param actions: -

        :stability: experimental
        '''
        ...


class _ITableProxy(
    jsii.proxy_for(aws_cdk.core.IConstruct) # type: ignore[misc]
):
    '''(experimental) Represents a table in a Redshift database.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-redshift.ITable"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cluster")
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        return typing.cast(ICluster, jsii.get(self, "cluster"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseName")
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "databaseName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tableColumns")
    def table_columns(self) -> typing.List[Column]:
        '''(experimental) The columns of the table.

        :stability: experimental
        '''
        return typing.cast(typing.List[Column], jsii.get(self, "tableColumns"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tableName")
    def table_name(self) -> builtins.str:
        '''(experimental) Name of the table.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "tableName"))

    @jsii.member(jsii_name="grant")
    def grant(self, user: "IUser", *actions: "TableAction") -> None:
        '''(experimental) Grant a user privilege to access this table.

        :param user: -
        :param actions: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "grant", [user, *actions]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, ITable).__jsii_proxy_class__ = lambda : _ITableProxy


@jsii.interface(jsii_type="@aws-cdk/aws-redshift.IUser")
class IUser(aws_cdk.core.IConstruct, typing_extensions.Protocol):
    '''(experimental) Represents a user in a Redshift database.

    :stability: experimental
    '''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cluster")
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseName")
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="password")
    def password(self) -> aws_cdk.core.SecretValue:
        '''(experimental) The password of the user.

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="username")
    def username(self) -> builtins.str:
        '''(experimental) The name of the user.

        :stability: experimental
        '''
        ...

    @jsii.member(jsii_name="addTablePrivileges")
    def add_table_privileges(self, table: ITable, *actions: "TableAction") -> None:
        '''(experimental) Grant this user privilege to access a table.

        :param table: -
        :param actions: -

        :stability: experimental
        '''
        ...


class _IUserProxy(
    jsii.proxy_for(aws_cdk.core.IConstruct) # type: ignore[misc]
):
    '''(experimental) Represents a user in a Redshift database.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-redshift.IUser"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cluster")
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        return typing.cast(ICluster, jsii.get(self, "cluster"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseName")
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "databaseName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="password")
    def password(self) -> aws_cdk.core.SecretValue:
        '''(experimental) The password of the user.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.core.SecretValue, jsii.get(self, "password"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="username")
    def username(self) -> builtins.str:
        '''(experimental) The name of the user.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "username"))

    @jsii.member(jsii_name="addTablePrivileges")
    def add_table_privileges(self, table: ITable, *actions: "TableAction") -> None:
        '''(experimental) Grant this user privilege to access a table.

        :param table: -
        :param actions: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "addTablePrivileges", [table, *actions]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IUser).__jsii_proxy_class__ = lambda : _IUserProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.Login",
    jsii_struct_bases=[],
    name_mapping={
        "master_username": "masterUsername",
        "encryption_key": "encryptionKey",
        "master_password": "masterPassword",
    },
)
class Login:
    def __init__(
        self,
        *,
        master_username: builtins.str,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        master_password: typing.Optional[aws_cdk.core.SecretValue] = None,
    ) -> None:
        '''(experimental) Username and password combination.

        :param master_username: (experimental) Username.
        :param encryption_key: (experimental) KMS encryption key to encrypt the generated secret. Default: default master key
        :param master_password: (experimental) Password. Do not put passwords in your CDK code directly. Default: a Secrets Manager generated password

        :stability: experimental

        Example::

            import aws_cdk.aws_kms as kms
            
            
            encryption_key = kms.Key(self, "Key")
            User(self, "User",
                encryption_key=encryption_key,
                cluster=cluster,
                database_name="databaseName"
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "master_username": master_username,
        }
        if encryption_key is not None:
            self._values["encryption_key"] = encryption_key
        if master_password is not None:
            self._values["master_password"] = master_password

    @builtins.property
    def master_username(self) -> builtins.str:
        '''(experimental) Username.

        :stability: experimental
        '''
        result = self._values.get("master_username")
        assert result is not None, "Required property 'master_username' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''(experimental) KMS encryption key to encrypt the generated secret.

        :default: default master key

        :stability: experimental
        '''
        result = self._values.get("encryption_key")
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], result)

    @builtins.property
    def master_password(self) -> typing.Optional[aws_cdk.core.SecretValue]:
        '''(experimental) Password.

        Do not put passwords in your CDK code directly.

        :default: a Secrets Manager generated password

        :stability: experimental
        '''
        result = self._values.get("master_password")
        return typing.cast(typing.Optional[aws_cdk.core.SecretValue], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Login(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-redshift.NodeType")
class NodeType(enum.Enum):
    '''(experimental) Possible Node Types to use in the cluster used for defining {@link ClusterProps.nodeType}.

    :stability: experimental
    '''

    DS2_XLARGE = "DS2_XLARGE"
    '''(experimental) ds2.xlarge.

    :stability: experimental
    '''
    DS2_8XLARGE = "DS2_8XLARGE"
    '''(experimental) ds2.8xlarge.

    :stability: experimental
    '''
    DC1_LARGE = "DC1_LARGE"
    '''(experimental) dc1.large.

    :stability: experimental
    '''
    DC1_8XLARGE = "DC1_8XLARGE"
    '''(experimental) dc1.8xlarge.

    :stability: experimental
    '''
    DC2_LARGE = "DC2_LARGE"
    '''(experimental) dc2.large.

    :stability: experimental
    '''
    DC2_8XLARGE = "DC2_8XLARGE"
    '''(experimental) dc2.8xlarge.

    :stability: experimental
    '''
    RA3_XLPLUS = "RA3_XLPLUS"
    '''(experimental) ra3.xlplus.

    :stability: experimental
    '''
    RA3_4XLARGE = "RA3_4XLARGE"
    '''(experimental) ra3.4xlarge.

    :stability: experimental
    '''
    RA3_16XLARGE = "RA3_16XLARGE"
    '''(experimental) ra3.16xlarge.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.RotationMultiUserOptions",
    jsii_struct_bases=[],
    name_mapping={"secret": "secret", "automatically_after": "automaticallyAfter"},
)
class RotationMultiUserOptions:
    def __init__(
        self,
        *,
        secret: aws_cdk.aws_secretsmanager.ISecret,
        automatically_after: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> None:
        '''(experimental) Options to add the multi user rotation.

        :param secret: (experimental) The secret to rotate. It must be a JSON string with the following format:: { "engine": <required: database engine>, "host": <required: instance host name>, "username": <required: username>, "password": <required: password>, "dbname": <optional: database name>, "port": <optional: if not specified, default port will be used>, "masterarn": <required: the arn of the master secret which will be used to create users/change passwords> }
        :param automatically_after: (experimental) Specifies the number of days after the previous rotation before Secrets Manager triggers the next automatic rotation. Default: Duration.days(30)

        :stability: experimental

        Example::

            import aws_cdk.aws_secretsmanager as secretsmanager
            
            
            cluster.add_rotation_multi_user("MyUser",
                secret=secretsmanager.Secret.from_secret_name_v2(self, "Imported Secret", "my-secret")
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "secret": secret,
        }
        if automatically_after is not None:
            self._values["automatically_after"] = automatically_after

    @builtins.property
    def secret(self) -> aws_cdk.aws_secretsmanager.ISecret:
        '''(experimental) The secret to rotate.

        It must be a JSON string with the following format::

           {
              "engine": <required: database engine>,
              "host": <required: instance host name>,
              "username": <required: username>,
              "password": <required: password>,
              "dbname": <optional: database name>,
              "port": <optional: if not specified, default port will be used>,
              "masterarn": <required: the arn of the master secret which will be used to create users/change passwords>
           }

        :stability: experimental
        '''
        result = self._values.get("secret")
        assert result is not None, "Required property 'secret' is missing"
        return typing.cast(aws_cdk.aws_secretsmanager.ISecret, result)

    @builtins.property
    def automatically_after(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''(experimental) Specifies the number of days after the previous rotation before Secrets Manager triggers the next automatic rotation.

        :default: Duration.days(30)

        :stability: experimental
        '''
        result = self._values.get("automatically_after")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RotationMultiUserOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(ITable)
class Table(
    aws_cdk.core.Construct,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.Table",
):
    '''(experimental) A table in a Redshift cluster.

    :stability: experimental

    Example::

        Table(self, "Table",
            table_columns=[Column(name="col1", data_type="varchar(4)", dist_key=True), Column(name="col2", data_type="float")
            ],
            cluster=cluster,
            database_name="databaseName",
            dist_style=TableDistStyle.KEY
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        table_columns: typing.Sequence[Column],
        dist_style: typing.Optional["TableDistStyle"] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        sort_style: typing.Optional["TableSortStyle"] = None,
        table_name: typing.Optional[builtins.str] = None,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: ICluster,
        database_name: builtins.str,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param table_columns: (experimental) The columns of the table.
        :param dist_style: (experimental) The distribution style of the table. Default: TableDistStyle.AUTO
        :param removal_policy: (experimental) The policy to apply when this resource is removed from the application. Default: cdk.RemovalPolicy.Retain
        :param sort_style: (experimental) The sort style of the table. Default: TableSortStyle.AUTO if no sort key is specified, TableSortStyle.COMPOUND if a sort key is specified
        :param table_name: (experimental) The name of the table. Default: - a name is generated
        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.

        :stability: experimental
        '''
        props = TableProps(
            table_columns=table_columns,
            dist_style=dist_style,
            removal_policy=removal_policy,
            sort_style=sort_style,
            table_name=table_name,
            admin_user=admin_user,
            cluster=cluster,
            database_name=database_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromTableAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_table_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        cluster: ICluster,
        database_name: builtins.str,
        table_columns: typing.Sequence[Column],
        table_name: builtins.str,
    ) -> ITable:
        '''(experimental) Specify a Redshift table using a table name and schema that already exists.

        :param scope: -
        :param id: -
        :param cluster: (experimental) The cluster where the table is located.
        :param database_name: (experimental) The name of the database where the table is located.
        :param table_columns: (experimental) The columns of the table.
        :param table_name: (experimental) Name of the table.

        :stability: experimental
        '''
        attrs = TableAttributes(
            cluster=cluster,
            database_name=database_name,
            table_columns=table_columns,
            table_name=table_name,
        )

        return typing.cast(ITable, jsii.sinvoke(cls, "fromTableAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="applyRemovalPolicy")
    def apply_removal_policy(self, policy: aws_cdk.core.RemovalPolicy) -> None:
        '''(experimental) Apply the given removal policy to this resource.

        The Removal Policy controls what happens to this resource when it stops
        being managed by CloudFormation, either because you've removed it from the
        CDK application or because you've made a change that requires the resource
        to be replaced.

        The resource can be destroyed (``RemovalPolicy.DESTROY``), or left in your AWS
        account for data recovery and cleanup later (``RemovalPolicy.RETAIN``).

        This resource is retained by default.

        :param policy: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "applyRemovalPolicy", [policy]))

    @jsii.member(jsii_name="grant")
    def grant(self, user: IUser, *actions: "TableAction") -> None:
        '''(experimental) Grant a user privilege to access this table.

        :param user: -
        :param actions: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "grant", [user, *actions]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cluster")
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        return typing.cast(ICluster, jsii.get(self, "cluster"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseName")
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "databaseName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tableColumns")
    def table_columns(self) -> typing.List[Column]:
        '''(experimental) The columns of the table.

        :stability: experimental
        '''
        return typing.cast(typing.List[Column], jsii.get(self, "tableColumns"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tableName")
    def table_name(self) -> builtins.str:
        '''(experimental) Name of the table.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "tableName"))


@jsii.enum(jsii_type="@aws-cdk/aws-redshift.TableAction")
class TableAction(enum.Enum):
    '''(experimental) An action that a Redshift user can be granted privilege to perform on a table.

    :stability: experimental

    Example::

        database_name = "databaseName"
        username = "myuser"
        table_name = "mytable"
        
        user = User(self, "User",
            username=username,
            cluster=cluster,
            database_name=database_name
        )
        table = Table(self, "Table",
            table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
            cluster=cluster,
            database_name=database_name
        )
        table.grant(user, TableAction.INSERT)
    '''

    SELECT = "SELECT"
    '''(experimental) Grants privilege to select data from a table or view using a SELECT statement.

    :stability: experimental
    '''
    INSERT = "INSERT"
    '''(experimental) Grants privilege to load data into a table using an INSERT statement or a COPY statement.

    :stability: experimental
    '''
    UPDATE = "UPDATE"
    '''(experimental) Grants privilege to update a table column using an UPDATE statement.

    :stability: experimental
    '''
    DELETE = "DELETE"
    '''(experimental) Grants privilege to delete a data row from a table.

    :stability: experimental
    '''
    DROP = "DROP"
    '''(experimental) Grants privilege to drop a table.

    :stability: experimental
    '''
    REFERENCES = "REFERENCES"
    '''(experimental) Grants privilege to create a foreign key constraint.

    You need to grant this privilege on both the referenced table and the referencing table; otherwise, the user can't create the constraint.

    :stability: experimental
    '''
    ALL = "ALL"
    '''(experimental) Grants all available privileges at once to the specified user or user group.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.TableAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "cluster": "cluster",
        "database_name": "databaseName",
        "table_columns": "tableColumns",
        "table_name": "tableName",
    },
)
class TableAttributes:
    def __init__(
        self,
        *,
        cluster: ICluster,
        database_name: builtins.str,
        table_columns: typing.Sequence[Column],
        table_name: builtins.str,
    ) -> None:
        '''(experimental) A full specification of a Redshift table that can be used to import it fluently into the CDK application.

        :param cluster: (experimental) The cluster where the table is located.
        :param database_name: (experimental) The name of the database where the table is located.
        :param table_columns: (experimental) The columns of the table.
        :param table_name: (experimental) Name of the table.

        :stability: experimental

        Example::

            database_name = "databaseName"
            username = "myuser"
            table_name = "mytable"
            
            user = User.from_user_attributes(self, "User",
                username=username,
                password=SecretValue.plain_text("NOT_FOR_PRODUCTION"),
                cluster=cluster,
                database_name=database_name
            )
            table = Table.from_table_attributes(self, "Table",
                table_name=table_name,
                table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
                cluster=cluster,
                database_name="databaseName"
            )
            table.grant(user, TableAction.INSERT)
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster": cluster,
            "database_name": database_name,
            "table_columns": table_columns,
            "table_name": table_name,
        }

    @builtins.property
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        result = self._values.get("cluster")
        assert result is not None, "Required property 'cluster' is missing"
        return typing.cast(ICluster, result)

    @builtins.property
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        result = self._values.get("database_name")
        assert result is not None, "Required property 'database_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def table_columns(self) -> typing.List[Column]:
        '''(experimental) The columns of the table.

        :stability: experimental
        '''
        result = self._values.get("table_columns")
        assert result is not None, "Required property 'table_columns' is missing"
        return typing.cast(typing.List[Column], result)

    @builtins.property
    def table_name(self) -> builtins.str:
        '''(experimental) Name of the table.

        :stability: experimental
        '''
        result = self._values.get("table_name")
        assert result is not None, "Required property 'table_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TableAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-redshift.TableDistStyle")
class TableDistStyle(enum.Enum):
    '''(experimental) The data distribution style of a table.

    :stability: experimental

    Example::

        Table(self, "Table",
            table_columns=[Column(name="col1", data_type="varchar(4)", dist_key=True), Column(name="col2", data_type="float")
            ],
            cluster=cluster,
            database_name="databaseName",
            dist_style=TableDistStyle.KEY
        )
    '''

    AUTO = "AUTO"
    '''(experimental) Amazon Redshift assigns an optimal distribution style based on the table data.

    :stability: experimental
    '''
    EVEN = "EVEN"
    '''(experimental) The data in the table is spread evenly across the nodes in a cluster in a round-robin distribution.

    :stability: experimental
    '''
    KEY = "KEY"
    '''(experimental) The data is distributed by the values in the DISTKEY column.

    :stability: experimental
    '''
    ALL = "ALL"
    '''(experimental) A copy of the entire table is distributed to every node.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.TableProps",
    jsii_struct_bases=[DatabaseOptions],
    name_mapping={
        "admin_user": "adminUser",
        "cluster": "cluster",
        "database_name": "databaseName",
        "table_columns": "tableColumns",
        "dist_style": "distStyle",
        "removal_policy": "removalPolicy",
        "sort_style": "sortStyle",
        "table_name": "tableName",
    },
)
class TableProps(DatabaseOptions):
    def __init__(
        self,
        *,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: ICluster,
        database_name: builtins.str,
        table_columns: typing.Sequence[Column],
        dist_style: typing.Optional[TableDistStyle] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        sort_style: typing.Optional["TableSortStyle"] = None,
        table_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''(experimental) Properties for configuring a Redshift table.

        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.
        :param table_columns: (experimental) The columns of the table.
        :param dist_style: (experimental) The distribution style of the table. Default: TableDistStyle.AUTO
        :param removal_policy: (experimental) The policy to apply when this resource is removed from the application. Default: cdk.RemovalPolicy.Retain
        :param sort_style: (experimental) The sort style of the table. Default: TableSortStyle.AUTO if no sort key is specified, TableSortStyle.COMPOUND if a sort key is specified
        :param table_name: (experimental) The name of the table. Default: - a name is generated

        :stability: experimental

        Example::

            Table(self, "Table",
                table_columns=[Column(name="col1", data_type="varchar(4)", dist_key=True), Column(name="col2", data_type="float")
                ],
                cluster=cluster,
                database_name="databaseName",
                dist_style=TableDistStyle.KEY
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster": cluster,
            "database_name": database_name,
            "table_columns": table_columns,
        }
        if admin_user is not None:
            self._values["admin_user"] = admin_user
        if dist_style is not None:
            self._values["dist_style"] = dist_style
        if removal_policy is not None:
            self._values["removal_policy"] = removal_policy
        if sort_style is not None:
            self._values["sort_style"] = sort_style
        if table_name is not None:
            self._values["table_name"] = table_name

    @builtins.property
    def admin_user(self) -> typing.Optional[aws_cdk.aws_secretsmanager.ISecret]:
        '''(experimental) The secret containing credentials to a Redshift user with administrator privileges.

        Secret JSON schema: ``{ username: string; password: string }``.

        :default: - the admin secret is taken from the cluster

        :stability: experimental
        '''
        result = self._values.get("admin_user")
        return typing.cast(typing.Optional[aws_cdk.aws_secretsmanager.ISecret], result)

    @builtins.property
    def cluster(self) -> ICluster:
        '''(experimental) The cluster containing the database.

        :stability: experimental
        '''
        result = self._values.get("cluster")
        assert result is not None, "Required property 'cluster' is missing"
        return typing.cast(ICluster, result)

    @builtins.property
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database.

        :stability: experimental
        '''
        result = self._values.get("database_name")
        assert result is not None, "Required property 'database_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def table_columns(self) -> typing.List[Column]:
        '''(experimental) The columns of the table.

        :stability: experimental
        '''
        result = self._values.get("table_columns")
        assert result is not None, "Required property 'table_columns' is missing"
        return typing.cast(typing.List[Column], result)

    @builtins.property
    def dist_style(self) -> typing.Optional[TableDistStyle]:
        '''(experimental) The distribution style of the table.

        :default: TableDistStyle.AUTO

        :stability: experimental
        '''
        result = self._values.get("dist_style")
        return typing.cast(typing.Optional[TableDistStyle], result)

    @builtins.property
    def removal_policy(self) -> typing.Optional[aws_cdk.core.RemovalPolicy]:
        '''(experimental) The policy to apply when this resource is removed from the application.

        :default: cdk.RemovalPolicy.Retain

        :stability: experimental
        '''
        result = self._values.get("removal_policy")
        return typing.cast(typing.Optional[aws_cdk.core.RemovalPolicy], result)

    @builtins.property
    def sort_style(self) -> typing.Optional["TableSortStyle"]:
        '''(experimental) The sort style of the table.

        :default: TableSortStyle.AUTO if no sort key is specified, TableSortStyle.COMPOUND if a sort key is specified

        :stability: experimental
        '''
        result = self._values.get("sort_style")
        return typing.cast(typing.Optional["TableSortStyle"], result)

    @builtins.property
    def table_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the table.

        :default: - a name is generated

        :stability: experimental
        '''
        result = self._values.get("table_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TableProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-redshift.TableSortStyle")
class TableSortStyle(enum.Enum):
    '''(experimental) The sort style of a table.

    :stability: experimental

    Example::

        Table(self, "Table",
            table_columns=[Column(name="col1", data_type="varchar(4)", sort_key=True), Column(name="col2", data_type="float", sort_key=True)
            ],
            cluster=cluster,
            database_name="databaseName",
            sort_style=TableSortStyle.COMPOUND
        )
    '''

    AUTO = "AUTO"
    '''(experimental) Amazon Redshift assigns an optimal sort key based on the table data.

    :stability: experimental
    '''
    COMPOUND = "COMPOUND"
    '''(experimental) Specifies that the data is sorted using a compound key made up of all of the listed columns, in the order they are listed.

    :stability: experimental
    '''
    INTERLEAVED = "INTERLEAVED"
    '''(experimental) Specifies that the data is sorted using an interleaved sort key.

    :stability: experimental
    '''


@jsii.implements(IUser)
class User(
    aws_cdk.core.Construct,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.User",
):
    '''(experimental) A user in a Redshift cluster.

    :stability: experimental

    Example::

        import aws_cdk.aws_kms as kms
        
        
        encryption_key = kms.Key(self, "Key")
        User(self, "User",
            encryption_key=encryption_key,
            cluster=cluster,
            database_name="databaseName"
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        username: typing.Optional[builtins.str] = None,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: ICluster,
        database_name: builtins.str,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param encryption_key: (experimental) KMS key to encrypt the generated secret. Default: - the default AWS managed key is used
        :param removal_policy: (experimental) The policy to apply when this resource is removed from the application. Default: cdk.RemovalPolicy.Destroy
        :param username: (experimental) The name of the user. For valid values, see: https://docs.aws.amazon.com/redshift/latest/dg/r_names.html Default: - a name is generated
        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.

        :stability: experimental
        '''
        props = UserProps(
            encryption_key=encryption_key,
            removal_policy=removal_policy,
            username=username,
            admin_user=admin_user,
            cluster=cluster,
            database_name=database_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromUserAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_user_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        password: aws_cdk.core.SecretValue,
        username: builtins.str,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: ICluster,
        database_name: builtins.str,
    ) -> IUser:
        '''(experimental) Specify a Redshift user using credentials that already exist.

        :param scope: -
        :param id: -
        :param password: (experimental) The password of the user. Do not put passwords in CDK code directly.
        :param username: (experimental) The name of the user.
        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.

        :stability: experimental
        '''
        attrs = UserAttributes(
            password=password,
            username=username,
            admin_user=admin_user,
            cluster=cluster,
            database_name=database_name,
        )

        return typing.cast(IUser, jsii.sinvoke(cls, "fromUserAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addTablePrivileges")
    def add_table_privileges(self, table: ITable, *actions: TableAction) -> None:
        '''(experimental) Grant this user privilege to access a table.

        :param table: -
        :param actions: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "addTablePrivileges", [table, *actions]))

    @jsii.member(jsii_name="applyRemovalPolicy")
    def apply_removal_policy(self, policy: aws_cdk.core.RemovalPolicy) -> None:
        '''(experimental) Apply the given removal policy to this resource.

        The Removal Policy controls what happens to this resource when it stops
        being managed by CloudFormation, either because you've removed it from the
        CDK application or because you've made a change that requires the resource
        to be replaced.

        The resource can be destroyed (``RemovalPolicy.DESTROY``), or left in your AWS
        account for data recovery and cleanup later (``RemovalPolicy.RETAIN``).

        This resource is destroyed by default.

        :param policy: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "applyRemovalPolicy", [policy]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cluster")
    def cluster(self) -> ICluster:
        '''(experimental) The cluster where the table is located.

        :stability: experimental
        '''
        return typing.cast(ICluster, jsii.get(self, "cluster"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseName")
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database where the table is located.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "databaseName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="password")
    def password(self) -> aws_cdk.core.SecretValue:
        '''(experimental) The password of the user.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.core.SecretValue, jsii.get(self, "password"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="username")
    def username(self) -> builtins.str:
        '''(experimental) The name of the user.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "username"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="databaseProps")
    def _database_props(self) -> DatabaseOptions:
        '''
        :stability: experimental
        '''
        return typing.cast(DatabaseOptions, jsii.get(self, "databaseProps"))

    @_database_props.setter
    def _database_props(self, value: DatabaseOptions) -> None:
        jsii.set(self, "databaseProps", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.UserAttributes",
    jsii_struct_bases=[DatabaseOptions],
    name_mapping={
        "admin_user": "adminUser",
        "cluster": "cluster",
        "database_name": "databaseName",
        "password": "password",
        "username": "username",
    },
)
class UserAttributes(DatabaseOptions):
    def __init__(
        self,
        *,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: ICluster,
        database_name: builtins.str,
        password: aws_cdk.core.SecretValue,
        username: builtins.str,
    ) -> None:
        '''(experimental) A full specification of a Redshift user that can be used to import it fluently into the CDK application.

        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.
        :param password: (experimental) The password of the user. Do not put passwords in CDK code directly.
        :param username: (experimental) The name of the user.

        :stability: experimental

        Example::

            database_name = "databaseName"
            username = "myuser"
            table_name = "mytable"
            
            user = User.from_user_attributes(self, "User",
                username=username,
                password=SecretValue.plain_text("NOT_FOR_PRODUCTION"),
                cluster=cluster,
                database_name=database_name
            )
            table = Table.from_table_attributes(self, "Table",
                table_name=table_name,
                table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
                cluster=cluster,
                database_name="databaseName"
            )
            table.grant(user, TableAction.INSERT)
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster": cluster,
            "database_name": database_name,
            "password": password,
            "username": username,
        }
        if admin_user is not None:
            self._values["admin_user"] = admin_user

    @builtins.property
    def admin_user(self) -> typing.Optional[aws_cdk.aws_secretsmanager.ISecret]:
        '''(experimental) The secret containing credentials to a Redshift user with administrator privileges.

        Secret JSON schema: ``{ username: string; password: string }``.

        :default: - the admin secret is taken from the cluster

        :stability: experimental
        '''
        result = self._values.get("admin_user")
        return typing.cast(typing.Optional[aws_cdk.aws_secretsmanager.ISecret], result)

    @builtins.property
    def cluster(self) -> ICluster:
        '''(experimental) The cluster containing the database.

        :stability: experimental
        '''
        result = self._values.get("cluster")
        assert result is not None, "Required property 'cluster' is missing"
        return typing.cast(ICluster, result)

    @builtins.property
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database.

        :stability: experimental
        '''
        result = self._values.get("database_name")
        assert result is not None, "Required property 'database_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def password(self) -> aws_cdk.core.SecretValue:
        '''(experimental) The password of the user.

        Do not put passwords in CDK code directly.

        :stability: experimental
        '''
        result = self._values.get("password")
        assert result is not None, "Required property 'password' is missing"
        return typing.cast(aws_cdk.core.SecretValue, result)

    @builtins.property
    def username(self) -> builtins.str:
        '''(experimental) The name of the user.

        :stability: experimental
        '''
        result = self._values.get("username")
        assert result is not None, "Required property 'username' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "UserAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-redshift.UserProps",
    jsii_struct_bases=[DatabaseOptions],
    name_mapping={
        "admin_user": "adminUser",
        "cluster": "cluster",
        "database_name": "databaseName",
        "encryption_key": "encryptionKey",
        "removal_policy": "removalPolicy",
        "username": "username",
    },
)
class UserProps(DatabaseOptions):
    def __init__(
        self,
        *,
        admin_user: typing.Optional[aws_cdk.aws_secretsmanager.ISecret] = None,
        cluster: ICluster,
        database_name: builtins.str,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        username: typing.Optional[builtins.str] = None,
    ) -> None:
        '''(experimental) Properties for configuring a Redshift user.

        :param admin_user: (experimental) The secret containing credentials to a Redshift user with administrator privileges. Secret JSON schema: ``{ username: string; password: string }``. Default: - the admin secret is taken from the cluster
        :param cluster: (experimental) The cluster containing the database.
        :param database_name: (experimental) The name of the database.
        :param encryption_key: (experimental) KMS key to encrypt the generated secret. Default: - the default AWS managed key is used
        :param removal_policy: (experimental) The policy to apply when this resource is removed from the application. Default: cdk.RemovalPolicy.Destroy
        :param username: (experimental) The name of the user. For valid values, see: https://docs.aws.amazon.com/redshift/latest/dg/r_names.html Default: - a name is generated

        :stability: experimental

        Example::

            import aws_cdk.aws_kms as kms
            
            
            encryption_key = kms.Key(self, "Key")
            User(self, "User",
                encryption_key=encryption_key,
                cluster=cluster,
                database_name="databaseName"
            )
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cluster": cluster,
            "database_name": database_name,
        }
        if admin_user is not None:
            self._values["admin_user"] = admin_user
        if encryption_key is not None:
            self._values["encryption_key"] = encryption_key
        if removal_policy is not None:
            self._values["removal_policy"] = removal_policy
        if username is not None:
            self._values["username"] = username

    @builtins.property
    def admin_user(self) -> typing.Optional[aws_cdk.aws_secretsmanager.ISecret]:
        '''(experimental) The secret containing credentials to a Redshift user with administrator privileges.

        Secret JSON schema: ``{ username: string; password: string }``.

        :default: - the admin secret is taken from the cluster

        :stability: experimental
        '''
        result = self._values.get("admin_user")
        return typing.cast(typing.Optional[aws_cdk.aws_secretsmanager.ISecret], result)

    @builtins.property
    def cluster(self) -> ICluster:
        '''(experimental) The cluster containing the database.

        :stability: experimental
        '''
        result = self._values.get("cluster")
        assert result is not None, "Required property 'cluster' is missing"
        return typing.cast(ICluster, result)

    @builtins.property
    def database_name(self) -> builtins.str:
        '''(experimental) The name of the database.

        :stability: experimental
        '''
        result = self._values.get("database_name")
        assert result is not None, "Required property 'database_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''(experimental) KMS key to encrypt the generated secret.

        :default: - the default AWS managed key is used

        :stability: experimental
        '''
        result = self._values.get("encryption_key")
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], result)

    @builtins.property
    def removal_policy(self) -> typing.Optional[aws_cdk.core.RemovalPolicy]:
        '''(experimental) The policy to apply when this resource is removed from the application.

        :default: cdk.RemovalPolicy.Destroy

        :stability: experimental
        '''
        result = self._values.get("removal_policy")
        return typing.cast(typing.Optional[aws_cdk.core.RemovalPolicy], result)

    @builtins.property
    def username(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the user.

        For valid values, see: https://docs.aws.amazon.com/redshift/latest/dg/r_names.html

        :default: - a name is generated

        :stability: experimental
        '''
        result = self._values.get("username")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "UserProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(ICluster)
class Cluster(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.Cluster",
):
    '''(experimental) Create a Redshift cluster a given number of nodes.

    :stability: experimental
    :resource: AWS::Redshift::Cluster

    Example::

        import aws_cdk.aws_ec2 as ec2
        
        
        vpc = ec2.Vpc(self, "Vpc")
        cluster = Cluster(self, "Redshift",
            master_user=Login(
                master_username="admin"
            ),
            vpc=vpc
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        master_user: Login,
        vpc: aws_cdk.aws_ec2.IVpc,
        cluster_name: typing.Optional[builtins.str] = None,
        cluster_type: typing.Optional[ClusterType] = None,
        default_database_name: typing.Optional[builtins.str] = None,
        encrypted: typing.Optional[builtins.bool] = None,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        logging_bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
        logging_key_prefix: typing.Optional[builtins.str] = None,
        node_type: typing.Optional[NodeType] = None,
        number_of_nodes: typing.Optional[jsii.Number] = None,
        parameter_group: typing.Optional[IClusterParameterGroup] = None,
        port: typing.Optional[jsii.Number] = None,
        preferred_maintenance_window: typing.Optional[builtins.str] = None,
        publicly_accessible: typing.Optional[builtins.bool] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        roles: typing.Optional[typing.Sequence[aws_cdk.aws_iam.IRole]] = None,
        security_groups: typing.Optional[typing.Sequence[aws_cdk.aws_ec2.ISecurityGroup]] = None,
        subnet_group: typing.Optional[IClusterSubnetGroup] = None,
        vpc_subnets: typing.Optional[aws_cdk.aws_ec2.SubnetSelection] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param master_user: (experimental) Username and password for the administrative user.
        :param vpc: (experimental) The VPC to place the cluster in.
        :param cluster_name: (experimental) An optional identifier for the cluster. Default: - A name is automatically generated.
        :param cluster_type: (experimental) Settings for the individual instances that are launched. Default: {@link ClusterType.MULTI_NODE}
        :param default_database_name: (experimental) Name of a database which is automatically created inside the cluster. Default: - default_db
        :param encrypted: (experimental) Whether to enable encryption of data at rest in the cluster. Default: true
        :param encryption_key: (experimental) The KMS key to use for encryption of data at rest. Default: - AWS-managed key, if encryption at rest is enabled
        :param logging_bucket: (experimental) Bucket to send logs to. Logging information includes queries and connection attempts, for the specified Amazon Redshift cluster. Default: - No Logs
        :param logging_key_prefix: (experimental) Prefix used for logging. Default: - no prefix
        :param node_type: (experimental) The node type to be provisioned for the cluster. Default: {@link NodeType.DC2_LARGE}
        :param number_of_nodes: (experimental) Number of compute nodes in the cluster. Only specify this property for multi-node clusters. Value must be at least 2 and no more than 100. Default: - 2 if ``clusterType`` is ClusterType.MULTI_NODE, undefined otherwise
        :param parameter_group: (experimental) Additional parameters to pass to the database engine https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html. Default: - No parameter group.
        :param port: (experimental) What port to listen on. Default: - The default for the engine is used.
        :param preferred_maintenance_window: (experimental) A preferred maintenance window day/time range. Should be specified as a range ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). Example: 'Sun:23:45-Mon:00:15' Default: - 30-minute window selected at random from an 8-hour block of time for each AWS Region, occurring on a random day of the week.
        :param publicly_accessible: (experimental) Whether to make cluster publicly accessible. Default: false
        :param removal_policy: (experimental) The removal policy to apply when the cluster and its instances are removed from the stack or replaced during an update. Default: RemovalPolicy.RETAIN
        :param roles: (experimental) A list of AWS Identity and Access Management (IAM) role that can be used by the cluster to access other AWS services. Specify a maximum of 10 roles. Default: - No role is attached to the cluster.
        :param security_groups: (experimental) Security group. Default: - a new security group is created.
        :param subnet_group: (experimental) A cluster subnet group to use with this cluster. Default: - a new subnet group will be created.
        :param vpc_subnets: (experimental) Where to place the instances within the VPC. Default: - private subnets

        :stability: experimental
        '''
        props = ClusterProps(
            master_user=master_user,
            vpc=vpc,
            cluster_name=cluster_name,
            cluster_type=cluster_type,
            default_database_name=default_database_name,
            encrypted=encrypted,
            encryption_key=encryption_key,
            logging_bucket=logging_bucket,
            logging_key_prefix=logging_key_prefix,
            node_type=node_type,
            number_of_nodes=number_of_nodes,
            parameter_group=parameter_group,
            port=port,
            preferred_maintenance_window=preferred_maintenance_window,
            publicly_accessible=publicly_accessible,
            removal_policy=removal_policy,
            roles=roles,
            security_groups=security_groups,
            subnet_group=subnet_group,
            vpc_subnets=vpc_subnets,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromClusterAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_cluster_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        cluster_endpoint_address: builtins.str,
        cluster_endpoint_port: jsii.Number,
        cluster_name: builtins.str,
        security_groups: typing.Optional[typing.Sequence[aws_cdk.aws_ec2.ISecurityGroup]] = None,
    ) -> ICluster:
        '''(experimental) Import an existing DatabaseCluster from properties.

        :param scope: -
        :param id: -
        :param cluster_endpoint_address: (experimental) Cluster endpoint address.
        :param cluster_endpoint_port: (experimental) Cluster endpoint port.
        :param cluster_name: (experimental) Identifier for the cluster.
        :param security_groups: (experimental) The security groups of the redshift cluster. Default: no security groups will be attached to the import

        :stability: experimental
        '''
        attrs = ClusterAttributes(
            cluster_endpoint_address=cluster_endpoint_address,
            cluster_endpoint_port=cluster_endpoint_port,
            cluster_name=cluster_name,
            security_groups=security_groups,
        )

        return typing.cast(ICluster, jsii.sinvoke(cls, "fromClusterAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addRotationMultiUser")
    def add_rotation_multi_user(
        self,
        id: builtins.str,
        *,
        secret: aws_cdk.aws_secretsmanager.ISecret,
        automatically_after: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> aws_cdk.aws_secretsmanager.SecretRotation:
        '''(experimental) Adds the multi user rotation to this cluster.

        :param id: -
        :param secret: (experimental) The secret to rotate. It must be a JSON string with the following format:: { "engine": <required: database engine>, "host": <required: instance host name>, "username": <required: username>, "password": <required: password>, "dbname": <optional: database name>, "port": <optional: if not specified, default port will be used>, "masterarn": <required: the arn of the master secret which will be used to create users/change passwords> }
        :param automatically_after: (experimental) Specifies the number of days after the previous rotation before Secrets Manager triggers the next automatic rotation. Default: Duration.days(30)

        :stability: experimental
        '''
        options = RotationMultiUserOptions(
            secret=secret, automatically_after=automatically_after
        )

        return typing.cast(aws_cdk.aws_secretsmanager.SecretRotation, jsii.invoke(self, "addRotationMultiUser", [id, options]))

    @jsii.member(jsii_name="addRotationSingleUser")
    def add_rotation_single_user(
        self,
        automatically_after: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> aws_cdk.aws_secretsmanager.SecretRotation:
        '''(experimental) Adds the single user rotation of the master password to this cluster.

        :param automatically_after: Specifies the number of days after the previous rotation before Secrets Manager triggers the next automatic rotation.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.aws_secretsmanager.SecretRotation, jsii.invoke(self, "addRotationSingleUser", [automatically_after]))

    @jsii.member(jsii_name="asSecretAttachmentTarget")
    def as_secret_attachment_target(
        self,
    ) -> aws_cdk.aws_secretsmanager.SecretAttachmentTargetProps:
        '''(experimental) Renders the secret attachment target specifications.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.aws_secretsmanager.SecretAttachmentTargetProps, jsii.invoke(self, "asSecretAttachmentTarget", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterEndpoint")
    def cluster_endpoint(self) -> Endpoint:
        '''(experimental) The endpoint to use for read/write operations.

        :stability: experimental
        '''
        return typing.cast(Endpoint, jsii.get(self, "clusterEndpoint"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterName")
    def cluster_name(self) -> builtins.str:
        '''(experimental) Identifier of the cluster.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> aws_cdk.aws_ec2.Connections:
        '''(experimental) Access to the network connections.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.aws_ec2.Connections, jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="secret")
    def secret(self) -> typing.Optional[aws_cdk.aws_secretsmanager.ISecret]:
        '''(experimental) The secret attached to this cluster.

        :stability: experimental
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_secretsmanager.ISecret], jsii.get(self, "secret"))


@jsii.implements(IClusterParameterGroup)
class ClusterParameterGroup(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.ClusterParameterGroup",
):
    '''(experimental) A cluster parameter group.

    :stability: experimental
    :resource: AWS::Redshift::ClusterParameterGroup

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_redshift as redshift
        
        cluster_parameter_group = redshift.ClusterParameterGroup(self, "MyClusterParameterGroup",
            parameters={
                "parameters_key": "parameters"
            },
        
            # the properties below are optional
            description="description"
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        description: typing.Optional[builtins.str] = None,
        parameters: typing.Mapping[builtins.str, builtins.str],
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param description: (experimental) Description for this parameter group. Default: a CDK generated description
        :param parameters: (experimental) The parameters in this parameter group.

        :stability: experimental
        '''
        props = ClusterParameterGroupProps(
            description=description, parameters=parameters
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromClusterParameterGroupName") # type: ignore[misc]
    @builtins.classmethod
    def from_cluster_parameter_group_name(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        cluster_parameter_group_name: builtins.str,
    ) -> IClusterParameterGroup:
        '''(experimental) Imports a parameter group.

        :param scope: -
        :param id: -
        :param cluster_parameter_group_name: -

        :stability: experimental
        '''
        return typing.cast(IClusterParameterGroup, jsii.sinvoke(cls, "fromClusterParameterGroupName", [scope, id, cluster_parameter_group_name]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterParameterGroupName")
    def cluster_parameter_group_name(self) -> builtins.str:
        '''(experimental) The name of the parameter group.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterParameterGroupName"))


@jsii.implements(IClusterSubnetGroup)
class ClusterSubnetGroup(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-redshift.ClusterSubnetGroup",
):
    '''(experimental) Class for creating a Redshift cluster subnet group.

    :stability: experimental
    :resource: AWS::Redshift::ClusterSubnetGroup

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_ec2 as ec2
        import aws_cdk.aws_redshift as redshift
        import aws_cdk.core as cdk
        
        # subnet is of type Subnet
        # subnet_filter is of type SubnetFilter
        # vpc is of type Vpc
        
        cluster_subnet_group = redshift.ClusterSubnetGroup(self, "MyClusterSubnetGroup",
            description="description",
            vpc=vpc,
        
            # the properties below are optional
            removal_policy=cdk.RemovalPolicy.DESTROY,
            vpc_subnets=ec2.SubnetSelection(
                availability_zones=["availabilityZones"],
                one_per_az=False,
                subnet_filters=[subnet_filter],
                subnet_group_name="subnetGroupName",
                subnet_name="subnetName",
                subnets=[subnet],
                subnet_type=ec2.SubnetType.ISOLATED
            )
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        description: builtins.str,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        vpc: aws_cdk.aws_ec2.IVpc,
        vpc_subnets: typing.Optional[aws_cdk.aws_ec2.SubnetSelection] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param description: (experimental) Description of the subnet group.
        :param removal_policy: (experimental) The removal policy to apply when the subnet group are removed from the stack or replaced during an update. Default: RemovalPolicy.RETAIN
        :param vpc: (experimental) The VPC to place the subnet group in.
        :param vpc_subnets: (experimental) Which subnets within the VPC to associate with this group. Default: - private subnets

        :stability: experimental
        '''
        props = ClusterSubnetGroupProps(
            description=description,
            removal_policy=removal_policy,
            vpc=vpc,
            vpc_subnets=vpc_subnets,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromClusterSubnetGroupName") # type: ignore[misc]
    @builtins.classmethod
    def from_cluster_subnet_group_name(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        cluster_subnet_group_name: builtins.str,
    ) -> IClusterSubnetGroup:
        '''(experimental) Imports an existing subnet group by name.

        :param scope: -
        :param id: -
        :param cluster_subnet_group_name: -

        :stability: experimental
        '''
        return typing.cast(IClusterSubnetGroup, jsii.sinvoke(cls, "fromClusterSubnetGroupName", [scope, id, cluster_subnet_group_name]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clusterSubnetGroupName")
    def cluster_subnet_group_name(self) -> builtins.str:
        '''(experimental) The name of the cluster subnet group.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "clusterSubnetGroupName"))


__all__ = [
    "CfnCluster",
    "CfnClusterParameterGroup",
    "CfnClusterParameterGroupProps",
    "CfnClusterProps",
    "CfnClusterSecurityGroup",
    "CfnClusterSecurityGroupIngress",
    "CfnClusterSecurityGroupIngressProps",
    "CfnClusterSecurityGroupProps",
    "CfnClusterSubnetGroup",
    "CfnClusterSubnetGroupProps",
    "CfnEndpointAccess",
    "CfnEndpointAccessProps",
    "CfnEndpointAuthorization",
    "CfnEndpointAuthorizationProps",
    "CfnEventSubscription",
    "CfnEventSubscriptionProps",
    "CfnScheduledAction",
    "CfnScheduledActionProps",
    "Cluster",
    "ClusterAttributes",
    "ClusterParameterGroup",
    "ClusterParameterGroupProps",
    "ClusterProps",
    "ClusterSubnetGroup",
    "ClusterSubnetGroupProps",
    "ClusterType",
    "Column",
    "DatabaseOptions",
    "DatabaseSecret",
    "DatabaseSecretProps",
    "Endpoint",
    "ICluster",
    "IClusterParameterGroup",
    "IClusterSubnetGroup",
    "ITable",
    "IUser",
    "Login",
    "NodeType",
    "RotationMultiUserOptions",
    "Table",
    "TableAction",
    "TableAttributes",
    "TableDistStyle",
    "TableProps",
    "TableSortStyle",
    "User",
    "UserAttributes",
    "UserProps",
]

publication.publish()
