diff --git a/poetry.lock b/poetry.lock index 3b9659455d..e99424b62a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "adal" @@ -5493,4 +5493,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.11" -content-hash = "971596e47325293cbc984bb5a8aabd88a211f4ff4bbd72323f5eb6a168643feb" +content-hash = "a60a856644c1282f9e2c1cc98949e47164cce6683c84b7e92de1224991014ab6" diff --git a/pyproject.toml b/pyproject.toml index b5c706a18c..514ac87d15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,6 +88,8 @@ tzlocal = "4.3.1" pyodbc = "5.1.0" debugpy = "^1.8.9" paramiko = "3.4.1" +boto3 = "1.28.8" +botocore = "1.31.8" [tool.poetry.group.all_ds] optional = true @@ -95,8 +97,6 @@ optional = true [tool.poetry.group.all_ds.dependencies] atsd-client = "3.0.5" azure-kusto-data = "0.0.35" -boto3 = "1.28.8" -botocore = "1.31.8" cassandra-driver = "3.21.0" certifi = ">=2019.9.11" cmem-cmempy = "21.2.3" diff --git a/redash/models/base.py b/redash/models/base.py index 2ed95c38fb..4bac1506eb 100644 --- a/redash/models/base.py +++ b/redash/models/base.py @@ -1,7 +1,10 @@ import functools +import boto3 from flask_sqlalchemy import BaseQuery, SQLAlchemy from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy.engine import Engine +from sqlalchemy.event import listens_for from sqlalchemy.orm import object_session from sqlalchemy.pool import NullPool from sqlalchemy_searchable import SearchQueryMixin, make_searchable, vectorizer @@ -42,6 +45,21 @@ def apply_pool_defaults(self, app, options): make_searchable(db.metadata, options={"regconfig": "pg_catalog.simple"}) +# IAM database authentication for AWS RDS +# See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html +if settings.REDASH_DATABASE_IAM_AUTH: + + @listens_for(Engine, "do_connect") + def db_connect_hook(dialect, conn_rec, cargs, cparams): + rds_client = boto3.client("rds") + auth_token = rds_client.generate_db_auth_token( + DBHostname=cparams["host"], + Port=cparams["port"], + DBUsername=cparams["user"], + ) + cparams["password"] = auth_token + + class SearchBaseQuery(BaseQuery, SearchQueryMixin): """ The SQA query class to use when full text search is wanted. diff --git a/redash/settings/__init__.py b/redash/settings/__init__.py index 973beffc55..2005123775 100644 --- a/redash/settings/__init__.py +++ b/redash/settings/__init__.py @@ -459,3 +459,6 @@ def email_server_is_configured(): # Email blocked domains, use delimiter comma to separated multiple domains BLOCKED_DOMAINS = set_from_string(os.environ.get("REDASH_BLOCKED_DOMAINS", "qq.com")) + +# AWS +REDASH_DATABASE_IAM_AUTH = parse_boolean(os.environ.get("REDASH_DATABASE_IAM_AUTH", "false"))