faucet-common-redshift
Shared connection, credentials, and connection-pool types for the
faucet-stream Amazon Redshift
source (faucet-source-redshift) and sink (faucet-sink-redshift)
connectors.
Redshift speaks the PostgreSQL wire protocol, so the password and iam
methods connect through sqlx's Postgres driver; redshift_data_api runs every
statement through the Redshift Data API over HTTPS instead. This crate
centralises all three so TLS, auth, pooling and the Data API behave identically
on both sides.
Types
RedshiftCredentials— adjacently-tagged{ type, config }enum:password— username/password auth (the user comes from the connection block).iam— temporary database credentials over the PostgreSQL wire protocol. Set exactly one ofcluster_identifier(provisioned:redshift:GetClusterCredentialswithdb_user— default the connection'suser—auto_create,db_groups) orworkgroup_name(serverless:redshift-serverless:GetCredentials, the user comes from the IAM identity).duration_secs(900–3600) sets the lifetime;region,aws_credentialsandendpoint_urlselect how AWS is called. The pool fetches credentials on first use and again 60 s before they expire (half way through a shorter lifetime), so every connection it opens afterwards logs in with valid ones; open connections are unaffected. A refresh that fails while the current credentials are still valid is logged and retried after a backoff (a quarter of the remaining lifetime, 1–60 s), not on every use; once they have expired it fails the operation asFaucetError::Auth. Credentials are never refetched sooner than 1 s after the last fetch, even when they look expired already (a skewed clock).redshift_data_api— every statement goes through the Data API (ExecuteStatement, polled withDescribeStatementuntilFINISHED/FAILED/ABORTED, rows paged withGetStatementResult). Set exactly one ofcluster_identifier(with exactly one ofdb_userorsecret_arn) orworkgroup_name(optionalsecret_arn).host,port,userand the TLS settings are not used and may be left out;databaseis required.
RedshiftAwsCredentials— the AWS credentialsiamandredshift_data_apicall AWS with, the same shape as the other AWS connectors:default(the SDK chain),profile { name },access_key { access_key_id, secret_access_key, session_token? },assume_role { role_arn, session_name?, external_id? },web_identity.RedshiftConnection—host,port(default5439),database,user,credentials, atlstoggle (defaulttrue), and the optionaltls_mode(disable|prefer|require|verify_ca|verify_full, overridestls) +ssl_root_cert(CA PEM path for the verifying modes; without it they verify against the Mozilla root store bundled into the binary, not the operating system's). Flattened into both end configs.
Helpers
build_connect_options(&RedshiftConnection)— purePgConnectOptionsbuilder.tls: true→sslmode=require(encrypted, certificate not verified);tls: false→sslmode=prefer. Settls_mode: verify_fullwithssl_root_cert(the Redshift CA bundle) to verify the server certificate and host name;ssl_root_certwith a non-verifying mode is a config error.build_pool_lazy(conn, max)— lazily-connected pool (no I/O at construction).build_pool(conn, max)— eagerly validated pool (fails fast on bad creds).resolve_password(&RedshiftCredentials)— extracts the password (iamandredshift_data_apihave none and returnFaucetError::Config).connect_lazy(conn, max)→RedshiftPool— the wire pool forpasswordandiam;RedshiftPool::get(&CallContext)returns the pool, refreshingiamcredentials first when they are due (the callcredentials).DataApiClient::from_connection(conn, error_kind)— the Data API client for aredshift_data_apiconnection.execute(ctx, Effect, &Statement)submits (the callsubmit; aEffect::Writeis a single attempt, never resubmitted) and polls (poll, waiting throughCallContext::wait, 50 ms doubling to 1 s); a run deadline or cancel ends the wait and cancels the statement on the service, best effort. A failed poll is retried up to 4 times (250 ms doubling); when polling gives up the statement is cancelled as well, and for anEffect::Writethe error names the statement id and says whether it committed is unknown (check the destination before re-running).result_page(fetch) pages the result;queryreads a small one whole.data_api::named_parametersturns$nplaceholders into:pNparameters (NULL and empty strings are written into the SQL, since a parameter value can be neither), anddata_api::field_to_jsonrenders the typed fields throughfaucet_core::fidelity—longValuea number,doubleValuea float (float4in single precision),NUMERICtext an exact decimal string,timestamptzRFC 3339 with its offset,timestampwithout one (microsecond precision),blobValue/VARBYTEhex base64, JSON parsed with exact numbers, anything else text.
Example
host: my-cluster.abc123.us-east-1.redshift.amazonaws.com
port: 5439
database: dev
user: admin
credentials:
type: password
config:
password: ${env:REDSHIFT_PASSWORD}
tls_mode: verify_full
ssl_root_cert: /etc/ssl/redshift-ca-bundle.crt
Temporary IAM credentials for a provisioned cluster:
host: my-cluster.abc123.us-east-1.redshift.amazonaws.com
database: dev
credentials:
type: iam
config:
region: us-east-1
cluster_identifier: my-cluster
db_user: loader
db_groups:
duration_secs: 3600
aws_credentials:
The Data API against a serverless workgroup:
database: dev
credentials:
type: redshift_data_api
config:
region: us-east-1
workgroup_name: analytics
License: MIT OR Apache-2.0