Skip to content

Commit 586f9dc

Browse files
committed
Cluster API: Address suggestions from code review by CodeRabbit
1 parent 72d3fd9 commit 586f9dc

File tree

10 files changed

+57
-37
lines changed

10 files changed

+57
-37
lines changed

cratedb_toolkit/cluster/croud.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,8 @@ def get_jwt_token(self) -> t.Dict[str, str]:
385385
"""
386386
client = CroudClient.create()
387387
data, errors = client.get(f"/api/v2/clusters/{self.cluster_id}/jwt/")
388-
errmsg = "Getting JWT token failed: Unknown error"
389-
if errors:
390-
errmsg = f"Getting JWT token failed: {errors}"
391388
if data is None:
392-
raise IOError(errmsg)
389+
if errors:
390+
raise IOError(f"Getting JWT token failed: {errors}")
391+
raise IOError("Getting JWT token failed: Unknown error")
393392
return data

cratedb_toolkit/cluster/model.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,9 @@ def close(self):
114114
"""
115115

116116
try:
117-
self.adapter.connection.close()
117+
self.adapter.close()
118118
except Exception as e:
119-
logger.warning(f"Error closing adapter connection: {e}")
120-
121-
try:
122-
self.adapter.engine.dispose()
123-
except Exception as e:
124-
logger.warning(f"Error disposing SQLAlchemy engine: {e}")
119+
logger.warning(f"Error closing database adapter: {e}")
125120

126121
try:
127122
self.dbapi.close()

cratedb_toolkit/shell/cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def help_cli():
3131
- https://cratedb-toolkit.readthedocs.io/util/shell.html
3232
- https://cratedb.com/docs/crate/crash/
3333
34-
TODO: Learn/forward more options of `crash`.
34+
TODO: Implement/forward more options of `crash`.
3535
"""
3636

3737

@@ -84,19 +84,19 @@ def cli(
8484
if cluster.address is None:
8585
raise click.UsageError("Inquiring cluster address failed.")
8686

87-
http_url = cluster.address.httpuri
88-
8987
is_cloud = cluster_id is not None or cluster_name is not None
9088
jwt_token = None
9189
if is_cloud:
9290
if username is not None:
9391
logger.info("Using username/password credentials for authentication")
9492
else:
9593
logger.info("Using JWT token for authentication")
96-
jwt_token = cluster.info.jwt.token
94+
jwt_token_obj = getattr(cluster.info, "jwt", None)
95+
if jwt_token_obj:
96+
jwt_token = jwt_token_obj.token
9797

9898
run_crash(
99-
hosts=http_url,
99+
hosts=cluster.address.httpuri,
100100
username=username,
101101
password=password,
102102
jwt_token=jwt_token,

cratedb_toolkit/util/client.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
import contextlib
2-
from unittest import mock
32

43
import crate.client.http
54

65

76
@contextlib.contextmanager
87
def jwt_token_patch(jwt_token: str = None):
9-
with mock.patch.object(crate.client.http.Client, "_request", _mk_crate_client_server_request(jwt_token)):
8+
original_request = crate.client.http.Client._request
9+
crate.client.http.Client._request = _mk_crate_client_request(original_request, jwt_token)
10+
try:
1011
yield
12+
finally:
13+
crate.client.http.Client._request = original_request
1114

1215

13-
def _mk_crate_client_server_request(jwt_token: str = None):
16+
def _mk_crate_client_request(orig, jwt_token: str = None):
1417
"""
15-
Create a monkey patched Server.request method to add the Authorization header for JWT token-based authentication.
18+
Create a monkey patched Client._request method to add the Authorization header for JWT token-based authentication.
1619
"""
1720

18-
_crate_client_server_request_dist = crate.client.http.Client._request
19-
20-
def _crate_client_server_request(self, *args, **kwargs):
21+
def _crate_client_request(self, *args, **kwargs):
2122
"""
2223
Monkey patch the Server.request method to add the Authorization header for JWT token-based authentication.
2324
@@ -26,6 +27,6 @@ def _crate_client_server_request(self, *args, **kwargs):
2627
if jwt_token:
2728
kwargs.setdefault("headers", {})
2829
kwargs["headers"].update({"Authorization": "Bearer " + jwt_token})
29-
return _crate_client_server_request_dist(self, *args, **kwargs)
30+
return orig(self, *args, **kwargs)
3031

31-
return _crate_client_server_request
32+
return _crate_client_request

cratedb_toolkit/util/database.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,18 @@ def run_sql_real(self, sql: str, parameters: t.Mapping[str, str] = None, records
123123
for statement in sqlparse.split(sql):
124124
if self.internal:
125125
statement += self.internal_tag
126+
# FIXME: Persistent self.connection risks leaks & thread-unsafety.
127+
# https://github.com/crate/cratedb-toolkit/pull/81#discussion_r2071499204
126128
result = self.connection.execute(sa.text(statement), parameters)
127129
data: t.Any
128-
if records:
129-
rows = result.mappings().fetchall()
130-
data = [dict(row.items()) for row in rows]
130+
if result.returns_rows:
131+
if records:
132+
rows = result.mappings().fetchall()
133+
data = [dict(row.items()) for row in rows]
134+
else:
135+
data = result.fetchall()
131136
else:
132-
data = result.fetchall()
137+
data = None
133138
results.append(data)
134139

135140
# Backward-compatibility.
@@ -387,6 +392,25 @@ def describe_table_columns(self, table_name: str):
387392
table_address = TableAddress.from_string(table_name)
388393
return inspector.get_columns(table_name=t.cast(str, table_address.table), schema=table_address.schema)
389394

395+
def close(self):
396+
"""
397+
Close all database connections created to this cluster.
398+
Should be called when the cluster handle is no longer needed.
399+
"""
400+
401+
try:
402+
self.connection.close()
403+
except Exception as e:
404+
logger.warning(f"Error closing adapter connection: {e}")
405+
406+
try:
407+
self.engine.dispose()
408+
except Exception as e:
409+
logger.warning(f"Error disposing SQLAlchemy engine: {e}")
410+
411+
def __del__(self):
412+
self.close()
413+
390414

391415
def sa_is_empty(thing):
392416
"""

doc/util/shell.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,8 @@ ctk shell --command "SELECT 42;"
7676
```
7777

7878

79-
Include authentication credentials into the
80-
SQLAlchemy or HTTP connection URLs.
81-
82-
8379
:::{seealso}
84-
{ref}`cluster-api-tutorial` includes a full end-to-end tutorial which also includes
80+
{ref}`cluster-api-tutorial` demonstrates a full end-to-end tutorial, which also includes
8581
`ctk shell`.
8682
:::
8783

examples/python/cloud_cluster.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ def workload_procedural():
9595
pprint(results, stream=sys.stderr) # noqa: T201
9696

9797
# Stop the cluster again.
98+
# Note: We intentionally don't stop the cluster here to prevent accidental
99+
# shutdown of resources that might be in use for demonstration purposes.
98100
# cluster.stop()
99101

100102

tests/cluster/test_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from cratedb_toolkit.cluster.cli import cli
44

55

6-
def test_managed_cluster_info_empty(cloud_environment):
6+
def test_managed_cluster_info_default(cloud_environment):
77
"""
88
Verify `ctk cluster info` on a managed cluster works when a valid environment is provided.
99
"""

tests/conftest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ def prune_environment():
8989
@pytest.fixture(scope="session", autouse=True)
9090
def reset_environment():
9191
"""
92-
Reset all environment variables in use, so that they do not pollute the test suite.
92+
Reset environment variables defined in ManagedClusterSettings.
93+
94+
This complements the `prune_environment` fixture by specifically targeting
95+
variables from ManagedClusterSettings rather than all CRATEDB_* variables.
9396
9497
TODO: Possibly synchronize with `prune_environment()`, as suggested.
9598
"""

tests/shell/test_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def test_shell_managed_jwt(mocker, cloud_cluster_name):
5454

5555
def test_shell_managed_username_password(mocker, cloud_cluster_name):
5656
"""
57-
Verify the successful incantation of `ctk shell` against CrateDB Cloud, using username/password authentication..
57+
Verify the successful incantation of `ctk shell` against CrateDB Cloud, using username/password authentication.
5858
"""
5959

6060
settings = {

0 commit comments

Comments
 (0)