Skip to content

Commit 572e790

Browse files
szaffaranoharitamar
authored andcommitted
Add optional ssl config flag
1 parent 714817e commit 572e790

3 files changed

Lines changed: 50 additions & 11 deletions

File tree

elementary/clients/slack/client.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import json
2+
import ssl
23
from abc import ABC, abstractmethod
34
from typing import Dict, List, Optional, Tuple, Union
45

56
import requests
7+
import certifi
68
from ratelimit import limits, sleep_and_retry
79
from slack_sdk import WebClient, WebhookClient
810
from slack_sdk.errors import SlackApiError
@@ -25,8 +27,9 @@ class SlackClient(ABC):
2527
def __init__(
2628
self,
2729
tracking: Optional[Tracking] = None,
30+
ssl_context: Optional[ssl.SSLContext] = None,
2831
):
29-
self.client = self._initial_client()
32+
self.client = self._initial_client(ssl_context)
3033
self.tracking = tracking
3134
self._initial_retry_handlers()
3235
self.email_to_user_id_cache: Dict[str, str] = {}
@@ -38,19 +41,38 @@ def create_client(
3841
if not config.has_slack:
3942
return None
4043
if config.slack_token:
41-
logger.debug("Creating Slack client with token.")
42-
return SlackWebClient(token=config.slack_token, tracking=tracking)
44+
logger.debug(
45+
"Creating Slack client with token (system CA? = %s).",
46+
config.use_system_ca_files,
47+
)
48+
ssl_context = (
49+
None
50+
if config.use_system_ca_files
51+
else ssl.create_default_context(cafile=certifi.where())
52+
)
53+
return SlackWebClient(
54+
token=config.slack_token, tracking=tracking, ssl_context=ssl_context
55+
)
4356
elif config.slack_webhook:
44-
logger.debug("Creating Slack client with webhook.")
57+
logger.debug(
58+
"Creating Slack client with webhook (system CA? = %s).",
59+
config.use_system_ca_files,
60+
)
61+
ssl_context = (
62+
ssl.create_default_context(cafile=certifi.where())
63+
if not config.use_system_ca_files
64+
else None
65+
)
4566
return SlackWebhookClient(
4667
webhook=config.slack_webhook,
4768
is_workflow=config.is_slack_workflow,
4869
tracking=tracking,
70+
ssl_context=ssl_context
4971
)
5072
return None
5173

5274
@abstractmethod
53-
def _initial_client(self):
75+
def _initial_client(self, ssl_context: Optional[ssl.SSLContext]):
5476
raise NotImplementedError
5577

5678
def _initial_retry_handlers(self):
@@ -85,12 +107,13 @@ def __init__(
85107
self,
86108
token: str,
87109
tracking: Optional[Tracking] = None,
110+
ssl_context: Optional[ssl.SSLContext] = None,
88111
):
89112
self.token = token
90-
super().__init__(tracking)
113+
super().__init__(tracking, ssl_context)
91114

92-
def _initial_client(self):
93-
return WebClient(token=self.token)
115+
def _initial_client(self, ssl_context: Optional[ssl.SSLContext]):
116+
return WebClient(token=self.token, ssl=ssl_context)
94117

95118
@sleep_and_retry
96119
@limits(calls=1, period=ONE_SECOND)
@@ -231,16 +254,20 @@ def __init__(
231254
webhook: str,
232255
is_workflow: bool,
233256
tracking: Optional[Tracking] = None,
257+
ssl_context: Optional[ssl.SSLContext] = None,
234258
):
235259
self.webhook = webhook
236260
self.is_workflow = is_workflow
237-
super().__init__(tracking)
261+
super().__init__(tracking, ssl_context)
238262

239-
def _initial_client(self):
263+
def _initial_client(self, ssl_context: Optional[ssl.SSLContext]):
240264
if self.is_workflow:
241265
return requests.Session()
266+
242267
return WebhookClient(
243-
url=self.webhook, default_headers={"Content-type": "application/json"}
268+
url=self.webhook,
269+
default_headers={"Content-type": "application/json"},
270+
ssl=ssl_context,
244271
)
245272

246273
@sleep_and_retry

elementary/config/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def __init__(
7676
run_dbt_deps_if_needed: Optional[bool] = None,
7777
project_name: Optional[str] = None,
7878
quiet_logs: Optional[bool] = None,
79+
use_system_ca_files: bool = True,
7980
):
8081
self.config_dir = config_dir
8182
self.profiles_dir = profiles_dir
@@ -222,6 +223,8 @@ def __init__(
222223
self.quiet_logs = self._first_not_none(
223224
quiet_logs, config.get("quiet_logs"), False
224225
)
226+
227+
self.use_system_ca_files = use_system_ca_files
225228

226229
def _load_configuration(self) -> dict:
227230
if not os.path.exists(self.config_dir):

elementary/monitor/cli.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ def decorator(func):
7575
default=None,
7676
help="The Slack token for your workspace.",
7777
)(func)
78+
func = click.option(
79+
"--use-system-ca-files/--no-use-system-ca-files",
80+
default=True,
81+
help="Whether to use the system CA files for SSL connections or the ones provided by certify (see https://pypi.org/project/certifi).",
82+
)(func)
7883
if cmd in (Command.REPORT, Command.SEND_REPORT):
7984
func = click.option(
8085
"--exclude-elementary-models",
@@ -331,6 +336,7 @@ def monitor(
331336
teams_webhook,
332337
maximum_columns_in_alert_samples,
333338
quiet_logs,
339+
use_system_ca_files,
334340
):
335341
"""
336342
Get alerts on failures in dbt jobs.
@@ -365,6 +371,7 @@ def monitor(
365371
teams_webhook=teams_webhook,
366372
maximum_columns_in_alert_samples=maximum_columns_in_alert_samples,
367373
quiet_logs=quiet_logs,
374+
use_system_ca_files=use_system_ca_files,
368375
)
369376
anonymous_tracking = AnonymousCommandLineTracking(config)
370377
anonymous_tracking.set_env("use_select", bool(select))
@@ -692,6 +699,7 @@ def send_report(
692699
include,
693700
target_path,
694701
quiet_logs,
702+
use_system_ca_files,
695703
):
696704
"""
697705
Generate and send the report to an external platform.
@@ -735,6 +743,7 @@ def send_report(
735743
env=env,
736744
project_name=project_name,
737745
quiet_logs=quiet_logs,
746+
use_system_ca_files=use_system_ca_files,
738747
)
739748
anonymous_tracking = AnonymousCommandLineTracking(config)
740749
anonymous_tracking.set_env("use_select", bool(select))

0 commit comments

Comments
 (0)