def test_update_password(): # create a test database name = 'u%s' % str(uuid.uuid4()).replace('-', '') event = Event('Create', name, with_database=True) event['DeletionPolicy'] = 'Drop' response = handler(event, {}) assert response['Status'] == 'SUCCESS', '%s' % response['Reason'] assert 'PhysicalResourceId' in response physical_resource_id = response['PhysicalResourceId'] expect_id = 'postgresql:localhost:5432:postgres:%(name)s:%(name)s' % {'name': name} assert physical_resource_id == expect_id, 'expected %s, got %s' % (expect_id, physical_resource_id) # update the password event = Event('Update', name, physical_resource_id, with_database=True) event['Password'] = '******' response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] with event.test_user_connection() as connection: pass # update the user is not possible event = Event('Update', name + '-', physical_resource_id, with_database=True) response = handler(event, {}) assert response['Status'] == 'FAILED', response['Reason'] # delete the created database event['User'] = name event['ResourceProperties']['DeletionPolicy'] = 'Drop' event['RequestType'] = 'Delete' response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason']
def test_password_parameter_use(): ssm = boto3.client('ssm') uuid_string = str(uuid.uuid4()).replace('-', '') name = 'user_%s' % uuid_string user_password_name = 'p%s' % uuid_string dbowner_password_name = 'o%s' % uuid_string try: event = Event('Create', name) user_password = str(uuid.uuid4()) del event['ResourceProperties']['Password'] event['ResourceProperties']['PasswordParameterName'] = user_password_name dbowner_password = event['ResourceProperties']['Database']['Password'] del event['ResourceProperties']['Database']['Password'] event['ResourceProperties']['Database']['PasswordParameterName'] = dbowner_password_name ssm.put_parameter(Name=user_password_name, Value=user_password, Type='SecureString', Overwrite=True) ssm.put_parameter(Name=dbowner_password_name, Value=dbowner_password, Type='SecureString', Overwrite=True) response = handler(event, {}) with event.test_user_connection(user_password) as connection: pass event['PhysicalResourceId'] = response['PhysicalResourceId'] event['ResourceProperties']['DeletionPolicy'] = 'Drop' response = handler(event, {}) except Exception as e: sys.stderr.write('%s\n' % e) raise finally: ssm.delete_parameter(Name=user_password_name) ssm.delete_parameter(Name=dbowner_password_name)
def test_create_database(): # create a test database name = 'u%s' % str(uuid.uuid4()).replace('-', '') event = Event('Create', name, with_database=True) response = handler(event, {}) assert response['Status'] == 'SUCCESS', '%s' % response['Reason'] assert 'PhysicalResourceId' in response physical_resource_id = response['PhysicalResourceId'] expect_id = 'postgresql:localhost:5432:postgres:%(name)s:%(name)s' % { 'name': name } assert physical_resource_id == expect_id, 'expected %s, got %s' % ( expect_id, physical_resource_id) # create the database again response = handler(event, {}) assert response['Status'] == 'SUCCESS', '%s' % response['Reason'] # delete non existing database event = Event('Delete', name + "-", physical_resource_id + '-') response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] # drop the login to the database event = Event('Delete', name, physical_resource_id, with_database=True) response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] try: with event.test_user_connection() as connection: assert False, 'succesfully logged in to delete user' except: pass with event.test_owner_connection() as connection: with connection.cursor() as cursor: cursor.execute( 'SELECT 1 FROM pg_catalog.pg_database WHERE datname = %s', [name]) rows = cursor.fetchall() assert len(rows) == 1, 'database %s was dropped' % name # drop the database event = Event('Delete', name, physical_resource_id, with_database=True) event['ResourceProperties']['DeletionPolicy'] = 'Drop' response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] with event.test_owner_connection() as connection: with connection.cursor() as cursor: cursor.execute( 'SELECT 1 FROM pg_catalog.pg_database WHERE datname = %s', [name]) rows = cursor.fetchall() assert len(rows) == 0, 'database %s still exists' % name
def test_password_with_special_chars(): name = 'u%s' % str(uuid.uuid4()).replace('-', '') event = Event('Create', name, with_database=False) event['ResourceProperties']['Password'] = "******" response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] with event.test_user_connection() as connection: pass assert 'PhysicalResourceId' in response physical_resource_id = response['PhysicalResourceId'] # delete the created user event = Event('Delete', name, physical_resource_id) response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason']
def test_invalid_delete(): event = Event( 'Delete', "noop", 'postgresql:localhost:5432:postgres:%(name)s:%(name)s' % {'name': 'noop'}) del event['ResourceProperties']['User'] response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason']
def handler(request, context): logging.basicConfig(level=os.getenv("LOG_LEVEL", "INFO")) if request['ResourceType'] == 'Custom::PostgreSQLSchema': return postgresql_schema_provider.handler(request, context) elif request['ResourceType'] == 'Custom::PostgreSQLRoleGrant': return postgresql_role_grant_provider.handler(request, context) else: return postgresql_user_provider.handler(request, context)
def test_create_user_iam_authentication(): # create a test user name = 'u%s' % str(uuid.uuid4()).replace('-', '') event = Event('Create', name, with_database=False, with_iam_authentication=True) # create rds_iam role with event.test_owner_connection() as connection: with connection.cursor() as cursor: cursor.execute('DROP ROLE IF EXISTS rds_iam; CREATE ROLE rds_iam;') response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] assert 'PhysicalResourceId' in response physical_resource_id = response['PhysicalResourceId'] expect_id = 'postgresql:localhost:5432:postgres::%(name)s' % {'name': name} assert physical_resource_id == expect_id, 'expected %s, got %s' % (expect_id, physical_resource_id) with event.test_user_connection() as connection: pass event = Event('Create', name, with_database=True, with_iam_authentication=True) response = handler(event, {}) assert response['Status'] == 'SUCCESS', '%s' % response['Reason'] # delete the created user event = Event('Delete', name, physical_resource_id) response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] try: with event.test_user_connection() as connection: assert False, 'succesfully logged in to delete user' except: pass event = Event('Delete', name, physical_resource_id, with_database=True) event['ResourceProperties']['DeletionPolicy'] = 'Drop' response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason']
def test_create_user(): # create a test user name = 'u%s' % str(uuid.uuid4()).replace('-', '') event = Event('Create', name, with_database=False) response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] assert 'PhysicalResourceId' in response physical_resource_id = response['PhysicalResourceId'] expect_id = 'postgresql:localhost:5432:postgres::%(name)s' % {'name': name} assert physical_resource_id == expect_id, 'expected %s, got %s' % ( expect_id, physical_resource_id) with event.test_user_connection() as connection: pass event = Event('Create', name, with_database=True) response = handler(event, {}) assert response['Status'] == 'SUCCESS', '%s' % response['Reason'] # delete non existing user event = Event('Delete', name + "-", physical_resource_id + '-') response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] # delete the created user event = Event('Delete', name, physical_resource_id) response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason'] try: with event.test_user_connection() as connection: assert False, 'succesfully logged in to delete user' except: pass event = Event('Delete', name, physical_resource_id, with_database=True) event['ResourceProperties']['DeletionPolicy'] = 'Drop' response = handler(event, {}) assert response['Status'] == 'SUCCESS', response['Reason']
def test_invalid_user_name(): event = Event('Create', 'a-user', with_database=False) response = handler(event, {}) assert response['Status'] == 'FAILED', response['Reason']