mirror of
https://github.com/apache/superset.git
synced 2026-04-20 00:24:38 +00:00
feat: add SSL certificate validation for Druid (#9396)
* feat: add SSL certificate feature * Address comments * don't mutate extras * Address comments and add polish * Add further polish
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
# under the License.
|
||||
# pylint: disable=unused-argument
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from contextlib import closing
|
||||
@@ -59,6 +61,8 @@ if TYPE_CHECKING:
|
||||
)
|
||||
from superset.models.core import Database # pylint: disable=unused-import
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class TimeGrain(NamedTuple): # pylint: disable=too-few-public-methods
|
||||
name: str # TODO: redundant field, remove
|
||||
@@ -959,3 +963,21 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
|
||||
:param database: instance to be mutated
|
||||
"""
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_extra_params(database: "Database") -> Dict[str, Any]:
|
||||
"""
|
||||
Some databases require adding elements to connection parameters,
|
||||
like passing certificates to `extra`. This can be done here.
|
||||
|
||||
:param database: database instance from which to extract extras
|
||||
:raises CertificateException: If certificate is not valid/unparseable
|
||||
"""
|
||||
extra: Dict[str, Any] = {}
|
||||
if database.extra:
|
||||
try:
|
||||
extra = json.loads(database.extra)
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
return extra
|
||||
|
||||
@@ -14,14 +14,20 @@
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from typing import TYPE_CHECKING
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, Dict, TYPE_CHECKING
|
||||
|
||||
from superset.db_engine_specs.base import BaseEngineSpec
|
||||
from superset.utils import core as utils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from superset.connectors.sqla.models import ( # pylint: disable=unused-import
|
||||
TableColumn,
|
||||
)
|
||||
from superset.models.core import Database # pylint: disable=unused-import
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class DruidEngineSpec(BaseEngineSpec): # pylint: disable=abstract-method
|
||||
@@ -47,3 +53,27 @@ class DruidEngineSpec(BaseEngineSpec): # pylint: disable=abstract-method
|
||||
def alter_new_orm_column(cls, orm_col: "TableColumn") -> None:
|
||||
if orm_col.column_name == "__time":
|
||||
orm_col.is_dttm = True
|
||||
|
||||
@staticmethod
|
||||
def get_extra_params(database: "Database") -> Dict[str, Any]:
|
||||
"""
|
||||
For Druid, the path to a SSL certificate is placed in `connect_args`.
|
||||
|
||||
:param database: database instance from which to extract extras
|
||||
:raises CertificateException: If certificate is not valid/unparseable
|
||||
"""
|
||||
try:
|
||||
extra = json.loads(database.extra or "{}")
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
if database.server_cert:
|
||||
engine_params = extra.get("engine_params", {})
|
||||
connect_args = engine_params.get("connect_args", {})
|
||||
connect_args["scheme"] = "https"
|
||||
path = utils.create_ssl_cert_file(database.server_cert)
|
||||
connect_args["ssl_verify_cert"] = path
|
||||
engine_params["connect_args"] = connect_args
|
||||
extra["engine_params"] = engine_params
|
||||
return extra
|
||||
|
||||
Reference in New Issue
Block a user