kaqing 2.0.52__py3-none-any.whl → 2.0.184__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 (223) hide show
  1. adam/__init__.py +0 -2
  2. adam/app_session.py +9 -12
  3. adam/apps.py +20 -6
  4. adam/batch.py +15 -19
  5. adam/checks/check_utils.py +19 -49
  6. adam/checks/compactionstats.py +1 -1
  7. adam/checks/cpu.py +9 -3
  8. adam/checks/cpu_metrics.py +52 -0
  9. adam/checks/disk.py +3 -4
  10. adam/checks/gossip.py +1 -1
  11. adam/checks/memory.py +3 -3
  12. adam/checks/status.py +1 -1
  13. adam/columns/columns.py +3 -1
  14. adam/columns/cpu.py +3 -1
  15. adam/columns/cpu_metrics.py +22 -0
  16. adam/columns/memory.py +3 -4
  17. adam/commands/__init__.py +24 -0
  18. adam/commands/alter_tables.py +37 -63
  19. adam/commands/app/app.py +38 -0
  20. adam/commands/{app_ping.py → app/app_ping.py} +8 -14
  21. adam/commands/app/show_app_actions.py +49 -0
  22. adam/commands/{show → app}/show_app_id.py +9 -12
  23. adam/commands/{show → app}/show_app_queues.py +8 -14
  24. adam/commands/app/utils_app.py +98 -0
  25. adam/commands/audit/audit.py +81 -0
  26. adam/commands/audit/audit_repair_tables.py +72 -0
  27. adam/commands/audit/audit_run.py +50 -0
  28. adam/commands/audit/show_last10.py +37 -0
  29. adam/commands/audit/show_slow10.py +36 -0
  30. adam/commands/audit/show_top10.py +36 -0
  31. adam/commands/audit/utils_show_top10.py +71 -0
  32. adam/commands/bash/__init__.py +5 -0
  33. adam/commands/bash/bash.py +36 -0
  34. adam/commands/bash/bash_completer.py +93 -0
  35. adam/commands/bash/utils_bash.py +16 -0
  36. adam/commands/cat.py +36 -0
  37. adam/commands/cd.py +14 -89
  38. adam/commands/check.py +18 -21
  39. adam/commands/cli_commands.py +5 -6
  40. adam/commands/clipboard_copy.py +86 -0
  41. adam/commands/code.py +57 -0
  42. adam/commands/command.py +197 -35
  43. adam/commands/commands_utils.py +15 -31
  44. adam/commands/cql/cql_completions.py +29 -8
  45. adam/commands/cql/cqlsh.py +12 -27
  46. adam/commands/cql/utils_cql.py +297 -0
  47. adam/commands/deploy/code_start.py +7 -10
  48. adam/commands/deploy/code_stop.py +4 -21
  49. adam/commands/deploy/code_utils.py +5 -5
  50. adam/commands/deploy/deploy.py +4 -21
  51. adam/commands/deploy/deploy_frontend.py +14 -17
  52. adam/commands/deploy/deploy_pg_agent.py +3 -6
  53. adam/commands/deploy/deploy_pod.py +71 -79
  54. adam/commands/deploy/deploy_utils.py +16 -26
  55. adam/commands/deploy/undeploy.py +4 -21
  56. adam/commands/deploy/undeploy_frontend.py +4 -7
  57. adam/commands/deploy/undeploy_pg_agent.py +6 -8
  58. adam/commands/deploy/undeploy_pod.py +15 -16
  59. adam/commands/devices/__init__.py +0 -0
  60. adam/commands/devices/device.py +123 -0
  61. adam/commands/devices/device_app.py +163 -0
  62. adam/commands/devices/device_auit_log.py +49 -0
  63. adam/commands/devices/device_cass.py +179 -0
  64. adam/commands/devices/device_export.py +84 -0
  65. adam/commands/devices/device_postgres.py +150 -0
  66. adam/commands/devices/devices.py +25 -0
  67. adam/commands/download_file.py +47 -0
  68. adam/commands/exit.py +1 -4
  69. adam/commands/export/__init__.py +0 -0
  70. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  71. adam/commands/export/clean_up_export_sessions.py +39 -0
  72. adam/commands/export/download_export_session.py +39 -0
  73. adam/commands/export/drop_export_database.py +39 -0
  74. adam/commands/export/drop_export_databases.py +37 -0
  75. adam/commands/export/export.py +53 -0
  76. adam/commands/export/export_databases.py +245 -0
  77. adam/commands/export/export_select.py +59 -0
  78. adam/commands/export/export_select_x.py +54 -0
  79. adam/commands/export/export_sessions.py +209 -0
  80. adam/commands/export/export_use.py +49 -0
  81. adam/commands/export/exporter.py +332 -0
  82. adam/commands/export/import_files.py +44 -0
  83. adam/commands/export/import_session.py +44 -0
  84. adam/commands/export/importer.py +81 -0
  85. adam/commands/export/importer_athena.py +177 -0
  86. adam/commands/export/importer_sqlite.py +67 -0
  87. adam/commands/export/show_column_counts.py +45 -0
  88. adam/commands/export/show_export_databases.py +38 -0
  89. adam/commands/export/show_export_session.py +39 -0
  90. adam/commands/export/show_export_sessions.py +37 -0
  91. adam/commands/export/utils_export.py +343 -0
  92. adam/commands/find_files.py +51 -0
  93. adam/commands/find_processes.py +76 -0
  94. adam/commands/head.py +36 -0
  95. adam/commands/help.py +14 -9
  96. adam/commands/intermediate_command.py +49 -0
  97. adam/commands/issues.py +14 -40
  98. adam/commands/kubectl.py +38 -0
  99. adam/commands/login.py +26 -25
  100. adam/commands/logs.py +5 -7
  101. adam/commands/ls.py +11 -110
  102. adam/commands/medusa/medusa.py +4 -22
  103. adam/commands/medusa/medusa_backup.py +22 -29
  104. adam/commands/medusa/medusa_restore.py +40 -39
  105. adam/commands/medusa/medusa_show_backupjobs.py +19 -20
  106. adam/commands/medusa/medusa_show_restorejobs.py +15 -20
  107. adam/commands/nodetool.py +11 -15
  108. adam/commands/param_get.py +11 -14
  109. adam/commands/param_set.py +8 -12
  110. adam/commands/postgres/postgres.py +45 -46
  111. adam/commands/postgres/postgres_databases.py +269 -0
  112. adam/commands/postgres/postgres_ls.py +4 -8
  113. adam/commands/postgres/postgres_preview.py +5 -9
  114. adam/commands/postgres/psql_completions.py +4 -3
  115. adam/commands/postgres/utils_postgres.py +70 -0
  116. adam/commands/preview_table.py +10 -61
  117. adam/commands/pwd.py +14 -43
  118. adam/commands/reaper/reaper.py +4 -24
  119. adam/commands/reaper/reaper_forward.py +49 -56
  120. adam/commands/reaper/reaper_forward_session.py +6 -0
  121. adam/commands/reaper/reaper_forward_stop.py +10 -16
  122. adam/commands/reaper/reaper_restart.py +8 -15
  123. adam/commands/reaper/reaper_run_abort.py +8 -33
  124. adam/commands/reaper/reaper_runs.py +43 -58
  125. adam/commands/reaper/reaper_runs_abort.py +29 -49
  126. adam/commands/reaper/reaper_schedule_activate.py +9 -32
  127. adam/commands/reaper/reaper_schedule_start.py +9 -32
  128. adam/commands/reaper/reaper_schedule_stop.py +9 -32
  129. adam/commands/reaper/reaper_schedules.py +4 -14
  130. adam/commands/reaper/reaper_status.py +8 -16
  131. adam/commands/reaper/utils_reaper.py +194 -0
  132. adam/commands/repair/repair.py +4 -22
  133. adam/commands/repair/repair_log.py +6 -12
  134. adam/commands/repair/repair_run.py +29 -36
  135. adam/commands/repair/repair_scan.py +33 -39
  136. adam/commands/repair/repair_stop.py +6 -12
  137. adam/commands/report.py +25 -21
  138. adam/commands/restart.py +27 -28
  139. adam/commands/rollout.py +20 -25
  140. adam/commands/shell.py +12 -4
  141. adam/commands/show/show.py +11 -23
  142. adam/commands/show/show_adam.py +3 -3
  143. adam/commands/show/show_cassandra_repairs.py +35 -0
  144. adam/commands/show/show_cassandra_status.py +34 -52
  145. adam/commands/show/show_cassandra_version.py +5 -18
  146. adam/commands/show/show_commands.py +20 -25
  147. adam/commands/show/show_host.py +33 -0
  148. adam/commands/show/show_login.py +23 -27
  149. adam/commands/show/show_params.py +2 -5
  150. adam/commands/show/show_processes.py +16 -20
  151. adam/commands/show/show_storage.py +10 -20
  152. adam/commands/watch.py +27 -30
  153. adam/config.py +7 -15
  154. adam/embedded_params.py +1 -1
  155. adam/log.py +4 -4
  156. adam/pod_exec_result.py +13 -5
  157. adam/repl.py +126 -119
  158. adam/repl_commands.py +63 -29
  159. adam/repl_state.py +320 -71
  160. adam/sql/sql_completer.py +98 -383
  161. adam/sql/sql_state_machine.py +630 -0
  162. adam/sql/term_completer.py +14 -4
  163. adam/sso/authn_ad.py +6 -8
  164. adam/sso/authn_okta.py +4 -6
  165. adam/sso/cred_cache.py +4 -6
  166. adam/sso/idp.py +10 -13
  167. adam/utils.py +511 -10
  168. adam/utils_athena.py +145 -0
  169. adam/utils_audits.py +102 -0
  170. adam/utils_issues.py +32 -0
  171. adam/utils_k8s/__init__.py +0 -0
  172. adam/utils_k8s/app_clusters.py +28 -0
  173. adam/utils_k8s/app_pods.py +36 -0
  174. adam/utils_k8s/cassandra_clusters.py +44 -0
  175. adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +11 -4
  176. adam/{k8s_utils → utils_k8s}/custom_resources.py +16 -17
  177. adam/{k8s_utils → utils_k8s}/deployment.py +2 -2
  178. adam/{k8s_utils → utils_k8s}/ingresses.py +2 -2
  179. adam/{k8s_utils → utils_k8s}/jobs.py +7 -11
  180. adam/utils_k8s/k8s.py +87 -0
  181. adam/{k8s_utils → utils_k8s}/kube_context.py +2 -2
  182. adam/{k8s_utils → utils_k8s}/pods.py +109 -74
  183. adam/{k8s_utils → utils_k8s}/secrets.py +7 -3
  184. adam/{k8s_utils → utils_k8s}/service_accounts.py +5 -4
  185. adam/{k8s_utils → utils_k8s}/services.py +2 -2
  186. adam/{k8s_utils → utils_k8s}/statefulsets.py +3 -14
  187. adam/utils_local.py +4 -0
  188. adam/utils_net.py +24 -0
  189. adam/utils_repl/__init__.py +0 -0
  190. adam/utils_repl/automata_completer.py +48 -0
  191. adam/utils_repl/repl_completer.py +46 -0
  192. adam/utils_repl/state_machine.py +173 -0
  193. adam/utils_sqlite.py +137 -0
  194. adam/version.py +1 -1
  195. {kaqing-2.0.52.dist-info → kaqing-2.0.184.dist-info}/METADATA +1 -1
  196. kaqing-2.0.184.dist-info/RECORD +244 -0
  197. adam/commands/app.py +0 -67
  198. adam/commands/bash.py +0 -87
  199. adam/commands/cp.py +0 -95
  200. adam/commands/cql/cql_table_completer.py +0 -8
  201. adam/commands/cql/cql_utils.py +0 -109
  202. adam/commands/describe/describe.py +0 -46
  203. adam/commands/describe/describe_keyspace.py +0 -60
  204. adam/commands/describe/describe_keyspaces.py +0 -50
  205. adam/commands/describe/describe_table.py +0 -60
  206. adam/commands/describe/describe_tables.py +0 -50
  207. adam/commands/devices.py +0 -89
  208. adam/commands/postgres/postgres_session.py +0 -240
  209. adam/commands/postgres/postgres_utils.py +0 -31
  210. adam/commands/postgres/psql_table_completer.py +0 -11
  211. adam/commands/reaper/reaper_session.py +0 -159
  212. adam/commands/show/show_app_actions.py +0 -53
  213. adam/commands/show/show_repairs.py +0 -47
  214. adam/k8s_utils/cassandra_clusters.py +0 -35
  215. adam/sql/sql_utils.py +0 -5
  216. kaqing-2.0.52.dist-info/RECORD +0 -184
  217. /adam/commands/{describe → app}/__init__.py +0 -0
  218. /adam/{k8s_utils → commands/audit}/__init__.py +0 -0
  219. /adam/{k8s_utils → utils_k8s}/config_maps.py +0 -0
  220. /adam/{k8s_utils → utils_k8s}/volumes.py +0 -0
  221. {kaqing-2.0.52.dist-info → kaqing-2.0.184.dist-info}/WHEEL +0 -0
  222. {kaqing-2.0.52.dist-info → kaqing-2.0.184.dist-info}/entry_points.txt +0 -0
  223. {kaqing-2.0.52.dist-info → kaqing-2.0.184.dist-info}/top_level.txt +0 -0
adam/log.py CHANGED
@@ -4,6 +4,8 @@ import os
4
4
  import sys
5
5
  import click
6
6
 
7
+ from adam.utils import log_exc
8
+
7
9
  class Log:
8
10
  DEBUG = False
9
11
 
@@ -28,7 +30,7 @@ class Log:
28
30
  print(file=sys.stderr)
29
31
 
30
32
  def log_to_file(config: dict[any, any]):
31
- try:
33
+ with log_exc():
32
34
  base = f"/tmp/logs"
33
35
  os.makedirs(base, exist_ok=True)
34
36
 
@@ -42,6 +44,4 @@ class Log:
42
44
  except:
43
45
  f.write(config)
44
46
  else:
45
- f.write(config)
46
- except:
47
- pass
47
+ f.write(config)
adam/pod_exec_result.py CHANGED
@@ -1,5 +1,7 @@
1
1
  import yaml
2
2
 
3
+ from adam.utils import log_exc
4
+
3
5
  class PodExecResult:
4
6
  # {
5
7
  # 'metadata': {},
@@ -15,19 +17,25 @@ class PodExecResult:
15
17
  # ]
16
18
  # }
17
19
  # }
18
- def __init__(self, stdout: str, stderr: str, command: str = None, error_output: str = None):
20
+ def __init__(self, stdout: str, stderr: str, command: str = None, error_output: str = None, pod: str = None, log_file: str = None):
19
21
  self.stdout: str = stdout
20
22
  self.stderr: str = stderr
21
23
  self.command: str = command
22
24
  if error_output:
23
25
  self.error = yaml.safe_load(error_output)
26
+ self.pod = pod
27
+ self.log_file = log_file
24
28
 
25
29
  def exit_code(self) -> int:
26
30
  code = 0
27
31
 
28
- try:
32
+ with log_exc(False):
29
33
  code = self.error['details']['causes'][0]['message']
30
- except:
31
- pass
32
34
 
33
- return code
35
+ return code
36
+
37
+ def __str__(self):
38
+ return f'{"OK" if self.exit_code() == 0 else self.exit_code()} {self.command}'
39
+
40
+ def __audit_extra__(self):
41
+ return self.log_file if self.log_file else None
adam/repl.py CHANGED
@@ -1,25 +1,24 @@
1
1
  import os
2
- import re
3
2
  import time
4
- import traceback
3
+ from typing import cast
5
4
  import click
6
- from prompt_toolkit.completion import NestedCompleter
7
5
  from prompt_toolkit.key_binding import KeyBindings
8
6
 
9
7
  from adam.cli_group import cli
10
- from adam.commands.command import Command
8
+ from adam.commands.command import Command, InvalidArgumentsException, InvalidStateException
11
9
  from adam.commands.command_helpers import ClusterCommandHelper
10
+ from adam.commands.devices.devices import Devices
12
11
  from adam.commands.help import Help
13
- from adam.commands.postgres.postgres_session import PostgresSession
14
12
  from adam.config import Config
15
- from adam.k8s_utils.kube_context import KubeContext
16
- from adam.k8s_utils.statefulsets import StatefulSets
13
+ from adam.utils_audits import Audits
14
+ from adam.utils_k8s.kube_context import KubeContext
17
15
  from adam.log import Log
18
16
  from adam.repl_commands import ReplCommands
19
17
  from adam.repl_session import ReplSession
20
18
  from adam.repl_state import ReplState
21
- from adam.utils import deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2
19
+ from adam.utils import clear_wait_log_flag, debug_trace, deep_merge_dicts, deep_sort_dict, tabulize, log2, log_exc, log_timing
22
20
  from adam.apps import Apps
21
+ from adam.utils_repl.repl_completer import ReplCompleter
23
22
  from . import __version__
24
23
 
25
24
  def enter_repl(state: ReplState):
@@ -33,54 +32,13 @@ def enter_repl(state: ReplState):
33
32
  session = ReplSession().prompt_session
34
33
 
35
34
  def prompt_msg():
36
- msg = ''
37
- if state.device == ReplState.P:
38
- msg = f'{ReplState.P}:'
39
- pg = PostgresSession(state.namespace, state.pg_path) if state.pg_path else None
40
- if pg and pg.db:
41
- msg += pg.db
42
- elif pg and pg.host:
43
- msg += pg.host
44
- elif state.device == ReplState.A:
45
- msg = f'{ReplState.A}:'
46
- if state.app_env:
47
- msg += state.app_env
48
- if state.app_app:
49
- msg += f'/{state.app_app}'
50
- else:
51
- msg = f'{ReplState.C}:'
52
- if state.pod:
53
- # cs-d0767a536f-cs-d0767a536f-default-sts-0
54
- group = re.match(r".*?-.*?-(.*)", state.pod)
55
- msg += group[1]
56
- elif state.sts:
57
- # cs-d0767a536f-cs-d0767a536f-default-sts
58
- group = re.match(r".*?-.*?-(.*)", state.sts)
59
- msg += group[1]
35
+ msg = state.__str__()
60
36
 
61
37
  return f"{msg}$ " if state.bash_session else f"{msg}> "
62
38
 
63
39
  Log.log2(f'kaqing {__version__}')
64
- ss = StatefulSets.list_sts_name_and_ns()
65
-
66
- if state.device == ReplState.C:
67
- if not ss:
68
- raise Exception("no Cassandra clusters found")
69
- elif len(ss) == 1 and Config().get('repl.auto-enter-only-cluster', True):
70
- cluster = ss[0]
71
- state.sts = cluster[0]
72
- state.namespace = cluster[1]
73
- Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}@{state.namespace}...')
74
- elif state.device == ReplState.A:
75
- if app := Config().get('repl.auto-enter-app', 'c3/c3'):
76
- if app != 'no':
77
- ea = app.split('/')
78
- state.app_env = ea[0]
79
- if len(ea) > 1:
80
- state.app_app = ea[1]
81
- Config().wait_log(f'Moving to {state.app_env}/{state.app_app}...')
82
- else:
83
- Config().wait_log(f'Moving to {state.app_env}...')
40
+
41
+ Devices.device(state).enter(state)
84
42
 
85
43
  kb = KeyBindings()
86
44
 
@@ -88,73 +46,122 @@ def enter_repl(state: ReplState):
88
46
  def _(event):
89
47
  event.app.current_buffer.text = ''
90
48
 
91
- # use sorted command list only for auto-completion
92
- sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
93
- while True:
94
- try:
95
- completer = NestedCompleter.from_nested_dict({})
96
- if not state.bash_session:
97
- completions = {}
98
- # app commands are available only on a: drive
99
- if state.device == ReplState.A and state.app_app:
100
- completions = Apps(path='apps.yaml').commands()
101
-
102
- for cmd in sorted_cmds:
103
- s1 = time.time()
104
- try:
105
- completions = deep_sort_dict(deep_merge_dicts(completions, cmd.completion(state)))
106
- finally:
107
- if Config().get('debugs.timings', False):
108
- log2(f'Timing auto-completion-calc {cmd.command()}: {time.time() - s1:.2f}')
109
-
110
- # print(json.dumps(completions, indent=4))
111
- completer = NestedCompleter.from_nested_dict(completions)
112
-
113
- cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
114
- s0 = time.time()
115
-
116
- if state.bash_session:
117
- if cmd.strip(' ') == 'exit':
118
- state.exit_bash()
119
- continue
120
-
121
- cmd = f'bash {cmd}'
122
-
123
- if cmd and cmd.strip(' ') and not cmds.run(cmd, state):
124
- c_sql_tried = False
125
- if state.device == ReplState.P:
126
- pg = PostgresSession(state.namespace, state.pg_path)
127
- if pg.db:
128
- c_sql_tried = True
129
- cmd = f'pg {cmd}'
130
- cmds.run(cmd, state)
131
- elif state.device == ReplState.A:
132
- if state.app_app:
133
- c_sql_tried = True
134
- cmd = f'app {cmd}'
135
- cmds.run(cmd, state)
136
- elif state.sts:
137
- c_sql_tried = True
138
- cmd = f'cql {cmd}'
139
- cmds.run(cmd, state)
140
-
141
- if not c_sql_tried:
142
- log2(f'* Invalid command: {cmd}')
143
- log2()
144
- lines = [c.help(state) for c in cmd_list if c.help(state)]
145
- log2(lines_to_tabular(lines, separator='\t'))
146
- except EOFError: # Handle Ctrl+D (EOF) for graceful exit
147
- break
148
- except Exception as e:
149
- if Config().get('debugs.exit-on-error', False):
150
- raise e
151
- else:
152
- log2(e)
153
- Config().debug(traceback.format_exc())
154
- finally:
155
- Config().clear_wait_log_flag()
156
- if Config().get('debugs.timings', False) and 'cmd' in locals() and 's0' in locals():
157
- log2(f'Timing command {cmd}: {time.time() - s0:.2f}')
49
+ with Audits.offload() as exec:
50
+ # warm up AWS lambda - this log line may timeout and get lost, which is fine
51
+ exec.submit(Audits.log, 'entering kaqing repl', state.namespace, 'z', 0.0)
52
+
53
+ s0 = time.time()
54
+
55
+ # use sorted command list only for auto-completion
56
+ sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
57
+ while True:
58
+ cmd: str = None
59
+ result = None
60
+ try:
61
+ completer = ReplCompleter.from_nested_dict({})
62
+ if not state.bash_session:
63
+ with log_timing('completion-calcs'):
64
+ completions = {}
65
+ # app commands are available only on a: drive
66
+ if state.device == ReplState.A and state.app_app:
67
+ completions = log_timing('actions', lambda: Apps(path='apps.yaml').commands())
68
+
69
+ for c in sorted_cmds:
70
+ with log_exc(f'* {c.command()} command returned None completions.'):
71
+ completions = log_timing(c.command(), lambda: deep_sort_dict(deep_merge_dicts(completions, c.completion(state))))
72
+
73
+ # print(json.dumps(completions, indent=4))
74
+ completer = ReplCompleter.from_nested_dict(completions)
75
+
76
+ cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
77
+ s0 = time.time()
78
+
79
+ if state.bash_session:
80
+ if cmd.strip(' ') == 'exit':
81
+ state.exit_bash()
82
+ continue
83
+
84
+ cmd = f'bash {cmd}'
85
+
86
+ def targetted(state: ReplState, cmd: str):
87
+ if not (cmd.startswith('@') and len(arry := cmd.split(' ')) > 1):
88
+ return state, cmd
89
+
90
+ if state.device == ReplState.A and state.app_app or state.device == ReplState.P:
91
+ state.push()
92
+
93
+ state.app_pod = arry[0].strip('@')
94
+ cmd = ' '.join(arry[1:])
95
+ elif state.device == ReplState.P:
96
+ state.push()
97
+
98
+ state.app_pod = arry[0].strip('@')
99
+ cmd = ' '.join(arry[1:])
100
+ elif state.sts:
101
+ state.push()
102
+
103
+ state.pod = arry[0].strip('@')
104
+ cmd = ' '.join(arry[1:])
105
+
106
+ return (state, cmd)
107
+
108
+ target, cmd = targetted(state, cmd)
109
+ try:
110
+ if cmd and cmd.strip(' ') and not (result := cmds.run(cmd, target)):
111
+ result = try_device_default_action(target, cmds, cmd_list, cmd)
112
+ except InvalidStateException:
113
+ pass
114
+ except InvalidArgumentsException:
115
+ pass
116
+
117
+ if result and type(result) is ReplState and (s := cast(ReplState, result).export_session) != state.export_session:
118
+ state.export_session = s
119
+
120
+ except EOFError: # Handle Ctrl+D (EOF) for graceful exit
121
+ break
122
+ except Exception as e:
123
+ if Config().get('debugs.exit-on-error', False):
124
+ raise e
125
+ else:
126
+ log2(e)
127
+ debug_trace()
128
+ finally:
129
+ if not state.bash_session:
130
+ state.pop()
131
+
132
+ clear_wait_log_flag()
133
+ if cmd:
134
+ log_timing(f'command {cmd}', s0=s0)
135
+
136
+ # offload audit logging
137
+ if cmd and (state.device != ReplState.L or Config().get('audit.log-audit-queries', False)):
138
+ exec.submit(Audits.log, cmd, state.namespace, state.device, time.time() - s0, get_audit_extra(result))
139
+
140
+ def try_device_default_action(state: ReplState, cmds: Command, cmd_list: list[Command], cmd: str):
141
+ action_taken, result = Devices.device(state).try_fallback_action(cmds, state, cmd)
142
+
143
+ if not action_taken:
144
+ log2(f'* Invalid command: {cmd}')
145
+ log2()
146
+ tabulize([c.help(state) for c in cmd_list if c.help(state)], separator='\t', to=2)
147
+
148
+ return result
149
+
150
+ def get_audit_extra(result: any):
151
+ if not result:
152
+ return None
153
+
154
+ if type(result) is list:
155
+ extras = set()
156
+
157
+ for r in result:
158
+ if hasattr(r, '__audit_extra__') and (x := r.__audit_extra__()):
159
+ extras.add(x)
160
+
161
+ return ','.join(list(extras))
162
+
163
+ if hasattr(result, '__audit_extra__') and (x := result.__audit_extra__()):
164
+ return x
158
165
 
159
166
  @cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=ClusterCommandHelper, help="Enter interactive shell.")
160
167
  @click.option('--kubeconfig', '-k', required=False, metavar='path', help='path to kubeconfig file')
adam/repl_commands.py CHANGED
@@ -1,6 +1,13 @@
1
1
  from adam.commands.alter_tables import AlterTables
2
- from adam.commands.app import App
3
- from adam.commands.app_ping import AppPing
2
+ from adam.commands.app.app import App
3
+ from adam.commands.app.app_ping import AppPing
4
+ from adam.commands.app.show_app_actions import ShowAppActions
5
+ from adam.commands.app.show_app_id import ShowAppId
6
+ from adam.commands.app.show_app_queues import ShowAppQueues
7
+ from adam.commands.audit.audit import Audit
8
+ from adam.commands.cat import Cat
9
+ from adam.commands.code import Code
10
+ from adam.commands.download_file import DownloadFile
4
11
  from adam.commands.deploy.code_start import CodeStart
5
12
  from adam.commands.deploy.code_stop import CodeStop
6
13
  from adam.commands.deploy.deploy import Deploy
@@ -11,27 +18,44 @@ from adam.commands.deploy.undeploy import Undeploy
11
18
  from adam.commands.deploy.undeploy_frontend import UndeployFrontend
12
19
  from adam.commands.deploy.undeploy_pg_agent import UndeployPgAgent
13
20
  from adam.commands.deploy.undeploy_pod import UndeployPod
14
- from adam.commands.describe.describe import Describe
15
- from adam.commands.describe.describe_keyspace import DescribeKeyspace
16
- from adam.commands.describe.describe_keyspaces import DescribeKeyspaces
17
- from adam.commands.describe.describe_table import DescribeTable
18
- from adam.commands.describe.describe_tables import DescribeTables
21
+ from adam.commands.devices.device_app import DeviceApp
22
+ from adam.commands.devices.device_auit_log import DeviceAuditLog
23
+ from adam.commands.devices.device_cass import DeviceCass
24
+ from adam.commands.devices.device_export import DeviceExport
25
+ from adam.commands.devices.device_postgres import DevicePostgres
26
+ from adam.commands.export.download_export_session import DownloadExportSession
27
+ from adam.commands.export.drop_export_database import DropExportDatabase
28
+ from adam.commands.export.export import ExportTables
29
+ from adam.commands.export.import_files import ImportCSVFiles
30
+ from adam.commands.export.import_session import ImportSession
31
+ from adam.commands.export.clean_up_export_sessions import CleanUpExportSessions
32
+ from adam.commands.export.clean_up_all_export_sessions import CleanUpAllExportSessions
33
+ from adam.commands.export.drop_export_databases import DropExportDatabases
34
+ from adam.commands.export.export_select import ExportSelect
35
+ from adam.commands.export.export_use import ExportUse
36
+ from adam.commands.export.export_select_x import ExportSelectX
37
+ from adam.commands.export.show_column_counts import ShowColumnCounts
38
+ from adam.commands.export.show_export_databases import ShowExportDatabases
39
+ from adam.commands.export.show_export_session import ShowExportSession
40
+ from adam.commands.export.show_export_sessions import ShowExportSessions
41
+ from adam.commands.find_files import FindLocalFiles
42
+ from adam.commands.find_processes import FindProcesses
43
+ from adam.commands.head import Head
44
+ from adam.commands.kubectl import Kubectl
19
45
  from adam.commands.shell import Shell
20
- from adam.commands.show.show_app_queues import ShowAppQueues
21
- from adam.commands.cp import ClipboardCopy
22
- from adam.commands.bash import Bash
46
+ from adam.commands.clipboard_copy import ClipboardCopy
47
+ from adam.commands.bash.bash import Bash
23
48
  from adam.commands.cd import Cd
24
49
  from adam.commands.check import Check
25
50
  from adam.commands.command import Command
26
51
  from adam.commands.cql.cqlsh import Cqlsh
27
- from adam.commands.devices import DeviceApp, DeviceCass, DevicePostgres
28
52
  from adam.commands.exit import Exit
29
53
  from adam.commands.medusa.medusa import Medusa
30
54
  from adam.commands.param_get import GetParam
31
55
  from adam.commands.issues import Issues
32
56
  from adam.commands.ls import Ls
33
57
  from adam.commands.nodetool import NodeTool
34
- from adam.commands.postgres.postgres import Postgres
58
+ from adam.commands.postgres.postgres import Postgres, PostgresPg
35
59
  from adam.commands.preview_table import PreviewTable
36
60
  from adam.commands.pwd import Pwd
37
61
  from adam.commands.reaper.reaper import Reaper
@@ -41,25 +65,24 @@ from adam.commands.restart import Restart
41
65
  from adam.commands.rollout import RollOut
42
66
  from adam.commands.param_set import SetParam
43
67
  from adam.commands.show.show import Show
44
- from adam.commands.show.show_app_actions import ShowAppActions
45
- from adam.commands.show.show_app_id import ShowAppId
46
68
  from adam.commands.show.show_cassandra_status import ShowCassandraStatus
47
69
  from adam.commands.show.show_cassandra_version import ShowCassandraVersion
48
70
  from adam.commands.show.show_commands import ShowKubectlCommands
71
+ from adam.commands.show.show_host import ShowHost
49
72
  from adam.commands.show.show_login import ShowLogin
50
73
  from adam.commands.show.show_params import ShowParams
51
74
  from adam.commands.show.show_processes import ShowProcesses
52
- from adam.commands.show.show_repairs import ShowRepairs
75
+ from adam.commands.show.show_cassandra_repairs import ShowCassandraRepairs
53
76
  from adam.commands.show.show_storage import ShowStorage
54
77
  from adam.commands.show.show_adam import ShowAdam
55
78
  from adam.commands.watch import Watch
56
79
 
57
80
  class ReplCommands:
58
81
  def repl_cmd_list() -> list[Command]:
59
- cmds: list[Command] = ReplCommands.navigation() + ReplCommands.cassandra_check() + ReplCommands.cassandra_ops() + \
60
- ReplCommands.tools() + ReplCommands.app() + ReplCommands.exit()
82
+ cmds: list[Command] = ReplCommands.navigation() + ReplCommands.cassandra_ops() + ReplCommands.postgres_ops() + \
83
+ ReplCommands.app_ops() + ReplCommands.audit_ops() + ReplCommands.export_ops() + ReplCommands.tools() + ReplCommands.exit()
61
84
 
62
- intermediate_cmds: list[Command] = [App(), Reaper(), Repair(), Deploy(), Describe(), Show(), Undeploy()]
85
+ intermediate_cmds: list[Command] = [App(), Audit(), Reaper(), Repair(), Deploy(), Show(), Undeploy()]
63
86
  ic = [c.command() for c in intermediate_cmds]
64
87
  # 1. dedup commands
65
88
  deduped = []
@@ -76,22 +99,33 @@ class ReplCommands:
76
99
  return deduped
77
100
 
78
101
  def navigation() -> list[Command]:
79
- return [Ls(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), Cd(), Pwd(), ClipboardCopy(),
80
- GetParam(), SetParam(), ShowParams(), ShowKubectlCommands(), ShowLogin(), ShowAdam()]
81
-
82
- def cassandra_check() -> list[Command]:
83
- return Describe.cmd_list() + [ShowCassandraStatus(),
84
- ShowCassandraVersion(), ShowRepairs(), ShowStorage(), ShowProcesses(), Check(), Issues(), NodeTool(), Report()]
102
+ return [Ls(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), DeviceAuditLog(), DeviceExport(),
103
+ Cd(), Cat(), Head(), DownloadFile(), FindLocalFiles(), FindProcesses(), Pwd(), ClipboardCopy(),
104
+ GetParam(), SetParam(), ShowParams(), ShowKubectlCommands(), ShowLogin(), ShowAdam(), ShowHost()]
85
105
 
86
106
  def cassandra_ops() -> list[Command]:
87
- return [AlterTables()] + Medusa.cmd_list() + [Restart(), RollOut(), Watch()] + Reaper.cmd_list() + Repair.cmd_list()
107
+ return [Cqlsh(), ShowCassandraStatus(), ShowCassandraVersion(), ShowCassandraRepairs(), ShowStorage(), ShowProcesses(),
108
+ Check(), Issues(), NodeTool(), Report(), AlterTables(), Bash(),
109
+ ExportTables(), ExportSelect(), ExportUse(), ShowExportDatabases(), ShowColumnCounts(),
110
+ DropExportDatabase(), DropExportDatabases(),
111
+ ShowExportSessions(), ShowExportSession(), DownloadExportSession(),
112
+ CleanUpExportSessions(), CleanUpAllExportSessions(), ImportSession(), ImportCSVFiles()] + \
113
+ Medusa().cmd_list() + [Restart(), RollOut(), Watch()] + Reaper().cmd_list() + Repair().cmd_list()
88
114
 
89
- def tools() -> list[Command]:
90
- return [Cqlsh(), Postgres(), Bash(), Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(),
91
- DeployPod(), UndeployPod(), DeployPgAgent(), UndeployPgAgent()]
115
+ def postgres_ops() -> list[Command]:
116
+ return [Postgres(), DeployPgAgent(), UndeployPgAgent(), PostgresPg()]
92
117
 
93
- def app() -> list[Command]:
118
+ def app_ops() -> list[Command]:
94
119
  return [ShowAppActions(), ShowAppId(), ShowAppQueues(), AppPing(), App()]
95
120
 
121
+ def audit_ops() -> list[Command]:
122
+ return [Audit()] + Audit().cmd_list()
123
+
124
+ def export_ops() -> list[Command]:
125
+ return [ExportSelectX(), DropExportDatabase(), DropExportDatabases(), ShowColumnCounts()]
126
+
127
+ def tools() -> list[Command]:
128
+ return [Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(), DeployPod(), UndeployPod(), Kubectl(), Code()]
129
+
96
130
  def exit() -> list[Command]:
97
131
  return [Exit()]