Skip to content

Redshift Password Rotation - Use redshift_connector module #104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions SecretsManagerRedshiftRotationSingleUser/lambda_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import json
import logging
import os
import pg
import pgdb
import redshift_connector

logger = logging.getLogger()
logger.setLevel(logging.INFO)
Expand Down Expand Up @@ -193,17 +192,22 @@ def set_secret(service_client, arn, token):
try:
with conn.cursor() as cur:
# Get escaped username via quote_ident
cur.execute("SELECT quote_ident(%s)", (pending_dict['username'],))
cur.execute("SELECT quote_ident(%s)", (pending_dict["username"],))
escaped_username = cur.fetchone()[0]
password = pending_dict["password"]

alter_role = "ALTER USER %s" % escaped_username
cur.execute(alter_role + " WITH PASSWORD %s", (pending_dict['password'],))
cur.execute(f"alter user {escaped_username} password '{password}'")
conn.commit()
logger.info("setSecret: Successfully set password for user %s in Redshift DB for secret arn %s." % (pending_dict['username'], arn))

logger.info(
"setSecret: Successfully set password for user %s in Redshift DB for secret arn %s."
% (pending_dict["username"], arn)
)
finally:
conn.close()



def test_secret(service_client, arn, token):
"""Test the pending secret against the database

Expand Down Expand Up @@ -284,7 +288,7 @@ def get_connection(secret_dict):
secret_dict (dict): The Secret Dictionary

Returns:
Connection: The pgdb.Connection object if successful. None otherwise
Connection: The redshift_connector.Connection object if successful. None otherwise

Raises:
KeyError: If the secret json does not contain the expected keys
Expand All @@ -296,13 +300,24 @@ def get_connection(secret_dict):

# Try to obtain a connection to the db
try:
conn = pgdb.connect(host=secret_dict['host'], user=secret_dict['username'], password=secret_dict['password'], database=dbname, port=port, connect_timeout=5)
logger.info("Successfully established connection as user '%s' with host: '%s'" % (secret_dict['username'], secret_dict['host']))
conn = redshift_connector.connect(
host=secret_dict["host"],
database=dbname,
port=port,
user=secret_dict["username"],
password=secret_dict["password"],
)
logger.info(
"Successfully established connection as user '%s' with host: '%s'"
% (secret_dict["username"], secret_dict["host"])
)
return conn
except pg.InternalError:
except redshift_connector.Error as e:
logger.info("Redshift Connection attempt failed with:\n %s", e)
return None



def get_secret_dict(service_client, arn, stage, token=None):
"""Gets the secret dictionary corresponding for the secret arn, stage, and token

Expand Down