1010import click
1111from boltons .urlutils import URL
1212
13- from cratedb_toolkit .cluster .croud import CloudManager
13+ from cratedb_toolkit .cluster .croud import CloudClusterServices , CloudRootServices
1414from cratedb_toolkit .cluster .guide import DataImportGuide
1515from cratedb_toolkit .cluster .model import ClientBundle , ClusterBase , ClusterInformation
1616from cratedb_toolkit .config import CONFIG
@@ -132,7 +132,8 @@ def __init__(
132132 "Failed to address cluster: Either cluster identifier or name needs to be specified"
133133 )
134134
135- self .cm = CloudManager ()
135+ self .root = CloudRootServices ()
136+ self .operation : t .Optional [CloudClusterServices ] = None
136137 self ._jwt_ctx : t .ContextManager = nullcontext ()
137138 self ._client_bundle : t .Optional [ClientBundle ] = None
138139
@@ -148,15 +149,18 @@ def __exit__(self, exc_type, exc_val, exc_tb):
148149
149150 try :
150151 self .close_connections ()
151- if self .stop_on_exit :
152- self .stop ()
153- logger .info (f"Successfully stopped cluster: id={ self .cluster_id } , name={ self .cluster_name } " )
154152 except Exception as ex :
155- logger .error (f"Failed to stop cluster: { ex } " )
156- # Don't swallow the original exception
157- return False
153+ logger .error (f"Failed to close connections: { ex } " )
154+ finally :
155+ if self .stop_on_exit :
156+ try :
157+ self .stop ()
158+ logger .info (f"Successfully stopped cluster: id={ self .cluster_id } , name={ self .cluster_name } " )
159+ except Exception as ex :
160+ logger .error (f"Failed to stop cluster: { ex } " )
158161
159- return False # Don't suppress any exceptions
162+ # Don't suppress the original exception.
163+ return False
160164
161165 @classmethod
162166 @flexfun (domain = "settings" )
@@ -202,13 +206,19 @@ def probe(self) -> "ManagedCluster":
202206 Probe a CrateDB Cloud cluster, API-wise.
203207
204208 TODO: Investigate callers, and reduce number of invocations.
209+ TODO: self._jwt_ctx is created once in probe() and reused for every query.
210+ If the per-cluster JWT expires (default 1 h) subsequent queries will fail.
211+ Consider refreshing self._jwt_ctx (or simply calling jwt_token_patch()
212+ inside query()) when probe() is older than e.g. 30 min.
205213 """
206214 try :
207215 self .info = ClusterInformation .from_id_or_name (cluster_id = self .cluster_id , cluster_name = self .cluster_name )
208216 self .cluster_id = self .info .cloud ["id" ]
209217 self .cluster_name = self .info .cloud ["name" ]
210218 self .address = DatabaseAddress .from_httpuri (self .info .cloud ["url" ])
211219 self ._jwt_ctx = jwt_token_patch (self .info .jwt .token )
220+ if self .cluster_id :
221+ self .operation = CloudClusterServices (cluster_id = self .cluster_id )
212222
213223 except (CroudException , DatabaseAddressMissingError ) as ex :
214224 self .exists = False
@@ -269,14 +279,13 @@ def deploy(self) -> "ManagedCluster":
269279
270280 Command: ctk cluster start
271281 """
272- # FIXME: Accept id or name.
273282 if self .cluster_name is None :
274283 raise DatabaseAddressMissingError ("Need cluster name to deploy" )
275284
276285 # Find the existing project by name (equals cluster name).
277286 project_id = None
278287 try :
279- projects = self .cm .list_projects ()
288+ projects = self .root .list_projects ()
280289 for project in projects :
281290 if project ["name" ] == self .cluster_name :
282291 project_id = project ["id" ]
@@ -287,11 +296,11 @@ def deploy(self) -> "ManagedCluster":
287296
288297 # Create a new project if none exists.
289298 if not project_id :
290- project = self .cm .create_project (name = self .cluster_name , organization_id = self .settings .organization_id )
299+ project = self .root .create_project (name = self .cluster_name , organization_id = self .settings .organization_id )
291300 project_id = project ["id" ]
292301 logger .info (f"Created project: { project_id } " )
293302
294- cluster_info = self .cm .deploy_cluster (
303+ cluster_info = self .root .deploy_cluster (
295304 name = self .cluster_name , project_id = project_id , subscription_id = self .settings .subscription_id
296305 )
297306
@@ -309,7 +318,8 @@ def resume(self) -> "ManagedCluster":
309318 if self .cluster_id is None :
310319 raise DatabaseAddressMissingError ("Need cluster identifier to resume cluster" )
311320 logger .info (f"Resuming CrateDB Cloud Cluster: id={ self .cluster_id } , name={ self .cluster_name } " )
312- self .cm .resume_cluster (identifier = self .cluster_id )
321+ if self .operation :
322+ self .operation .resume ()
313323 self .probe ()
314324 return self
315325
@@ -322,7 +332,8 @@ def stop(self) -> "ManagedCluster":
322332 if self .cluster_id is None :
323333 raise DatabaseAddressMissingError ("Need cluster identifier to stop cluster" )
324334 logger .info (f"Stopping CrateDB Cloud Cluster: id={ self .cluster_id } , name={ self .cluster_name } " )
325- self .cm .suspend_cluster (identifier = self .cluster_id )
335+ if self .operation :
336+ self .operation .suspend ()
326337 self .probe ()
327338 return self
328339
@@ -348,7 +359,6 @@ def load_table(
348359 self .probe ()
349360 target = target or TableAddress ()
350361
351- # FIXME: Accept id or name.
352362 if self .cluster_id is None :
353363 raise DatabaseAddressMissingError ("Need cluster identifier to load table" )
354364
0 commit comments