예제 #1
0
def test_set_iam_properties_via_aws_credentials(mocker, test_input):
    # spy = mocker.spy("redshift_connector", "set_iam_credentials")
    rp: RedshiftProperty = make_basic_redshift_property(**{
        **test_input,
        **{
            "ssl": True,
            "iam": True,
            "cluster_identifier": "blah"
        }
    })

    mocker.patch("redshift_connector.iam_helper.IamHelper.set_iam_credentials",
                 return_value=None)
    IamHelper.set_iam_properties(rp)

    for aws_cred_key, aws_cred_val in enumerate(test_input):
        if aws_cred_key == "profile":
            assert rp.profile == aws_cred_val
        if aws_cred_key == "access_key_id":
            assert rp.access_key_id == aws_cred_val
        if aws_cred_key == "secret_access_key":
            assert rp.secret_access_key == aws_cred_val
        if aws_cred_key == "password":
            assert rp.password == aws_cred_val
        if aws_cred_key == "session_token":
            assert rp.session_token == aws_cred_val
def test_set_iam_properties_enforce_client_protocol_version(_input):
    keywords: typing.Dict = {"client_protocol_version": _input}
    all_params: typing.Dict = get_set_iam_properties_args(**keywords)
    assert all_params["client_protocol_version"] == _input

    IamHelper.set_iam_properties(**all_params)
    assert all_params["info"].client_protocol_version == _input
예제 #3
0
def test_set_iam_properties_enforce_client_protocol_version(_input):
    keywords: typing.Dict[str, int] = {"client_protocol_version": _input}
    rp: RedshiftProperty = make_basic_redshift_property(**keywords)
    assert rp.client_protocol_version == _input

    IamHelper.set_iam_properties(rp)
    assert rp.client_protocol_version == _input
def test_set_iam_properties_enforce_min_ssl_mode(ssl_param):
    test_input, expected_mode = ssl_param
    keywords: typing.Dict = {"sslmode": test_input, "ssl": True}
    all_params: typing.Dict = get_set_iam_properties_args(**keywords)
    assert all_params["sslmode"] == test_input

    IamHelper.set_iam_properties(**all_params)
    assert all_params["info"].sslmode == expected_mode
예제 #5
0
def test_set_iam_properties_fails_when_non_str_credential_provider():
    keywords: typing.Dict[str, typing.Union[int, bool]] = {
        "credentials_provider": 1,
        "iam": True,
    }
    with pytest.raises(InterfaceError) as excinfo:
        IamHelper.set_iam_properties(make_basic_redshift_property(**keywords))
    assert "Invalid connection property setting" in str(excinfo.value)
예제 #6
0
def test_set_iam_properties_enforce_setting_compatibility(
        mocker, joint_params):
    test_input, expected_exception_msg = joint_params

    with pytest.raises(InterfaceError) as excinfo:
        IamHelper.set_iam_properties(
            make_basic_redshift_property(**test_input))
    assert expected_exception_msg in str(excinfo.value)
예제 #7
0
def test_set_iam_properties_calls_set_auth_props(mocker):
    mocker.patch(
        "redshift_connector.iam_helper.IdpAuthHelper.set_auth_properties",
        return_value=None)
    spy = mocker.spy(IdpAuthHelper, "set_auth_properties")
    mock_rp: MagicMock = MagicMock()
    mock_rp.credentials_provider = None
    mock_rp.is_serverless_host = False
    IamHelper.set_iam_properties(mock_rp)

    assert spy.called is True
    assert spy.call_count == 1
    assert spy.call_args[0][0] == mock_rp
예제 #8
0
def test_set_iam_properties_enforce_min_ssl_mode(ssl_param):
    test_input, expected_mode = ssl_param
    keywords: typing.Dict[str, typing.Union[str, bool]] = {
        "sslmode": test_input,
        "ssl": True
    }
    rp: RedshiftProperty = make_basic_redshift_property(**keywords)
    if test_input is None:
        assert rp.sslmode == expected_mode
    else:
        assert rp.sslmode == test_input

    IamHelper.set_iam_properties(rp)
    assert rp.sslmode == expected_mode
예제 #9
0
def test_set_iam_properties_use_redshift_auth_profile_calls_read_auth_profile(
        mocker):

    mocker.patch(
        "redshift_connector.idp_auth_helper.IdpAuthHelper.read_auth_profile",
        return_value=RedshiftProperty(kwargs={"": ""}),
    )
    mocker.patch("redshift_connector.iam_helper.IamHelper.set_iam_credentials",
                 return_value=None)
    spy = mocker.spy(IdpAuthHelper, "read_auth_profile")

    # anticipate read_auth_profile being called with the following parameters
    exp_call_arg: typing.Dict[str, str] = {
        "auth_profile": "someTestProfile",
        "access_key_id": "someAccessKeyIdValue",
        "session_token": "someSessionTokenValue",
        "secret_access_key": "someSecretAccessValue",
        "region": "someRegion",
        "endpoint_url": "someEndpointUrl",
    }

    rp: RedshiftProperty = make_basic_redshift_property(
        **{
            **{
                "iam": True,
                "ssl": True,
                "cluster_identifier": "someCluster"
            },
            **exp_call_arg
        })

    IamHelper.set_iam_properties(rp)

    assert spy.called is True
    assert spy.call_count == 1
    assert "auth_profile" in spy.call_args[1]
    assert spy.call_args[1]["auth_profile"] == exp_call_arg["auth_profile"]
    assert "iam_access_key_id" in spy.call_args[1]
    assert spy.call_args[1]["iam_access_key_id"] == exp_call_arg[
        "access_key_id"]
    assert "iam_session_token" in spy.call_args[1]
    assert spy.call_args[1]["iam_session_token"] == exp_call_arg[
        "session_token"]
    assert "iam_secret_key" in spy.call_args[1]
    assert spy.call_args[1]["iam_secret_key"] == exp_call_arg[
        "secret_access_key"]
    assert "info" in spy.call_args[1]
    assert spy.call_args[1]["info"].region == exp_call_arg["region"]
    assert spy.call_args[1]["info"].endpoint_url == exp_call_arg[
        "endpoint_url"]
예제 #10
0
def test_set_iam_properties_raises_exception_when_insufficient_boto3_version(
        mocker, boto3_version):
    mock_boto3_dist_obj = MagicMock()
    mock_boto3_dist_obj.version = boto3_version

    mocker.patch("pkg_resources.get_distribution",
                 return_value=mock_boto3_dist_obj)
    import pkg_resources

    with pytest.raises(pkg_resources.VersionConflict) as excinfo:
        IamHelper.set_iam_properties(
            make_basic_redshift_property(
                **{
                    "iam": True,
                    "ssl": True,
                    "auth_profile": "SomeTestProfile",
                    "cluster_identifier": "my_cluster"
                }))
    assert "boto3 >= 1.17.111 required for authentication via Amazon Redshift authentication profile." in str(
        excinfo.value)
def test_set_iam_properties_via_aws_credentials(mocker, test_input):
    # spy = mocker.spy("redshift_connector", "set_iam_credentials")
    info_obj: typing.Dict[str, typing.Any] = get_set_iam_properties_args(
        **test_input)
    info_obj["ssl"] = True
    info_obj["iam"] = True
    info_obj["cluster_identifier"] = "blah"

    mocker.patch("redshift_connector.iam_helper.IamHelper.set_iam_credentials",
                 return_value=None)
    IamHelper.set_iam_properties(**info_obj)

    for aws_cred_key, aws_cred_val in enumerate(test_input):
        if aws_cred_key == "profile":
            assert info_obj["info"].profile == aws_cred_val
        if aws_cred_key == "access_key_id":
            assert info_obj["info"].access_key_id == aws_cred_val
        if aws_cred_key == "secret_access_key":
            assert info_obj["info"].secret_access_key == aws_cred_val
        if aws_cred_key == "password":
            assert info_obj["info"].password == aws_cred_val
        if aws_cred_key == "session_token":
            assert info_obj["info"].session_token == aws_cred_val
예제 #12
0
def test_set_iam_properties_redshift_auth_profile_does_override(mocker):
    mock_contents: typing.Dict[str, str] = {
        "password": "******",
    }
    mock_auth_profile_contents: RedshiftProperty = RedshiftProperty(
        **mock_contents)
    mocker.patch(
        "redshift_connector.idp_auth_helper.IdpAuthHelper.read_auth_profile",
        return_value=mock_auth_profile_contents)
    mocker.patch("redshift_connector.iam_helper.IamHelper.set_iam_credentials",
                 return_value=None)
    redshift_auth_profile_spy = mocker.spy(IdpAuthHelper, "read_auth_profile")
    set_iam_crednetials_spy = mocker.spy(IamHelper, "set_iam_credentials")

    exp_call_arg: typing.Dict[str, str] = {
        "auth_profile": "someTestProfile",
        "access_key_id": "someAccessKeyIdValue",
        "session_token": "someSessionTokenValue",
        "secret_access_key": "someSecretAccessValue",
        "region": "someRegion",
        "endpoint_url": "someEndpointUrl",
    }

    rp: RedshiftProperty = make_basic_redshift_property(
        **{
            **{
                "iam": True,
                "ssl": True,
                "cluster_identifier": "someCluster"
            },
            **exp_call_arg,
        })

    res = IamHelper.set_iam_properties(rp)
    assert rp.password == mock_auth_profile_contents.password

    assert redshift_auth_profile_spy.called is True
    assert redshift_auth_profile_spy.call_count == 1
    assert res.password == mock_auth_profile_contents.password

    assert set_iam_crednetials_spy.called is True
    assert set_iam_crednetials_spy.call_count == 1
    assert set_iam_crednetials_spy.call_args[0][
        0].password == mock_auth_profile_contents.password
def test_set_iam_properties_fails_when_info_is_none(missing_param):
    keywords: typing.Dict = {missing_param: None}
    with pytest.raises(InterfaceError) as excinfo:
        IamHelper.set_iam_properties(**get_set_iam_properties_args(**keywords))
    assert "Invalid connection property setting" in str(excinfo.value)
예제 #14
0
def connect(
    user: str,
    database: str,
    password: str,
    port: int = 5439,
    host: str = "localhost",
    source_address: typing.Optional[str] = None,
    unix_sock: typing.Optional[str] = None,
    ssl: bool = True,
    sslmode: str = "verify-ca",
    timeout: typing.Optional[int] = None,
    max_prepared_statements: int = 1000,
    tcp_keepalive: bool = True,
    application_name: typing.Optional[str] = None,
    replication: typing.Optional[str] = None,
    idp_host: typing.Optional[str] = None,
    db_user: typing.Optional[str] = None,
    app_id: typing.Optional[str] = None,
    app_name: str = "amazon_aws_redshift",
    preferred_role: typing.Optional[str] = None,
    principal_arn: typing.Optional[str] = None,
    access_key_id: typing.Optional[str] = None,
    secret_access_key: typing.Optional[str] = None,
    session_token: typing.Optional[str] = None,
    profile: typing.Optional[str] = None,
    credentials_provider: typing.Optional[str] = None,
    region: typing.Optional[str] = None,
    cluster_identifier: typing.Optional[str] = None,
    iam: bool = False,
    client_id: typing.Optional[str] = None,
    idp_tenant: typing.Optional[str] = None,
    client_secret: typing.Optional[str] = None,
    partner_sp_id: typing.Optional[str] = None,
    idp_response_timeout: int = 120,
    listen_port: int = 7890,
    login_url: typing.Optional[str] = None,
    auto_create: bool = False,
    db_groups: typing.List[str] = list(),
    force_lowercase: bool = False,
    allow_db_user_override: bool = False,
    client_protocol_version: int = DEFAULT_PROTOCOL_VERSION,
    database_metadata_current_db_only: bool = True,
    ssl_insecure: typing.Optional[bool] = None,
    web_identity_token: typing.Optional[str] = None,
    role_session_name: typing.Optional[str] = None,
    role_arn: typing.Optional[str] = None,
) -> Connection:

    info: RedshiftProperty = RedshiftProperty()
    IamHelper.set_iam_properties(
        info,
        user=user,
        host=host,
        database=database,
        port=port,
        password=password,
        source_address=source_address,
        unix_sock=unix_sock,
        ssl=ssl,
        sslmode=sslmode,
        timeout=timeout,
        max_prepared_statements=max_prepared_statements,
        tcp_keepalive=tcp_keepalive,
        application_name=application_name,
        replication=replication,
        idp_host=idp_host,
        db_user=db_user,
        app_id=app_id,
        app_name=app_name,
        preferred_role=preferred_role,
        principal_arn=principal_arn,
        access_key_id=access_key_id,
        secret_access_key=secret_access_key,
        session_token=session_token,
        profile=profile,
        credentials_provider=credentials_provider,
        region=region,
        cluster_identifier=cluster_identifier,
        iam=iam,
        client_id=client_id,
        idp_tenant=idp_tenant,
        client_secret=client_secret,
        partner_sp_id=partner_sp_id,
        idp_response_timeout=idp_response_timeout,
        listen_port=listen_port,
        login_url=login_url,
        auto_create=auto_create,
        db_groups=db_groups,
        force_lowercase=force_lowercase,
        allow_db_user_override=allow_db_user_override,
        client_protocol_version=client_protocol_version,
        database_metadata_current_db_only=database_metadata_current_db_only,
        ssl_insecure=ssl_insecure,
        web_identity_token=web_identity_token,
        role_session_name=role_session_name,
        role_arn=role_arn,
    )

    return Connection(
        user=info.user_name,
        host=info.host,
        database=info.db_name,
        port=info.port,
        password=info.password,
        source_address=info.source_address,
        unix_sock=info.unix_sock,
        ssl=info.ssl,
        sslmode=info.sslmode,
        timeout=info.timeout,
        max_prepared_statements=info.max_prepared_statements,
        tcp_keepalive=info.tcp_keepalive,
        application_name=info.application_name,
        replication=info.replication,
        client_protocol_version=info.client_protocol_version,
        database_metadata_current_db_only=database_metadata_current_db_only,
    )
def connect(
    user: str,
    database: str,
    password: str,
    port: int = 5439,
    host: str = "localhost",
    source_address: typing.Optional[str] = None,
    unix_sock: typing.Optional[str] = None,
    ssl: bool = True,
    sslmode: str = "verify-ca",
    timeout: typing.Optional[int] = None,
    max_prepared_statements: int = 1000,
    tcp_keepalive: bool = True,
    application_name: typing.Optional[str] = None,
    replication: typing.Optional[str] = None,
    idp_host: typing.Optional[str] = None,
    db_user: typing.Optional[str] = None,
    app_id: typing.Optional[str] = None,
    app_name: str = "amazon_aws_redshift",
    preferred_role: typing.Optional[str] = None,
    principal_arn: typing.Optional[str] = None,
    access_key_id: typing.Optional[str] = None,
    secret_access_key: typing.Optional[str] = None,
    session_token: typing.Optional[str] = None,
    profile: typing.Optional[str] = None,
    credentials_provider: typing.Optional[str] = None,
    region: typing.Optional[str] = None,
    cluster_identifier: typing.Optional[str] = None,
    iam: bool = False,
    client_id: typing.Optional[str] = None,
    idp_tenant: typing.Optional[str] = None,
    client_secret: typing.Optional[str] = None,
    partner_sp_id: typing.Optional[str] = None,
    idp_response_timeout: int = 120,
    listen_port: int = 7890,
    login_url: typing.Optional[str] = None,
    auto_create: bool = False,
    db_groups: typing.List[str] = list(),
    force_lowercase: bool = False,
    allow_db_user_override: bool = False,
    client_protocol_version: int = DEFAULT_PROTOCOL_VERSION,
    database_metadata_current_db_only: bool = True,
    ssl_insecure: typing.Optional[bool] = None,
    web_identity_token: typing.Optional[str] = None,
    role_session_name: typing.Optional[str] = None,
    role_arn: typing.Optional[str] = None,
) -> Connection:
    """
    Establishes a :class:`Connection` to an Amazon Redshift cluster. This function validates user input, optionally authenticates using an identity provider plugin, then constructs a :class:`Connection` object.

    Parameters
    ----------
    user : str
        The username to use for authentication with the Amazon Redshift cluster.
    password : str
        The password to use for authentication with the Amazon Redshift cluster.
    database : str
        The name of the database instance to connect to.
    host : str
        The hostname of the Amazon Redshift cluster.
    port : int
        The port number of the Amazon Redshift cluster. Default value is 5439.
    source_address : typing.Optional[str]
    unix_sock : Optional[str]
    ssl : bool
        Is SSL enabled. Default value is ``True``. SSL must be enabled when authenticating using IAM.
    sslmode : str
        The security of the connection to the Amazon Redshift cluster. 'verify-ca' and 'verify-full' are supported.
    timeout : Optional[int]
        The number of seconds before the connection to the server will timeout. By default there is no timeout.
    max_prepared_statements : int
    tcp_keepalive : Optional[bool]
        Is `TCP keepalive <https://en.wikipedia.org/wiki/Keepalive#TCP_keepalive>`_ used. The default value is ``True``.
    application_name : Optional[str]
        Sets the application name. The default value is None.
    replication : Optional[str]
        Used to run in `streaming replication mode <https://www.postgresql.org/docs/12/protocol-replication.html>`_.
    idp_host : Optional[str]
        The hostname of the IdP.
    db_user : str
        The user ID to use with Amazon Redshift
    app_id : Optional[str]
    app_name : str
        The name of the identity provider (IdP) application used for authentication.
    preferred_role : str
        The IAM role preferred for the current connection.
    principal_arn : Optional[str]
    credentials_provider : str
        The class name of the IdP that will be used for authenticating with the Amazon Redshift cluster.
    region : str
        The AWS region where the Amazon Redshift cluster is located.
    cluster_identifier : str
        The cluster identifier of the Amazon Redshift cluster.
    iam : bool
        If IAM authentication is enabled. Default value is False. IAM must be True when authenticating using an IdP.
    client_id : str
        The client id from Azure IdP.
    idp_tenant : str
        The IdP tenant.
    client_secret : str
        The client secret from Azure IdP.
    partner_sp_id : Optional[str]
    idp_response_timeout : int
        The timeout for retrieving SAML assertion from IdP. Default value is `120`.
    listen_port : int
        The listen port the IdP will send the SAML assertion to. Default value is `7890`.
    login_url : str
        The SSO url for the IdP.
    auto_create :bool
        Indicates whether the user should be created if they do not exist. Default value is `False`.
    db_groups : str
        A comma-separated list of existing database group names that the `db_user` joins for the current session.
    force_lowercase :
    allow_db_user_override : bool
        Specifies if the driver uses the `db_user` value from the SAML assertion. TDefault value is `False`.
    client_protocol_version : int
         The requested server protocol version. The default value is 1 representing `EXTENDED_RESULT_METADATA`. If the requested server protocol cannot be satisfied, a warning will be displayed to the user.
    database_metadata_current_db_only : bool
        Is `datashare <https://docs.aws.amazon.com/redshift/latest/dg/datashare-overview.html>`_ disabled. Default value is True, implying datasharing will not be used.
    ssl_insecure : bool
        Specifies if IdP host's server certificate will be verified. Default value is True

    Returns
    -------
    A Connection object associated with the specified Amazon Redshift cluster: :class:`Connection`
    """
    info: RedshiftProperty = RedshiftProperty()
    IamHelper.set_iam_properties(
        info,
        user=user,
        host=host,
        database=database,
        port=port,
        password=password,
        source_address=source_address,
        unix_sock=unix_sock,
        ssl=ssl,
        sslmode=sslmode,
        timeout=timeout,
        max_prepared_statements=max_prepared_statements,
        tcp_keepalive=tcp_keepalive,
        application_name=application_name,
        replication=replication,
        idp_host=idp_host,
        db_user=db_user,
        app_id=app_id,
        app_name=app_name,
        preferred_role=preferred_role,
        principal_arn=principal_arn,
        access_key_id=access_key_id,
        secret_access_key=secret_access_key,
        session_token=session_token,
        profile=profile,
        credentials_provider=credentials_provider,
        region=region,
        cluster_identifier=cluster_identifier,
        iam=iam,
        client_id=client_id,
        idp_tenant=idp_tenant,
        client_secret=client_secret,
        partner_sp_id=partner_sp_id,
        idp_response_timeout=idp_response_timeout,
        listen_port=listen_port,
        login_url=login_url,
        auto_create=auto_create,
        db_groups=db_groups,
        force_lowercase=force_lowercase,
        allow_db_user_override=allow_db_user_override,
        client_protocol_version=client_protocol_version,
        database_metadata_current_db_only=database_metadata_current_db_only,
        ssl_insecure=ssl_insecure,
        web_identity_token=web_identity_token,
        role_session_name=role_session_name,
        role_arn=role_arn,
    )

    return Connection(
        user=info.user_name,
        host=info.host,
        database=info.db_name,
        port=info.port,
        password=info.password,
        source_address=info.source_address,
        unix_sock=info.unix_sock,
        ssl=info.ssl,
        sslmode=info.sslmode,
        timeout=info.timeout,
        max_prepared_statements=info.max_prepared_statements,
        tcp_keepalive=info.tcp_keepalive,
        application_name=info.application_name,
        replication=info.replication,
        client_protocol_version=info.client_protocol_version,
        database_metadata_current_db_only=database_metadata_current_db_only,
    )
예제 #16
0
def test_set_iam_properties_raises_exception_when_info_is_none():
    with pytest.raises(InterfaceError) as excinfo:
        IamHelper.set_iam_properties(None)
    assert "Invalid connection property setting. info must be specified" in str(
        excinfo.value)
예제 #17
0
def connect(
    user: typing.Optional[str] = None,
    database: typing.Optional[str] = None,
    password: typing.Optional[str] = None,
    port: typing.Optional[int] = None,
    host: typing.Optional[str] = None,
    source_address: typing.Optional[str] = None,
    unix_sock: typing.Optional[str] = None,
    ssl: typing.Optional[bool] = None,
    sslmode: typing.Optional[str] = None,
    timeout: typing.Optional[int] = None,
    max_prepared_statements: typing.Optional[int] = None,
    tcp_keepalive: typing.Optional[bool] = None,
    application_name: typing.Optional[str] = None,
    replication: typing.Optional[str] = None,
    idp_host: typing.Optional[str] = None,
    db_user: typing.Optional[str] = None,
    app_id: typing.Optional[str] = None,
    app_name: typing.Optional[str] = None,
    preferred_role: typing.Optional[str] = None,
    principal_arn: typing.Optional[str] = None,
    access_key_id: typing.Optional[str] = None,
    secret_access_key: typing.Optional[str] = None,
    session_token: typing.Optional[str] = None,
    profile: typing.Optional[str] = None,
    credentials_provider: typing.Optional[str] = None,
    region: typing.Optional[str] = None,
    cluster_identifier: typing.Optional[str] = None,
    iam: typing.Optional[bool] = None,
    client_id: typing.Optional[str] = None,
    idp_tenant: typing.Optional[str] = None,
    client_secret: typing.Optional[str] = None,
    partner_sp_id: typing.Optional[str] = None,
    idp_response_timeout: typing.Optional[int] = None,
    listen_port: typing.Optional[int] = None,
    login_url: typing.Optional[str] = None,
    auto_create: typing.Optional[bool] = None,
    db_groups: typing.Optional[typing.List[str]] = None,
    force_lowercase: typing.Optional[bool] = None,
    allow_db_user_override: typing.Optional[bool] = None,
    client_protocol_version: typing.Optional[int] = None,
    database_metadata_current_db_only: typing.Optional[bool] = None,
    ssl_insecure: typing.Optional[bool] = None,
    web_identity_token: typing.Optional[str] = None,
    role_session_name: typing.Optional[str] = None,
    role_arn: typing.Optional[str] = None,
    iam_disable_cache: typing.Optional[bool] = None,
    auth_profile: typing.Optional[str] = None,
    endpoint_url: typing.Optional[str] = None,
    provider_name: typing.Optional[str] = None,
    scope: typing.Optional[str] = None,
) -> Connection:
    """
    Establishes a :class:`Connection` to an Amazon Redshift cluster. This function validates user input, optionally authenticates using an identity provider plugin, then constructs a :class:`Connection` object.

    Parameters
    ----------
    user : Optional[str]
        The username to use for authentication with the Amazon Redshift cluster.
    password : Optional[str]
        The password to use for authentication with the Amazon Redshift cluster.
    database : Optional[str]
        The name of the database instance to connect to.
    host : Optional[str]
        The hostname of the Amazon Redshift cluster.
    port : Optional[int]
        The port number of the Amazon Redshift cluster. Default value is 5439.
    source_address : typing.Optional[str]
    unix_sock : Optional[str]
    ssl : Optional[bool]
        Is SSL enabled. Default value is ``True``. SSL must be enabled when authenticating using IAM.
    sslmode : Optional[str]
        The security of the connection to the Amazon Redshift cluster. 'verify-ca' and 'verify-full' are supported.
    timeout : Optional[int]
        The number of seconds before the connection to the server will timeout. By default there is no timeout.
    max_prepared_statements : Optional[int]
    tcp_keepalive : Optional[bool]
        Is `TCP keepalive <https://en.wikipedia.org/wiki/Keepalive#TCP_keepalive>`_ used. The default value is ``True``.
    application_name : Optional[str]
        Sets the application name. The default value is None.
    replication : Optional[str]
        Used to run in `streaming replication mode <https://www.postgresql.org/docs/12/protocol-replication.html>`_.
    idp_host : Optional[str]
        The hostname of the IdP.
    db_user : Optional[str]
        The user ID to use with Amazon Redshift
    app_id : Optional[str]
    app_name : Optional[str]
        The name of the identity provider (IdP) application used for authentication.
    preferred_role : Optional[str]
        The IAM role preferred for the current connection.
    principal_arn : Optional[str]
        The ARN of the IAM entity (user or role) for which you are generating a policy.
    credentials_provider : Optional[str]
        The class name of the IdP that will be used for authenticating with the Amazon Redshift cluster.
    region : Optional[str]
        The AWS region where the Amazon Redshift cluster is located.
    cluster_identifier : Optional[str]
        The cluster identifier of the Amazon Redshift cluster.
    iam : Optional[bool]
        If IAM authentication is enabled. Default value is False. IAM must be True when authenticating using an IdP.
    client_id : Optional[str]
        The client id from Azure IdP.
    idp_tenant : Optional[str]
        The IdP tenant.
    client_secret : Optional[str]
        The client secret from Azure IdP.
    partner_sp_id : Optional[str]
        The Partner SP Id used for authentication with Ping.
    idp_response_timeout : Optional[int]
        The timeout for retrieving SAML assertion from IdP. Default value is `120`.
    listen_port : Optional[int]
        The listen port the IdP will send the SAML assertion to. Default value is `7890`.
    login_url : Optional[str]
        The SSO url for the IdP.
    auto_create : Optional[bool]
        Indicates whether the user should be created if they do not exist. Default value is `False`.
    db_groups : Optional[str]
        A comma-separated list of existing database group names that the `db_user` joins for the current session.
    force_lowercase : Optional[bool]
    allow_db_user_override : Optional[bool]
        Specifies if the driver uses the `db_user` value from the SAML assertion. TDefault value is `False`.
    client_protocol_version : Optional[int]
         The requested server protocol version. The default value is 2 representing `BINARY`. If the requested server protocol cannot be satisfied a warning will be displayed to the user and the driver will default to the highest supported protocol. See `ClientProtocolVersion` for more details.
    database_metadata_current_db_only : Optional[bool]
        Is `datashare <https://docs.aws.amazon.com/redshift/latest/dg/datashare-overview.html>`_ disabled. Default value is True, implying datasharing will not be used.
    ssl_insecure : Optional[bool]
        Specifies if IdP host's server certificate will be verified. Default value is True
    web_identity_token: Optional[str]
        A web identity token used for authentication with JWT.
    role_session_name: Optional[str]
        An identifier for the assumed role session used for authentication with JWT.
    role_arn: Optional[str]
        The role ARN used for authentication with JWT. This parameter is required when using a JWTCredentialsProvider.
    iam_disable_cache: Optional[bool]
        This option specifies whether the IAM credentials are cached. By default caching is enabled.
    auth_profile: Optional[str]
        The name of an Amazon Redshift Authentication profile having connection properties as JSON. See :class:RedshiftProperty to learn how connection properties should be named.
    endpoint_url: Optional[str]
        The Amazon Redshift endpoint url. This option is only used by AWS internal teams.
    provider_name: Optional[str]
        The name of the Redshift Native Auth Provider.
    scope: Optional[str]
        Scope for BrowserAzureOauth2CredentialsProvider authentication.
    Returns
    -------
    A Connection object associated with the specified Amazon Redshift cluster: :class:`Connection`
    """
    info: RedshiftProperty = RedshiftProperty()
    info.put("access_key_id", access_key_id)
    info.put("allow_db_user_override", allow_db_user_override)
    info.put("app_id", app_id)
    info.put("app_name", app_name)
    info.put("application_name", application_name)
    info.put("auth_profile", auth_profile)
    info.put("auto_create", auto_create)
    info.put("client_id", client_id)
    info.put("client_protocol_version", client_protocol_version)
    info.put("client_secret", client_secret)
    info.put("cluster_identifier", cluster_identifier)
    info.put("credentials_provider", credentials_provider)
    info.put("database_metadata_current_db_only",
             database_metadata_current_db_only)
    info.put("db_groups", db_groups)
    info.put("db_name", database)
    info.put("db_user", db_user)
    info.put("endpoint_url", endpoint_url)
    info.put("force_lowercase", force_lowercase)
    info.put("host", host)
    info.put("iam", iam)
    info.put("iam_disable_cache", iam_disable_cache)
    info.put("idp_host", idp_host)
    info.put("idp_response_timeout", idp_response_timeout)
    info.put("idp_tenant", idp_tenant)
    info.put("listen_port", listen_port)
    info.put("login_url", login_url)
    info.put("max_prepared_statements", max_prepared_statements)
    info.put("partner_sp_id", partner_sp_id)
    info.put("password", password)
    info.put("port", port)
    info.put("preferred_role", preferred_role)
    info.put("principal", principal_arn)
    info.put("profile", profile)
    info.put("provider_name", provider_name)
    info.put("region", region)
    info.put("replication", replication)
    info.put("role_arn", role_arn)
    info.put("role_session_name", role_session_name)
    info.put("scope", scope)
    info.put("secret_access_key", secret_access_key)
    info.put("session_token", session_token)
    info.put("source_address", source_address)
    info.put("ssl", ssl)
    info.put("ssl_insecure", ssl_insecure)
    info.put("sslmode", sslmode)
    info.put("tcp_keepalive", tcp_keepalive)
    info.put("timeout", timeout)
    info.put("unix_sock", unix_sock)
    info.put("user_name", user)
    info.put("web_identity_token", web_identity_token)

    _logger.debug(make_divider_block())
    _logger.debug("User provided connection arguments")
    _logger.debug(make_divider_block())
    _logger.debug(mask_secure_info_in_props(info).__str__())
    _logger.debug(make_divider_block())

    if (info.ssl is False) and (info.iam is True):
        raise InterfaceError(
            "Invalid connection property setting. SSL must be enabled when using IAM"
        )

    if (info.iam is False) and (info.ssl_insecure is False):
        raise InterfaceError(
            "Invalid connection property setting. IAM must be enabled when using ssl_insecure"
        )

    if info.client_protocol_version not in ClientProtocolVersion.list():
        raise InterfaceError(
            "Invalid connection property setting. client_protocol_version must be in: {}"
            .format(ClientProtocolVersion.list()))

    redshift_native_auth: bool = False
    if info.iam:
        if info.credentials_provider == "BasicJwtCredentialsProvider":
            redshift_native_auth = True
            _logger.debug("redshift_native_auth enabled")

    if not redshift_native_auth:
        IamHelper.set_iam_properties(info)

    _logger.debug(make_divider_block())
    _logger.debug(
        "Connection arguments following validation and IAM auth (if applicable)"
    )
    _logger.debug(make_divider_block())
    _logger.debug(mask_secure_info_in_props(info).__str__())
    _logger.debug(make_divider_block())

    return Connection(
        user=info.user_name,
        host=info.host,
        database=info.db_name,
        port=info.port,
        password=info.password,
        source_address=info.source_address,
        unix_sock=info.unix_sock,
        ssl=info.ssl,
        sslmode=info.sslmode,
        timeout=info.timeout,
        max_prepared_statements=info.max_prepared_statements,
        tcp_keepalive=info.tcp_keepalive,
        application_name=info.application_name,
        replication=info.replication,
        client_protocol_version=info.client_protocol_version,
        database_metadata_current_db_only=info.
        database_metadata_current_db_only,
        credentials_provider=info.credentials_provider,
        provider_name=info.provider_name,
        web_identity_token=info.web_identity_token,
    )