Skip to content

Commit 2026f3b

Browse files
authored
Pass certificates explicitly (#222)
1 parent 6c0706a commit 2026f3b

File tree

41 files changed

+333
-126
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+333
-126
lines changed

app/dl_control_api/dl_control_api/app_factory.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def _get_env_manager_factory(self, settings: ControlApiAppSettings) -> EnvManage
3636
def _get_inst_specific_sr_factory(
3737
self,
3838
settings: ControlApiAppSettings,
39+
ca_data: bytes,
3940
) -> StandaloneServiceRegistryFactory:
4041
return StandaloneServiceRegistryFactory()
4142

app/dl_data_api/dl_data_api/app_factory.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from dl_api_lib.connector_availability.base import ConnectorAvailabilityConfig
1818
from dl_configs.connectors_settings import ConnectorSettingsBase
1919
from dl_configs.enums import RequiredService
20+
from dl_configs.utils import get_root_certificates
2021
from dl_constants.enums import ConnectionType
2122
from dl_core.aio.middlewares.services_registry import services_registry_middleware
2223
from dl_core.aio.middlewares.us_manager import service_us_manager_middleware
@@ -43,6 +44,7 @@ def _get_env_manager_factory(self, settings: AppSettings) -> EnvManagerFactory:
4344
def _get_inst_specific_sr_factory(
4445
self,
4546
settings: AppSettings,
47+
ca_data: bytes,
4648
) -> Optional[InstallationSpecificServiceRegistryFactory]:
4749
return None
4850

@@ -78,9 +80,14 @@ def set_up_environment(
7880
sr_middleware_list: list[AIOHTTPMiddleware]
7981
usm_middleware_list: list[AIOHTTPMiddleware]
8082

83+
ca_data = get_root_certificates(path=self._settings.CA_FILE_PATH)
84+
8185
conn_opts_factory = ConnOptionsMutatorsFactory()
8286
sr_factory = self.get_sr_factory(
83-
settings=self._settings, conn_opts_factory=conn_opts_factory, connectors_settings=connectors_settings
87+
settings=self._settings,
88+
conn_opts_factory=conn_opts_factory,
89+
connectors_settings=connectors_settings,
90+
ca_data=ca_data,
8491
)
8592

8693
# Auth middlewares
@@ -105,6 +112,7 @@ def set_up_environment(
105112
common_us_kw = dict(
106113
us_base_url=self._settings.US_BASE_URL,
107114
crypto_keys_config=self._settings.CRYPTO_KEYS_CONFIG,
115+
ca_data=ca_data,
108116
)
109117
usm_middleware_list = [
110118
service_us_manager_middleware(us_master_token=self._settings.US_MASTER_TOKEN, **common_us_kw), # type: ignore

lib/dl_api_commons/dl_api_commons/aiohttp/aiohttp_client.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import aiohttp.web
2323
import attr
2424

25-
from dl_configs.utils import get_root_certificates_path
26-
2725

2826
LOGGER = logging.getLogger(__name__)
2927

@@ -93,10 +91,6 @@ async def retry_request(
9391
raise Exception("You should not be here")
9492

9593

96-
def default_ssl_context() -> ssl.SSLContext:
97-
return ssl.create_default_context(cafile=get_root_certificates_path())
98-
99-
10094
@attr.s(kw_only=True)
10195
class BIAioHTTPClient:
10296
base_url: str = attr.ib()
@@ -112,26 +106,24 @@ class BIAioHTTPClient:
112106

113107
retrier: BaseRetrier = attr.ib(factory=NoRetriesRetrier)
114108

115-
ssl_context: Optional[ssl.SSLContext] = attr.ib(factory=default_ssl_context)
116-
_session: Optional[aiohttp.ClientSession] = attr.ib()
117-
close_session_on_exit: Optional[bool] = attr.ib(default=None)
109+
_ca_data: bytes = attr.ib()
110+
_session: Optional[aiohttp.ClientSession] = attr.ib(init=False)
118111

119-
def make_default_session(self) -> aiohttp.ClientSession:
112+
def __attrs_post_init__(self):
113+
self._session = self._make_session()
114+
115+
def _make_session(self) -> aiohttp.ClientSession:
116+
ssl_context = ssl.create_default_context(cadata=self._ca_data.decode("utf-8"))
120117
return aiohttp.ClientSession(
121-
cookies=self.cookies, headers=self.headers, connector=aiohttp.TCPConnector(ssl_context=self.ssl_context)
118+
cookies=self.cookies,
119+
headers=self.headers,
120+
connector=aiohttp.TCPConnector(
121+
ssl_context=ssl_context,
122+
),
122123
)
123124

124-
@property
125-
def session(self) -> aiohttp.ClientSession:
126-
if self._session is None:
127-
self._session = self.make_default_session()
128-
if self.close_session_on_exit is None:
129-
self.close_session_on_exit = True
130-
return self._session
131-
132125
async def close(self) -> None:
133-
if self.close_session_on_exit:
134-
await self.session.close()
126+
await self._session.close()
135127

136128
async def __aenter__(self) -> BIAioHTTPClient:
137129
return self
@@ -168,7 +160,7 @@ async def _request(
168160
sock_connect=conn_timeout_sec or self.conn_timeout_sec,
169161
sock_read=read_timeout_sec or self.read_timeout_sec,
170162
)
171-
return await self.session.request(
163+
return await self._session.request(
172164
method=method,
173165
url=self.url(path),
174166
params=params,

lib/dl_api_commons/dl_api_commons/client/base.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import logging
2-
import ssl
32
from typing import (
43
Any,
54
AsyncIterable,
@@ -17,7 +16,6 @@
1716
TenantDef,
1817
)
1918
from dl_api_commons.tracing import get_current_tracing_headers
20-
from dl_configs.utils import get_root_certificates_path
2119
from dl_constants.api_constants import (
2220
DLHeaders,
2321
DLHeadersCommon,
@@ -57,21 +55,15 @@ def __init__(self, msg: str, content: bytes, status: int, request_id: str):
5755
self.request_id = request_id
5856

5957

60-
def get_default_aiohttp_session() -> aiohttp.ClientSession:
61-
return aiohttp.ClientSession(
62-
connector=aiohttp.TCPConnector(ssl_context=ssl.create_default_context(cafile=get_root_certificates_path())),
63-
)
64-
65-
6658
@attr.s(auto_attribs=True)
6759
class DLCommonAPIClient:
6860
_base_url: str = attr.ib()
6961
_tenant: TenantDef = attr.ib()
7062
_auth_data: AuthData = attr.ib()
63+
_session: aiohttp.ClientSession = attr.ib()
7164
_req_id: Optional[str] = attr.ib(default=None)
7265

7366
_extra_headers: Optional[dict[DLHeaders, str]] = attr.ib(default=None)
74-
_session: aiohttp.ClientSession = attr.ib(factory=get_default_aiohttp_session)
7567

7668
@staticmethod
7769
def update_dl_headers(acc: dict[DLHeaders, str], update: dict[DLHeaders, str], stage: str) -> None:

lib/dl_api_lib/dl_api_lib/app/control_api/app.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
ControlApiAppTestingsSettings,
3535
)
3636
from dl_configs.connectors_settings import ConnectorSettingsBase
37+
from dl_configs.utils import get_root_certificates
3738
from dl_constants.enums import (
3839
ConnectionType,
3940
USAuthMode,
@@ -103,6 +104,8 @@ def create_app(
103104
).wrap_flask_app(app)
104105
ContextVarMiddleware().wrap_flask_app(app)
105106

107+
ca_data = get_root_certificates(path=self._settings.CA_FILE_PATH)
108+
106109
if close_loop_after_request:
107110
AIOEventLoopMiddleware().wrap_flask_app(app)
108111

@@ -135,6 +138,7 @@ def create_app(
135138
settings=self._settings,
136139
conn_opts_factory=conn_opts_mutators_factory,
137140
connectors_settings=connectors_settings,
141+
ca_data=get_root_certificates(self._settings.CA_FILE_PATH),
138142
)
139143

140144
ServicesRegistryMiddleware(
@@ -146,6 +150,7 @@ def create_app(
146150
us_base_url=self._settings.US_BASE_URL,
147151
us_master_token=self._settings.US_MASTER_TOKEN,
148152
us_auth_mode=env_setup_result.us_auth_mode,
153+
ca_data=ca_data,
149154
).set_up(app)
150155

151156
app.logger

lib/dl_api_lib/dl_api_lib/app_common.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def _get_env_manager_factory(self, settings: TSettings) -> EnvManagerFactory:
103103
def _get_inst_specific_sr_factory(
104104
self,
105105
settings: TSettings,
106+
ca_data: bytes,
106107
) -> Optional[InstallationSpecificServiceRegistryFactory]:
107108
raise NotImplementedError
108109

@@ -136,6 +137,7 @@ def get_sr_factory(
136137
settings: TSettings,
137138
conn_opts_factory: ConnOptionsMutatorsFactory,
138139
connectors_settings: dict[ConnectionType, ConnectorSettingsBase],
140+
ca_data: bytes,
139141
) -> DefaultApiSRFactory:
140142
supported_functions_manager = SupportedFunctionsManager(supported_tags=settings.FORMULA_SUPPORTED_FUNC_TAGS)
141143

@@ -181,9 +183,13 @@ def get_sr_factory(
181183
localizer_factory=localization_factory,
182184
localizer_fallback=localizer_fallback,
183185
connector_availability=self._get_connector_availability(settings),
184-
inst_specific_sr_factory=self._get_inst_specific_sr_factory(settings),
186+
inst_specific_sr_factory=self._get_inst_specific_sr_factory(
187+
settings,
188+
ca_data=ca_data,
189+
),
185190
force_non_rqe_mode=settings.RQE_FORCE_OFF,
186191
query_proc_mode=settings.QUERY_PROCESSING_MODE,
192+
ca_data=ca_data,
187193
pivot_transformer_factory=pivot_transformer_factory,
188194
)
189195
return sr_factory

lib/dl_api_lib/dl_api_lib/app_settings.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
)
2222
from dl_configs.settings_loaders.settings_obj_base import SettingsBase
2323
from dl_configs.settings_submodels import RedisSettings
24-
from dl_configs.utils import split_by_comma
24+
from dl_configs.utils import (
25+
get_root_certificates_path,
26+
split_by_comma,
27+
)
2528
from dl_constants.enums import (
2629
DataPivotEngineType,
2730
QueryProcessingMode,
@@ -141,6 +144,7 @@ class AppSettings:
141144
env_var_converter=lambda s: QueryProcessingMode[s.lower()],
142145
missing=QueryProcessingMode.basic,
143146
)
147+
CA_FILE_PATH: str = s_attrib("CA_FILE_PATH", missing=get_root_certificates_path())
144148

145149
PIVOT_ENGINE_TYPE: DataPivotEngineType = s_attrib( # type: ignore
146150
"PIVOT_ENGINE_TYPE",
@@ -234,6 +238,8 @@ class DataApiAppSettings(AppSettings):
234238

235239
BI_ASYNC_APP_DISABLE_KEEPALIVE: bool = s_attrib("BI_ASYNC_APP_DISABLE_KEEPALIVE", missing=False) # type: ignore
236240

241+
CA_FILE_PATH: str = s_attrib("CA_FILE_PATH", missing=get_root_certificates_path())
242+
237243
@property
238244
def app_name(self) -> str:
239245
return "bi_data_api"

lib/dl_api_lib_testing/dl_api_lib_testing/app.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
from dl_core.utils import FutureRef
5454
from dl_core_testing.app_test_workarounds import TestEnvManagerFactory
5555
from dl_core_testing.fixture_server_runner import WSGIRunner
56+
from dl_testing.utils import get_root_certificates
5657

5758

5859
@attr.s
@@ -152,6 +153,7 @@ def _get_env_manager_factory(self, settings: AppSettings) -> EnvManagerFactory:
152153
def _get_inst_specific_sr_factory(
153154
self,
154155
settings: AppSettings,
156+
ca_data: bytes,
155157
) -> Optional[InstallationSpecificServiceRegistryFactory]:
156158
return TestingServiceRegistryFactory()
157159

@@ -209,8 +211,13 @@ def set_up_environment(
209211
connectors_settings: dict[ConnectionType, ConnectorSettingsBase],
210212
) -> DataApiEnvSetupResult:
211213
conn_opts_factory = ConnOptionsMutatorsFactory()
214+
ca_data = get_root_certificates()
215+
212216
sr_factory = self.get_sr_factory(
213-
settings=self._settings, conn_opts_factory=conn_opts_factory, connectors_settings=connectors_settings
217+
settings=self._settings,
218+
conn_opts_factory=conn_opts_factory,
219+
connectors_settings=connectors_settings,
220+
ca_data=ca_data,
214221
)
215222

216223
auth_mw_list = [
@@ -232,6 +239,7 @@ def set_up_environment(
232239
common_us_kw = dict(
233240
us_base_url=self._settings.US_BASE_URL,
234241
crypto_keys_config=self._settings.CRYPTO_KEYS_CONFIG,
242+
ca_data=ca_data,
235243
)
236244
usm_middleware_list = [
237245
service_us_manager_middleware(us_master_token=self._settings.US_MASTER_TOKEN, **common_us_kw), # type: ignore[arg-type]

lib/dl_api_lib_testing/dl_api_lib_testing/base.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
FlaskTestClient,
4545
FlaskTestResponse,
4646
)
47+
from dl_testing.utils import (
48+
get_root_certificates,
49+
get_root_certificates_path,
50+
)
4751

4852

4953
class ApiTestBase(abc.ABC):
@@ -115,6 +119,7 @@ def create_control_api_settings(
115119
FILE_UPLOADER_BASE_URL="http://127.0.0.1:9999", # fake url
116120
FILE_UPLOADER_MASTER_TOKEN="qwerty",
117121
QUERY_PROCESSING_MODE=cls.query_processing_mode,
122+
CA_FILE_PATH=get_root_certificates_path(),
118123
)
119124
return settings
120125

@@ -129,6 +134,10 @@ def control_api_app_settings(
129134
rqe_config_subprocess=rqe_config_subprocess,
130135
)
131136

137+
@pytest.fixture(scope="function")
138+
def ca_data(self) -> bytes:
139+
return get_root_certificates()
140+
132141
@pytest.fixture(scope="function")
133142
def control_api_app_factory(self, control_api_app_settings: ControlApiAppSettings) -> ControlApiAppFactory:
134143
return TestingControlApiAppFactory(settings=control_api_app_settings)
@@ -183,6 +192,7 @@ def sync_us_manager(
183192
control_api_app_factory: ControlApiAppFactory,
184193
connectors_settings: dict[ConnectionType, ConnectorSettingsBase],
185194
control_api_app_settings: ControlApiAppSettings,
195+
ca_data: bytes,
186196
) -> SyncUSManager:
187197
core_test_config = bi_test_config.core_test_config
188198
bi_context = RequestContextInfo.create_empty()
@@ -194,6 +204,7 @@ def sync_us_manager(
194204
conn_opts_factory=ConnOptionsMutatorsFactory(),
195205
connectors_settings=connectors_settings,
196206
settings=control_api_app_settings,
207+
ca_data=ca_data,
197208
).make_service_registry(request_context_info=bi_context),
198209
us_base_url=us_config.us_host,
199210
us_auth_context=USAuthContextMaster(us_config.us_master_token),

lib/dl_api_lib_testing/dl_api_lib_testing/data_api_base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from dl_constants.enums import ConnectionType
3535
from dl_core.components.ids import FieldIdGeneratorType
3636
from dl_core_testing.database import DbTable
37+
from dl_testing.utils import get_root_certificates_path
3738

3839

3940
class DataApiTestParams(NamedTuple):
@@ -85,6 +86,7 @@ def create_data_api_settings(
8586
FILE_UPLOADER_BASE_URL=f"{bi_test_config.file_uploader_api_host}:{bi_test_config.file_uploader_api_port}",
8687
FILE_UPLOADER_MASTER_TOKEN="qwerty",
8788
QUERY_PROCESSING_MODE=cls.query_processing_mode,
89+
CA_FILE_PATH=get_root_certificates_path(),
8890
) # type: ignore
8991

9092
@pytest.fixture(scope="function")

0 commit comments

Comments
 (0)