kaqing 2.0.172__py3-none-any.whl → 2.0.186__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kaqing might be problematic. Click here for more details.

Files changed (140) hide show
  1. adam/app_session.py +2 -2
  2. adam/apps.py +18 -4
  3. adam/batch.py +1 -1
  4. adam/checks/check_utils.py +3 -1
  5. adam/commands/__init__.py +8 -2
  6. adam/commands/alter_tables.py +24 -35
  7. adam/commands/app/__init__.py +0 -0
  8. adam/commands/app/app.py +38 -0
  9. adam/commands/app/app_ping.py +38 -0
  10. adam/commands/app/show_app_actions.py +49 -0
  11. adam/commands/app/show_app_id.py +44 -0
  12. adam/commands/app/show_app_queues.py +38 -0
  13. adam/commands/app/utils_app.py +106 -0
  14. adam/commands/audit/audit.py +9 -27
  15. adam/commands/audit/audit_repair_tables.py +5 -7
  16. adam/commands/audit/audit_run.py +1 -1
  17. adam/commands/audit/completions_l.py +15 -0
  18. adam/commands/audit/show_last10.py +2 -14
  19. adam/commands/audit/show_slow10.py +2 -13
  20. adam/commands/audit/show_top10.py +2 -11
  21. adam/commands/audit/utils_show_top10.py +14 -1
  22. adam/commands/bash/bash.py +1 -1
  23. adam/commands/cat.py +5 -19
  24. adam/commands/cd.py +6 -8
  25. adam/commands/check.py +10 -18
  26. adam/commands/cli_commands.py +6 -1
  27. adam/commands/{cp.py → clipboard_copy.py} +34 -36
  28. adam/commands/code.py +2 -2
  29. adam/commands/command.py +94 -10
  30. adam/commands/commands_utils.py +19 -12
  31. adam/commands/cql/completions_c.py +28 -0
  32. adam/commands/cql/cqlsh.py +3 -7
  33. adam/commands/cql/utils_cql.py +22 -60
  34. adam/commands/deploy/deploy_pg_agent.py +2 -2
  35. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  36. adam/commands/devices/device.py +39 -8
  37. adam/commands/devices/device_app.py +19 -29
  38. adam/commands/devices/device_auit_log.py +3 -3
  39. adam/commands/devices/device_cass.py +17 -23
  40. adam/commands/devices/device_export.py +12 -11
  41. adam/commands/devices/device_postgres.py +79 -63
  42. adam/commands/download_file.py +47 -0
  43. adam/commands/export/clean_up_all_export_sessions.py +3 -3
  44. adam/commands/export/clean_up_export_sessions.py +7 -19
  45. adam/commands/export/completions_x.py +11 -0
  46. adam/commands/export/download_export_session.py +40 -0
  47. adam/commands/export/drop_export_database.py +6 -22
  48. adam/commands/export/drop_export_databases.py +3 -9
  49. adam/commands/export/export.py +1 -17
  50. adam/commands/export/export_databases.py +93 -21
  51. adam/commands/export/export_select.py +8 -68
  52. adam/commands/export/export_sessions.py +209 -0
  53. adam/commands/export/export_use.py +13 -16
  54. adam/commands/export/export_x_select.py +48 -0
  55. adam/commands/export/exporter.py +108 -129
  56. adam/commands/export/import_files.py +44 -0
  57. adam/commands/export/import_session.py +10 -6
  58. adam/commands/export/importer.py +19 -5
  59. adam/commands/export/importer_athena.py +112 -41
  60. adam/commands/export/importer_sqlite.py +47 -19
  61. adam/commands/export/show_column_counts.py +11 -20
  62. adam/commands/export/show_export_databases.py +5 -2
  63. adam/commands/export/show_export_session.py +6 -15
  64. adam/commands/export/show_export_sessions.py +4 -11
  65. adam/commands/export/utils_export.py +46 -16
  66. adam/commands/find_files.py +51 -0
  67. adam/commands/find_processes.py +76 -0
  68. adam/commands/head.py +36 -0
  69. adam/commands/help.py +2 -2
  70. adam/commands/intermediate_command.py +6 -3
  71. adam/commands/ls.py +1 -1
  72. adam/commands/medusa/medusa_backup.py +13 -16
  73. adam/commands/medusa/medusa_restore.py +39 -32
  74. adam/commands/medusa/medusa_show_backupjobs.py +6 -4
  75. adam/commands/medusa/medusa_show_restorejobs.py +5 -3
  76. adam/commands/medusa/utils_medusa.py +15 -0
  77. adam/commands/nodetool.py +3 -8
  78. adam/commands/param_get.py +10 -12
  79. adam/commands/param_set.py +7 -10
  80. adam/commands/postgres/completions_p.py +22 -0
  81. adam/commands/postgres/postgres.py +25 -40
  82. adam/commands/postgres/postgres_databases.py +270 -0
  83. adam/commands/postgres/utils_postgres.py +33 -20
  84. adam/commands/preview_table.py +4 -2
  85. adam/commands/pwd.py +3 -3
  86. adam/commands/reaper/reaper_forward.py +2 -2
  87. adam/commands/reaper/reaper_run_abort.py +4 -10
  88. adam/commands/reaper/reaper_runs.py +3 -3
  89. adam/commands/reaper/reaper_schedule_activate.py +12 -12
  90. adam/commands/reaper/reaper_schedule_start.py +7 -12
  91. adam/commands/reaper/reaper_schedule_stop.py +7 -12
  92. adam/commands/reaper/utils_reaper.py +13 -6
  93. adam/commands/repair/repair_scan.py +0 -2
  94. adam/commands/repair/repair_stop.py +0 -1
  95. adam/commands/shell.py +7 -5
  96. adam/commands/show/show.py +1 -1
  97. adam/commands/show/show_adam.py +3 -3
  98. adam/commands/show/show_cassandra_repairs.py +5 -3
  99. adam/commands/show/show_cassandra_status.py +27 -20
  100. adam/commands/show/{show_commands.py → show_cli_commands.py} +2 -2
  101. adam/commands/show/show_login.py +2 -2
  102. adam/commands/show/show_params.py +2 -5
  103. adam/commands/show/show_processes.py +15 -14
  104. adam/commands/show/show_storage.py +9 -8
  105. adam/config.py +1 -0
  106. adam/embedded_params.py +1 -1
  107. adam/repl.py +20 -11
  108. adam/repl_commands.py +16 -9
  109. adam/repl_session.py +8 -1
  110. adam/repl_state.py +33 -10
  111. adam/sql/lark_completer.py +280 -0
  112. adam/sql/lark_parser.py +604 -0
  113. adam/sql/sql_state_machine.py +8 -2
  114. adam/utils.py +116 -29
  115. adam/utils_athena.py +7 -8
  116. adam/utils_issues.py +2 -2
  117. adam/utils_k8s/app_clusters.py +2 -2
  118. adam/utils_k8s/app_pods.py +5 -2
  119. adam/utils_k8s/cassandra_clusters.py +11 -3
  120. adam/utils_k8s/cassandra_nodes.py +2 -2
  121. adam/utils_k8s/k8s.py +14 -5
  122. adam/utils_k8s/kube_context.py +2 -2
  123. adam/utils_k8s/pods.py +23 -5
  124. adam/utils_k8s/statefulsets.py +5 -2
  125. adam/utils_local.py +4 -0
  126. adam/utils_repl/appendable_completer.py +6 -0
  127. adam/utils_repl/repl_completer.py +128 -2
  128. adam/utils_sqlite.py +14 -14
  129. adam/version.py +1 -1
  130. {kaqing-2.0.172.dist-info → kaqing-2.0.186.dist-info}/METADATA +1 -1
  131. kaqing-2.0.186.dist-info/RECORD +250 -0
  132. adam/commands/cql/cql_completions.py +0 -33
  133. adam/commands/export/export_handlers.py +0 -71
  134. adam/commands/export/export_select_x.py +0 -54
  135. adam/commands/postgres/postgres_context.py +0 -272
  136. adam/commands/postgres/psql_completions.py +0 -10
  137. kaqing-2.0.172.dist-info/RECORD +0 -230
  138. {kaqing-2.0.172.dist-info → kaqing-2.0.186.dist-info}/WHEEL +0 -0
  139. {kaqing-2.0.172.dist-info → kaqing-2.0.186.dist-info}/entry_points.txt +0 -0
  140. {kaqing-2.0.172.dist-info → kaqing-2.0.186.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,14 @@ from adam.repl_state import ReplState
12
12
  from adam.utils import log2, log_timing, wait_log
13
13
  from adam.utils_k8s.statefulsets import StatefulSets
14
14
 
15
+ def cd_dirs(state: ReplState) -> list[str]:
16
+ if state.pod:
17
+ return [".."]
18
+ elif state.sts:
19
+ return [".."] + StatefulSets.pod_names(state.sts, state.namespace)
20
+ else:
21
+ return StatefulSets.list_sts_names()
22
+
15
23
  @functools.lru_cache()
16
24
  def cassandra_keyspaces(state: ReplState, on_any=True):
17
25
  if state.pod:
@@ -47,7 +55,7 @@ def table_spec(state: ReplState, table: str, on_any=False) -> 'TableSpec':
47
55
 
48
56
  return parse_cql_desc_table(r.stdout if state.pod else r[0].stdout)
49
57
 
50
- def run_cql(state: ReplState, cql: str, opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, background=False, log_file=None) -> list[PodExecResult]:
58
+ def run_cql(state: ReplState, cql: str, opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, backgrounded=False, log_file=None) -> list[PodExecResult]:
51
59
  if show_query:
52
60
  log2(cql)
53
61
 
@@ -61,7 +69,7 @@ def run_cql(state: ReplState, cql: str, opts: list = [], show_out = False, show_
61
69
 
62
70
  with log_timing(cql):
63
71
  with cassandra(state) as pods:
64
- return pods.exec(command, action='cql', show_out=show_out, on_any=on_any, background=background, log_file=log_file)
72
+ return pods.exec(command, action='cql', show_out=show_out, on_any=on_any, backgrounded=backgrounded, log_file=log_file)
65
73
 
66
74
  def parse_cql_desc_tables(out: str):
67
75
  # Keyspace data_endpoint_auth
@@ -215,70 +223,24 @@ def parse_cql_desc_table(out: str) -> TableSpec:
215
223
 
216
224
  return TableSpec(columns)
217
225
 
218
- class CqlShHandler:
219
- def __init__(self, state: ReplState, opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, background=False):
220
- self.state = state
221
- self.opts = opts
222
- self.show_out = show_out
223
- self.show_query = show_query
224
- self.use_single_quotes = use_single_quotes
225
- self.on_any = on_any
226
- self.backgroud = background
227
-
228
- def __enter__(self):
229
- return self.query
230
-
231
- def __exit__(self, exc_type, exc_val, exc_tb):
232
- return False
233
-
234
- def query(self, args: list[str], log_file: str = None):
235
- query: str = args
236
- background = self.backgroud
237
- show_out = self.show_out
238
-
239
- if isinstance(query, list):
240
- opts = []
241
- cqls = []
242
- for index, arg in enumerate(args):
243
- if arg.startswith('--'):
244
- opts.append(arg)
245
- # elif index == len(args) -1 and arg == '&':
246
- # background = True
247
- elif arg != '-e':
248
- cqls.append(arg)
249
- if not cqls:
250
- if self.state.in_repl:
251
- log2('Please enter cql statement. e.g. select host_id from system.local')
252
- else:
253
- log2('* CQL statement is missing.')
254
- log2()
255
- Command.display_help()
256
-
257
- return 'no-cql'
258
-
259
- query = ' '.join(cqls)
260
- show_out = True
261
-
262
- return run_cql(self.state, query, opts=self.opts, show_out=show_out, show_query=self.show_query, use_single_quotes=self.use_single_quotes, on_any=self.on_any, background=background, log_file=log_file)
263
-
264
226
  class CassandraPodService:
265
227
  def __init__(self, handler: 'CassandraExecHandler'):
266
228
  self.handler = handler
267
229
 
268
- def exec(self, command: str, action='bash', show_out = True, on_any = False, throw_err = False, shell = '/bin/sh', background = False, log_file = None) -> Union[PodExecResult, list[PodExecResult]]:
230
+ def exec(self, command: str, action='bash', show_out = True, on_any = False, throw_err = False, shell = '/bin/sh', backgrounded = False, log_file = None) -> Union[PodExecResult, list[PodExecResult]]:
269
231
  state = self.handler.state
270
232
  pod = self.handler.pod
271
233
 
272
234
  if pod:
273
235
  return CassandraNodes.exec(pod, state.namespace, command,
274
- show_out=show_out, throw_err=throw_err, shell=shell, background=background, log_file=log_file)
236
+ show_out=show_out, throw_err=throw_err, shell=shell, backgrounded=backgrounded, log_file=log_file)
275
237
  elif state.sts:
276
238
  return CassandraClusters.exec(state.sts, state.namespace, command, action=action,
277
- show_out=show_out, on_any=on_any, shell=shell, background=background, log_file=log_file)
239
+ show_out=show_out, on_any=on_any, shell=shell, backgrounded=backgrounded, log_file=log_file)
278
240
 
279
241
  return []
280
242
 
281
- def cql(self, args: list[str], opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, background=False, log_file: str = None):
243
+ def cql(self, args: list[str], opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, backgrounded=False, log_file: str = None):
282
244
  state = self.handler.state
283
245
  query: str = args
284
246
 
@@ -303,18 +265,18 @@ class CassandraPodService:
303
265
  query = ' '.join(cqls)
304
266
  show_out = True
305
267
 
306
- return run_cql(state, query, opts=opts, show_out=show_out, show_query=show_query, use_single_quotes=use_single_quotes, on_any=on_any, background=background, log_file=log_file)
268
+ return run_cql(state, query, opts=opts, show_out=show_out, show_query=show_query, use_single_quotes=use_single_quotes, on_any=on_any, backgrounded=backgrounded, log_file=log_file)
307
269
 
308
- def display_table(self, cols: str, header: str, show_out = True):
270
+ def display_table(self, cols: str, header: str, show_out = True, backgrounded = False):
309
271
  state = self.handler.state
310
272
 
311
273
  if state.pod:
312
- show_table(state, [state.pod], cols, header, show_out=show_out)
274
+ return show_table(state, [state.pod], cols, header, show_out=show_out, backgrounded = backgrounded)
313
275
  elif state.sts:
314
276
  pod_names = [pod.metadata.name for pod in StatefulSets.pods(state.sts, state.namespace)]
315
- show_table(state, pod_names, cols, header, show_out=show_out)
277
+ return show_table(state, pod_names, cols, header, show_out=show_out, backgrounded = backgrounded)
316
278
 
317
- def nodetool(self, args: str, show_out = True) -> Union[PodExecResult, list[PodExecResult]]:
279
+ def nodetool(self, args: str, status = False, show_out = True, backgrounded = False) -> Union[PodExecResult, list[PodExecResult]]:
318
280
  state = self.handler.state
319
281
  pod = self.handler.pod
320
282
 
@@ -322,9 +284,9 @@ class CassandraPodService:
322
284
  command = f"nodetool -u {user} -pw {pw} {args}"
323
285
 
324
286
  if pod:
325
- return CassandraNodes.exec(pod, state.namespace, command, show_out=show_out)
287
+ return CassandraNodes.exec(pod, state.namespace, command, show_out=show_out, backgrounded=backgrounded)
326
288
  else:
327
- return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool', show_out=show_out)
289
+ return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool.status' if status else 'nodetool', show_out=show_out, backgrounded=backgrounded)
328
290
 
329
291
  class CassandraExecHandler:
330
292
  def __init__(self, state: ReplState, pod: str = None):
@@ -340,4 +302,4 @@ class CassandraExecHandler:
340
302
  return False
341
303
 
342
304
  def cassandra(state: ReplState, pod: str=None):
343
- return CassandraExecHandler(state, pod=pod)
305
+ return CassandraExecHandler(state, pod=pod)
@@ -1,5 +1,5 @@
1
1
  from adam.commands.command import Command
2
- from adam.commands.postgres.postgres_context import PostgresContext
2
+ from adam.commands.postgres.postgres_databases import PostgresDatabases
3
3
  from adam.config import Config
4
4
  from adam.repl_state import ReplState, RequiredState
5
5
 
@@ -26,7 +26,7 @@ class DeployPgAgent(Command):
26
26
  return super().run(cmd, state)
27
27
 
28
28
  with self.validate(args, state) as (args, state):
29
- PostgresContext.deploy_pg_agent(Config().get('pg.agent.name', 'ops-pg-agent'), state.namespace)
29
+ PostgresDatabases.deploy_pg_agent(Config().get('pg.agent.name', 'ops-pg-agent'), state.namespace)
30
30
 
31
31
  def completion(self, state: ReplState):
32
32
  return super().completion(state)
@@ -1,5 +1,5 @@
1
1
  from adam.commands.command import Command
2
- from adam.commands.postgres.postgres_context import PostgresContext
2
+ from adam.commands.postgres.postgres_databases import PostgresDatabases
3
3
  from adam.config import Config
4
4
  from adam.repl_state import ReplState, RequiredState
5
5
  from adam.utils import ing
@@ -28,7 +28,7 @@ class UndeployPgAgent(Command):
28
28
 
29
29
  with self.validate(args, state) as (args, state):
30
30
  with ing('Deleting pod'):
31
- PostgresContext.undeploy_pg_agent(Config().get('pg.agent.name', 'ops-pg-agent'), state.namespace)
31
+ PostgresDatabases.undeploy_pg_agent(Config().get('pg.agent.name', 'ops-pg-agent'), state.namespace)
32
32
 
33
33
  return state
34
34
 
@@ -5,20 +5,35 @@ from adam.config import Config
5
5
  from adam.pod_exec_result import PodExecResult
6
6
  from adam.repl_state import BashSession, ReplState
7
7
  from adam.utils import log2
8
+ from adam.utils_k8s.pods import Pods
8
9
 
9
10
  class Device:
10
- @abstractmethod
11
- def ls(self, cmd: str, state: ReplState):
12
- pass
11
+ def pods(self, state: ReplState, me: str = None) -> tuple[list[str], str]:
12
+ return self.pod_names(state), me if me else self.pod(state)
13
13
 
14
- def ls_completion(self, cmd: str, state: ReplState, default: dict = {}):
15
- return default
14
+ def default_pod(self, state: ReplState) -> tuple[list[str], str]:
15
+ if me := self.pod(state):
16
+ return me
17
+
18
+ if pods := self.pod_names(state):
19
+ return pods[0]
20
+
21
+ return None
22
+
23
+ def pod(self, state: ReplState) -> str:
24
+ return None
25
+
26
+ def pod_names(self, state: ReplState) -> list[str]:
27
+ return []
28
+
29
+ def default_container(self, state: ReplState) -> str:
30
+ return None
16
31
 
17
32
  @abstractmethod
18
- def cat(self, cmd: str, state: ReplState):
33
+ def ls(self, cmd: str, state: ReplState):
19
34
  pass
20
35
 
21
- def cat_completion(self, cmd: str, state: ReplState, default: dict = {}):
36
+ def ls_completion(self, cmd: str, state: ReplState, default: dict = {}):
22
37
  return default
23
38
 
24
39
  def cd(self, dir: str, state: ReplState):
@@ -27,6 +42,9 @@ class Device:
27
42
  def cd_completion(self, cmd: str, state: ReplState, default: dict = {}):
28
43
  return default
29
44
 
45
+ def direct_dirs(self, cmd: str, state: ReplState, default: dict = {}) -> list[str]:
46
+ return []
47
+
30
48
  @abstractmethod
31
49
  def pwd(self, state: ReplState):
32
50
  pass
@@ -115,4 +133,17 @@ class Device:
115
133
  pass
116
134
 
117
135
  def bash_completion(self, cmd: str, state: ReplState, default: dict = {}):
118
- return default
136
+ return default
137
+
138
+ def files(self, state: ReplState):
139
+ r: PodExecResult = Pods.exec(self.default_pod(state), self.default_container(state), state.namespace, f'find -maxdepth 1 -type f', show_out=Config().is_debug(), shell='bash')
140
+
141
+ log_files = []
142
+ for line in r.stdout.split('\n'):
143
+ line = line.strip(' \r')
144
+ if line:
145
+ if line.startswith('./'):
146
+ line = line[2:]
147
+ log_files.append(line)
148
+
149
+ return log_files
@@ -1,11 +1,11 @@
1
1
  from adam.apps import Apps
2
2
  from adam.commands import app
3
3
  from adam.commands.bash.bash_completer import BashCompleter
4
- from adam.commands.command import Command, InvalidState
4
+ from adam.commands.command import Command, InvalidStateException
5
5
  from adam.commands.devices.device import Device
6
6
  from adam.config import Config
7
7
  from adam.repl_state import ReplState
8
- from adam.utils import lines_to_tabular, log, wait_log
8
+ from adam.utils import tabulize, log, wait_log
9
9
  from adam.utils_k8s.app_pods import AppPods
10
10
  from adam.utils_k8s.ingresses import Ingresses
11
11
 
@@ -38,13 +38,20 @@ class DeviceApp(Command, Device):
38
38
  def help(self, _: ReplState):
39
39
  return f'{DeviceApp.COMMAND}\t move to App Operations device'
40
40
 
41
+ def pod(self, state: ReplState) -> str:
42
+ return state.app_pod
43
+
44
+ def pod_names(self, state: ReplState) -> list[str]:
45
+ return AppPods.pod_names(state.namespace, state.app_env, state.app_app)
46
+
47
+ def default_container(self, state: ReplState) -> str:
48
+ return Config().get('app.container-name', 'c3-server')
49
+
41
50
  def ls(self, cmd: str, state: ReplState):
42
51
  if state.app_pod:
43
52
  return self.bash(state, state, cmd.split(' '))
44
53
  elif state.app_app:
45
- pods = AppPods.pod_names(state.namespace, state.app_env, state.app_app)
46
-
47
- log(lines_to_tabular(pods, 'POD_NAME'))
54
+ tabulize(self.pod_names(state), header='POD_NAME')
48
55
  elif state.app_env:
49
56
  def line(n: str, ns: str):
50
57
  host = Ingresses.get_host(Config().get('app.login.ingress', '{app_id}-k8singr-appleader-001').replace('{app_id}', f'{ns}-{n}'), ns)
@@ -59,30 +66,13 @@ class DeviceApp(Command, Device):
59
66
 
60
67
  svcs = [l for l in [line(n, ns) for n, ns in Apps.apps(state.app_env)] if l]
61
68
 
62
- log(lines_to_tabular(svcs, 'APP,HOST,ENDPOINT', separator=','))
69
+ tabulize(svcs, header='APP,HOST,ENDPOINT', separator=',')
63
70
  else:
64
- svcs = [n for n, ns in Apps.envs()]
65
-
66
- log(lines_to_tabular(svcs, 'ENV', separator=','))
71
+ tabulize(Apps.envs(), lambda a: a[0], header='ENV', separator=',')
67
72
 
68
73
  def ls_completion(self, cmd, state, default: dict = {}):
69
74
  if state.app_app:
70
- def pod_names():
71
- return [p for p in AppPods.pod_names(state.namespace, state.app_env, state.app_app)]
72
-
73
- return super().completion(state) | {f'@{p}': {cmd: None} for p in pod_names()}
74
-
75
- return default
76
-
77
- def cat(self, cmd: str, state: ReplState):
78
- if state.app_pod:
79
- return self.bash(state, state, cmd.split(' '))
80
-
81
- return InvalidState()
82
-
83
- def cat_completion(self, cmd: str, state: ReplState, default: dict = {}):
84
- if state.app_app:
85
- return {f'@{p}': {cmd: None} for p in AppPods.pod_names(state.namespace, state.app_env, state.app_app)}
75
+ return super().completion(state) | {f'@{p}': {cmd: None} for p in self.pod_names(state)}
86
76
 
87
77
  return default
88
78
 
@@ -112,7 +102,7 @@ class DeviceApp(Command, Device):
112
102
 
113
103
  def cd_completion(self, cmd: str, state: ReplState, default: dict = {}):
114
104
  if state.app_app:
115
- return {cmd: {'..': None} | {pod: None for pod in AppPods.pod_names(state.namespace, state.app_env, state.app_app)}}
105
+ return {cmd: {'..': None} | {pod: None for pod in self.pod_names(state)}}
116
106
  elif state.app_env:
117
107
  return {cmd: {'..': None} | {app[0].split('-')[1]: None for app in Apps.apps(state.app_env)}}
118
108
  else:
@@ -126,7 +116,7 @@ class DeviceApp(Command, Device):
126
116
  if state.app_app:
127
117
  words.append(f'app/{state.app_app}')
128
118
 
129
- return '\t'.join([f'{ReplState.X}:>'] + (words if words else ['/']))
119
+ return '\t'.join([f'{ReplState.A}:>'] + (words if words else ['/']))
130
120
 
131
121
  def try_fallback_action(self, chain: Command, state: ReplState, cmd: str):
132
122
  if state.app_app:
@@ -144,7 +134,7 @@ class DeviceApp(Command, Device):
144
134
  state.app_app = ea[1]
145
135
  state.app_pod = ea[2]
146
136
  if state.app_pod == '*':
147
- if (pods := AppPods.pod_names(state.namespace, ea[0], ea[1])):
137
+ if (pods := self.pod_names(state)):
148
138
  state.app_pod = pods[0]
149
139
  wait_log(f'Moving to {state.app_env}/{state.app_app}/{state.app_pod}...')
150
140
  else:
@@ -170,4 +160,4 @@ class DeviceApp(Command, Device):
170
160
 
171
161
  def bash_completion(self, cmd: str, state: ReplState, default: dict = {}):
172
162
  return {cmd: BashCompleter(lambda: [])} | \
173
- {f'@{p}': {cmd: BashCompleter(lambda: [])} for p in AppPods.pod_names(state.namespace, state.app_env, state.app_app)}
163
+ {f'@{p}': {cmd: BashCompleter(lambda: [])} for p in self.pod_names(state)}
@@ -1,7 +1,7 @@
1
1
  from adam.commands.command import Command
2
2
  from adam.commands.devices.device import Device
3
3
  from adam.repl_state import ReplState
4
- from adam.utils import lines_to_tabular, log
4
+ from adam.utils import tabulize, log
5
5
  from adam.utils_athena import Athena
6
6
 
7
7
  class DeviceAuditLog(Command, Device):
@@ -34,7 +34,7 @@ class DeviceAuditLog(Command, Device):
34
34
  return f'{DeviceAuditLog.COMMAND}\t move to Audit Log Operations device'
35
35
 
36
36
  def ls(self, cmd: str, _: ReplState):
37
- log(lines_to_tabular(Athena.table_names(), 'NAME', separator=','))
37
+ tabulize(Athena.table_names(), header='NAME', separator=',')
38
38
 
39
39
  def pwd(self, _: ReplState):
40
40
  return '\t'.join([f'{ReplState.L}:>', '/'])
@@ -43,7 +43,7 @@ class DeviceAuditLog(Command, Device):
43
43
  return True, chain.run(f'audit {cmd}', state)
44
44
 
45
45
  def show_tables(self, _: ReplState):
46
- log(lines_to_tabular(Athena.table_names(), separator=','))
46
+ tabulize(Athena.table_names(), separator=',')
47
47
 
48
48
  def show_table_preview(self, _: ReplState, table: str, rows: int):
49
49
  Athena.run_query(f'select * from {table} limit {rows}')
@@ -1,11 +1,11 @@
1
1
  from adam.commands.bash.bash_completer import BashCompleter
2
- from adam.commands.command import Command, InvalidState
2
+ from adam.commands.command import Command, InvalidStateException
3
3
  from adam.commands.commands_utils import show_pods, show_rollout
4
4
  from adam.commands.cql.utils_cql import cassandra, cassandra_table_names
5
5
  from adam.commands.devices.device import Device
6
6
  from adam.config import Config
7
7
  from adam.repl_state import ReplState
8
- from adam.utils import lines_to_tabular, log, log2, wait_log
8
+ from adam.utils import tabulize, log, log2, wait_log
9
9
  from adam.utils_k8s.cassandra_clusters import CassandraClusters
10
10
  from adam.utils_k8s.custom_resources import CustomResources
11
11
  from adam.utils_k8s.kube_context import KubeContext
@@ -34,12 +34,21 @@ class DeviceCass(Command, Device):
34
34
 
35
35
  return state
36
36
 
37
+ def pod(self, state: ReplState) -> str:
38
+ return state.pod
39
+
40
+ def pod_names(self, state: ReplState) -> list[str]:
41
+ return StatefulSets.pod_names(state.sts, state.namespace)
42
+
37
43
  def completion(self, state: ReplState):
38
44
  return super().completion(state)
39
45
 
40
46
  def help(self, _: ReplState):
41
47
  return f'{DeviceCass.COMMAND}\t move to Cassandra Operations device'
42
48
 
49
+ def default_container(self, _: ReplState) -> str:
50
+ return 'cassandra'
51
+
43
52
  def ls(self, cmd: str, state: ReplState):
44
53
  if state.pod:
45
54
  return self.bash(state, state, cmd.split(' '))
@@ -50,26 +59,11 @@ class DeviceCass(Command, Device):
50
59
  self.show_statefulsets()
51
60
 
52
61
  def ls_completion(self, cmd: str, state: ReplState, default: dict = {}):
53
- def pod_names():
54
- return [p for p in StatefulSets.pod_names(state.sts, state.namespace)]
55
-
56
62
  if state.sts:
57
- return super().completion(state) | {f'@{p}': {'ls': None} for p in pod_names()}
63
+ return super().completion(state) | {f'@{p}': {'ls': None} for p in self.pod_names(state)}
58
64
  else:
59
65
  return {cmd: {n: None for n in StatefulSets.list_sts_names()}}
60
66
 
61
- def cat(self, cmd: str, state: ReplState):
62
- if state.pod:
63
- return self.bash(state, state, cmd.split(' '))
64
-
65
- return InvalidState()
66
-
67
- def cat_completion(self, cmd: str, state: ReplState, default: dict = {}):
68
- if state.sts:
69
- return {f'@{p}': {cmd: None} for p in StatefulSets.pod_names(state.sts, state.namespace)}
70
-
71
- return default
72
-
73
67
  def show_statefulsets(self):
74
68
  ss = StatefulSets.list_sts_names()
75
69
  if len(ss) == 0:
@@ -88,7 +82,7 @@ class DeviceCass(Command, Device):
88
82
  header = 'STATEFULSET_NAME@NAMESPACE APP_ID'
89
83
  if KubeContext.in_cluster_namespace():
90
84
  header = 'STATEFULSET_NAME APP_ID'
91
- log(lines_to_tabular(list, header))
85
+ tabulize(list, header=header)
92
86
 
93
87
  def cd(self, dir: str, state: ReplState):
94
88
  if dir == '':
@@ -110,7 +104,7 @@ class DeviceCass(Command, Device):
110
104
  if p:
111
105
  state.pod = p
112
106
  else:
113
- names = CassandraClusters.pod_names_by_host_id(state.sts, state.namespace);
107
+ names = CassandraClusters.pod_names_by_host_id(state.sts, state.namespace)
114
108
  if dir in names:
115
109
  state.pod = names[dir]
116
110
  else:
@@ -120,7 +114,7 @@ class DeviceCass(Command, Device):
120
114
  if state.pod:
121
115
  return {cmd: {'..': None}}
122
116
  elif state.sts:
123
- return {cmd: {'..': None} | {p: None for p in StatefulSets.pod_names(state.sts, state.namespace)}}
117
+ return {cmd: {'..': None} | {p: None for p in self.pod_names(state)}}
124
118
  else:
125
119
  return {cmd: {p: None for p in StatefulSets.list_sts_names()}}
126
120
 
@@ -158,7 +152,7 @@ class DeviceCass(Command, Device):
158
152
  wait_log(f'Moving to the only Cassandra cluster: {state.sts}@{state.namespace}...')
159
153
 
160
154
  def show_tables(self, state: ReplState):
161
- log(lines_to_tabular(cassandra_table_names(state), separator=','))
155
+ tabulize(cassandra_table_names(state), separator=',')
162
156
 
163
157
  def show_table_preview(self, state: ReplState, table: str, rows: int):
164
158
  with cassandra(state) as pods:
@@ -179,7 +173,7 @@ class DeviceCass(Command, Device):
179
173
  completions = {cmd: BashCompleter(lambda: [])}
180
174
 
181
175
  if state.sts and state.namespace:
182
- completions |= {f'@{p}': {cmd: BashCompleter(lambda: [])} for p in StatefulSets.pod_names(state.sts, state.namespace)}
176
+ completions |= {f'@{p}': {cmd: BashCompleter(lambda: [])} for p in self.pod_names(state)}
183
177
 
184
178
  return completions
185
179
 
@@ -1,9 +1,9 @@
1
1
  from adam.commands.command import Command
2
2
  from adam.commands.devices.device import Device
3
- from adam.commands.export.export_databases import ExportDatabases
3
+ from adam.commands.export.export_databases import ExportDatabases, export_db
4
4
  from adam.config import Config
5
5
  from adam.repl_state import ReplState
6
- from adam.utils import lines_to_tabular, log, log2, wait_log
6
+ from adam.utils import tabulize, log2, wait_log
7
7
 
8
8
  class DeviceExport(Command, Device):
9
9
  COMMAND = f'{ReplState.X}:'
@@ -36,16 +36,14 @@ class DeviceExport(Command, Device):
36
36
 
37
37
  def ls(self, cmd: str, state: ReplState):
38
38
  if state.export_session:
39
- self.show_export_tables(state.export_session)
39
+ tabulize(ExportDatabases.table_names(state.export_session), header='NAME', separator=',')
40
40
  else:
41
- self.show_export_databases()
41
+ ExportDatabases.show_databases()
42
42
 
43
- def show_export_databases(self, importer: str = None):
44
- lines = [f'{k}\t{v}' for k, v in ExportDatabases.database_names_with_keyspace_cnt(importer).items()]
45
- log(lines_to_tabular(lines, 'NAME\tKEYSPACES', separator='\t'))
46
-
47
- def show_export_tables(self, export_session: str):
48
- log(lines_to_tabular(ExportDatabases.table_names(export_session), 'NAME', separator=','))
43
+ def show_table_preview(self, state: ReplState, table: str, rows: int):
44
+ if state.export_session:
45
+ with export_db(state) as dbs:
46
+ dbs.sql(f'select * from {table} limit {rows}')
49
47
 
50
48
  def cd(self, dir: str, state: ReplState):
51
49
  if dir in ['', '..']:
@@ -68,7 +66,10 @@ class DeviceExport(Command, Device):
68
66
  return '\t'.join([f'{ReplState.X}:>'] + (words if words else ['/']))
69
67
 
70
68
  def try_fallback_action(self, chain: Command, state: ReplState, cmd: str):
71
- result = chain.run(f'.{cmd}', state)
69
+ if cmd.startswith('select '):
70
+ cmd = f'xelect {cmd[7:]}'
71
+
72
+ result = chain.run(cmd, state)
72
73
  if type(result) is ReplState:
73
74
  if state.export_session and not result.export_session:
74
75
  state.export_session = None