feat: add event_logger to test_connection and create_database commands (#13468)

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
This commit is contained in:
Hugh A. Miles II
2021-03-09 08:17:13 -05:00
committed by GitHub
parent 9b8e2555bf
commit c91c45574b
6 changed files with 137 additions and 22 deletions

View File

@@ -32,7 +32,7 @@ from superset.databases.commands.exceptions import (
)
from superset.databases.commands.test_connection import TestConnectionDatabaseCommand
from superset.databases.dao import DatabaseDAO
from superset.extensions import db, security_manager
from superset.extensions import db, event_logger, security_manager
logger = logging.getLogger(__name__)
@@ -50,8 +50,12 @@ class CreateDatabaseCommand(BaseCommand):
try:
TestConnectionDatabaseCommand(self._actor, self._properties).run()
except Exception:
except Exception as ex: # pylint: disable=broad-except
db.session.rollback()
event_logger.log_with_context(
action=f"db_creation_failed.{ex.__class__.__name__}",
engine=database.db_engine_spec.__name__,
)
raise DatabaseConnectionFailedError()
# adding a new database we always want to force refresh schema list
@@ -63,7 +67,10 @@ class CreateDatabaseCommand(BaseCommand):
security_manager.add_permission_view_menu("database_access", database.perm)
db.session.commit()
except DAOCreateFailedError as ex:
logger.exception(ex.exception)
event_logger.log_with_context(
action=f"db_creation_failed.{ex.__class__.__name__}",
engine=database.db_engine_spec.__name__,
)
raise DatabaseCreateFailedError()
return database
@@ -84,4 +91,7 @@ class CreateDatabaseCommand(BaseCommand):
if exceptions:
exception = DatabaseInvalidError()
exception.add_list(exceptions)
event_logger.log_with_context(
action=f"db_connection_failed.{exception.__class__.__name__}"
)
raise exception

View File

@@ -20,7 +20,6 @@ from typing import Any, Dict, Optional
from flask_appbuilder.security.sqla.models import User
from flask_babel import gettext as _
from sqlalchemy.engine.url import make_url
from sqlalchemy.exc import DBAPIError, NoSuchModuleError
from superset.commands.base import BaseCommand
@@ -32,6 +31,7 @@ from superset.databases.commands.exceptions import (
)
from superset.databases.dao import DatabaseDAO
from superset.exceptions import SupersetSecurityException
from superset.extensions import event_logger
from superset.models.core import Database
logger = logging.getLogger(__name__)
@@ -55,24 +55,42 @@ class TestConnectionDatabaseCommand(BaseCommand):
impersonate_user=self._properties.get("impersonate_user", False),
encrypted_extra=self._properties.get("encrypted_extra", "{}"),
)
if database is not None:
database.set_sqlalchemy_uri(uri)
database.db_engine_spec.mutate_db_for_connection_test(database)
username = self._actor.username if self._actor is not None else None
engine = database.get_sqla_engine(user_name=username)
database.set_sqlalchemy_uri(uri)
database.db_engine_spec.mutate_db_for_connection_test(database)
username = self._actor.username if self._actor is not None else None
engine = database.get_sqla_engine(user_name=username)
with closing(engine.raw_connection()) as conn:
if not engine.dialect.do_ping(conn):
raise DBAPIError(None, None, None)
except (NoSuchModuleError, ModuleNotFoundError):
driver_name = make_url(uri).drivername
raise DatabaseTestConnectionDriverError(
message=_("Could not load database driver: {}").format(driver_name),
except (NoSuchModuleError, ModuleNotFoundError) as ex:
event_logger.log_with_context(
action=f"test_connection_error.{ex.__class__.__name__}",
engine=database.db_engine_spec.__name__,
)
raise DatabaseTestConnectionDriverError(
message=_("Could not load database driver: {}").format(
database.db_engine_spec.__name__
),
)
except DBAPIError as ex:
event_logger.log_with_context(
action=f"test_connection_error.{ex.__class__.__name__}",
engine=database.db_engine_spec.__name__,
)
except DBAPIError:
raise DatabaseTestConnectionFailedError()
except SupersetSecurityException as ex:
event_logger.log_with_context(
action=f"test_connection_error.{ex.__class__.__name__}",
engine=database.db_engine_spec.__name__,
)
raise DatabaseSecurityUnsafeError(message=str(ex))
except Exception:
except Exception as ex: # pylint: disable=broad-except
event_logger.log_with_context(
action=f"test_connection_error.{ex.__class__.__name__}",
engine=database.db_engine_spec.__name__,
)
raise DatabaseTestConnectionUnexpectedError()
def validate(self) -> None: