def handler()

in lambda/python/cfn_example_functions/manage_user.py [0:0]


def handler(event: dict, context):
    """
    The entry point of an execution only task is to guarantee that returned object is JSON serializable.
    """
    try:
        logger.debug(json.dumps(event))
        props = event[CFN_RESOURCE_PROPERTIES]
        old_props = event.get(CFN_OLD_RESOURCE_PROPERTIES)

        request_type = event[CFN_REQUEST_TYPE]

        if request_type == CFN_REQUEST_UPDATE and props[PROP_USERNAME] != old_props[PROP_USERNAME]:
            # Username changed, Redshift doesn't allow altering user rename and other properties in a single statement
            new_username = props.pop(PROP_USERNAME)
            old_username = old_props.pop(PROP_USERNAME)
            if props == old_props:
                sql_statement = f"ALTER USER {old_username} RENAME TO {new_username};"
            else:
                # TODO: Could improve such that Cloudformation handles this case by 2 separate ALTER statements
                raise ValueError("Cannot change username and other user properties in a single operation!")
        else:
            user = DBUser.make_from_dict(props)

            if request_type == CFN_REQUEST_DELETE:
                sql_statement = user.get_drop_sql()
            elif request_type == CFN_REQUEST_CREATE:
                sql_statement = user.get_create_sql()
            elif request_type == CFN_REQUEST_UPDATE:
                sql_statement = user.get_update_sql()
            else:
                raise ValueError(f"{CFN_REQUEST_TYPE} must be one of {CFN_REQUEST_TYPES}")

        event[EVENT_SQL_STATEMENT] = sql_statement

        response = lambda_client.invoke(
            FunctionName=CDK_STEPFUNCTIONS_REDSHIFT_LAMBDA,
            InvocationType='RequestResponse',
            Payload=json.dumps(event).encode('utf-8')
        )
        logger.info(f"Lambda returned {response}")

    except Exception as ve:
        fail_reason = f"User creation issue {ve}"
        cfnresponse.send(event, cfnresponse.FAILED, 'n/a', fail_reason)
        assert False, fail_reason