Skip to content

Commit e2719eb

Browse files
new: Support configuring a custom CA file path (#327)
## 📝 Description This change allows users to specify a custom CA file to be used for API requests made by the `LinodeClient` and `LinodeLoginClient` classes. This is useful for testing in alternate API environments. ## ✔️ How to Test ``` make testunit ```
1 parent 7415f28 commit e2719eb

File tree

5 files changed

+45
-3
lines changed

5 files changed

+45
-3
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ lint: build
6262
testint:
6363
python3 -m pytest test/integration/${INTEGRATION_TEST_PATH}${MODEL_COMMAND} ${TEST_CASE_COMMAND}
6464

65+
@PHONEY: testunit
66+
testunit:
67+
python3 -m python test/unit
68+
6569
@PHONEY: smoketest
6670
smoketest:
6771
pytest -m smoke test/integration --disable-warnings

linode_api4/linode_client.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(
6262
retry_rate_limit_interval=1.0,
6363
retry_max=5,
6464
retry_statuses=None,
65+
ca_path=None,
6566
):
6667
"""
6768
The main interface to the Linode API.
@@ -96,11 +97,14 @@ def __init__(
9697
:param retry_statuses: Additional HTTP response statuses to retry on.
9798
By default, the client will retry on 408, 429, and 502
9899
responses.
100+
:param ca_path: The path to a CA file to use for API requests in this client.
101+
:type ca_path: str
99102
"""
100103
self.base_url = base_url
101104
self._add_user_agent = user_agent
102105
self.token = token
103106
self.page_size = page_size
107+
self.ca_path = ca_path
104108

105109
retry_forcelist = [408, 429, 502]
106110

@@ -267,7 +271,9 @@ def _api_call(
267271
if data is not None:
268272
body = json.dumps(data)
269273

270-
response = method(url, headers=headers, data=body)
274+
response = method(
275+
url, headers=headers, data=body, verify=self.ca_path or True
276+
)
271277

272278
warning = response.headers.get("Warning", None)
273279
if warning:

linode_api4/login_client.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,11 @@ def serialize(scopes):
324324

325325
class LinodeLoginClient:
326326
def __init__(
327-
self, client_id, client_secret, base_url="https://login.linode.com"
327+
self,
328+
client_id,
329+
client_secret,
330+
base_url="https://login.linode.com",
331+
ca_path=None,
328332
):
329333
"""
330334
Create a new LinodeLoginClient. These clients do not make any requests
@@ -339,10 +343,13 @@ def __init__(
339343
:param base_url: The URL for Linode's OAuth server. This should not be
340344
changed.
341345
:type base_url: str
346+
:param ca_path: The path to the CA file to use for requests run by this client.
347+
:type ca_path: str
342348
"""
343349
self.base_url = base_url
344350
self.client_id = client_id
345351
self.client_secret = client_secret
352+
self.ca_path = ca_path
346353

347354
def _login_uri(self, path):
348355
return "{}{}".format(self.base_url, path)
@@ -423,6 +430,7 @@ def oauth_redirect():
423430
"client_id": self.client_id,
424431
"client_secret": self.client_secret,
425432
},
433+
verify=self.ca_path or True,
426434
)
427435

428436
if r.status_code != 200:
@@ -467,6 +475,7 @@ def refresh_oauth_token(self, refresh_token):
467475
"client_secret": self.client_secret,
468476
"refresh_token": refresh_token,
469477
},
478+
verify=self.ca_path or True,
470479
)
471480

472481
if r.status_code != 200:
@@ -501,6 +510,7 @@ def expire_token(self, token):
501510
"client_secret": self.client_secret,
502511
"token": token,
503512
},
513+
verify=self.ca_path or True,
504514
)
505515

506516
if r.status_code != 200:

test/unit/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def load_json(url):
3636
return FIXTURES.get_fixture(formatted_url)
3737

3838

39-
def mock_get(url, headers=None, data=None):
39+
def mock_get(url, headers=None, data=None, **kwargs):
4040
"""
4141
Loads the response from a JSON file
4242
"""

test/unit/linode_client_test.py

+22
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,28 @@ def test_tag_create_with_entities(self):
258258
},
259259
)
260260

261+
def test_override_ca(self):
262+
"""
263+
Tests that the CA file used for API requests can be overridden.
264+
"""
265+
self.client.ca_path = "foobar"
266+
267+
called = False
268+
269+
old_get = self.client.session.get
270+
271+
def get_mock(*params, verify=True, **kwargs):
272+
nonlocal called
273+
called = True
274+
assert verify == "foobar"
275+
return old_get(*params, **kwargs)
276+
277+
self.client.session.get = get_mock
278+
279+
self.client.linode.instances()
280+
281+
assert called
282+
261283

262284
class AccountGroupTest(ClientBaseCase):
263285
"""

0 commit comments

Comments
 (0)