kaqing 2.0.93__py3-none-any.whl → 2.0.115__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 (134) hide show
  1. adam/apps.py +2 -2
  2. adam/batch.py +2 -16
  3. adam/checks/check_utils.py +4 -4
  4. adam/checks/compactionstats.py +1 -1
  5. adam/checks/cpu.py +2 -2
  6. adam/checks/disk.py +1 -1
  7. adam/checks/gossip.py +1 -1
  8. adam/checks/memory.py +3 -3
  9. adam/checks/status.py +1 -1
  10. adam/commands/alter_tables.py +3 -14
  11. adam/commands/app.py +3 -3
  12. adam/commands/app_ping.py +2 -2
  13. adam/commands/audit/audit.py +26 -11
  14. adam/commands/audit/audit_repair_tables.py +39 -4
  15. adam/commands/audit/audit_run.py +58 -0
  16. adam/commands/audit/show_last10.py +51 -0
  17. adam/commands/audit/show_slow10.py +50 -0
  18. adam/commands/audit/show_top10.py +49 -0
  19. adam/commands/audit/utils_show_top10.py +59 -0
  20. adam/commands/bash/bash.py +124 -0
  21. adam/commands/bash/bash_completer.py +93 -0
  22. adam/commands/cat.py +55 -0
  23. adam/commands/cd.py +26 -14
  24. adam/commands/check.py +6 -0
  25. adam/commands/cli_commands.py +3 -3
  26. adam/commands/code.py +60 -0
  27. adam/commands/command.py +9 -4
  28. adam/commands/commands_utils.py +4 -5
  29. adam/commands/cql/cql_completions.py +7 -3
  30. adam/commands/cql/cql_utils.py +103 -11
  31. adam/commands/cql/cqlsh.py +10 -5
  32. adam/commands/deploy/code_utils.py +2 -2
  33. adam/commands/deploy/deploy.py +7 -1
  34. adam/commands/deploy/deploy_pg_agent.py +2 -2
  35. adam/commands/deploy/deploy_pod.py +6 -6
  36. adam/commands/deploy/deploy_utils.py +2 -2
  37. adam/commands/deploy/undeploy.py +7 -1
  38. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  39. adam/commands/deploy/undeploy_pod.py +4 -4
  40. adam/commands/devices.py +29 -0
  41. adam/commands/export/export.py +60 -0
  42. adam/commands/export/export_on_x.py +76 -0
  43. adam/commands/export/export_rmdbs.py +65 -0
  44. adam/commands/export/export_select.py +68 -0
  45. adam/commands/export/export_use.py +56 -0
  46. adam/commands/export/utils_export.py +253 -0
  47. adam/commands/help.py +9 -5
  48. adam/commands/issues.py +6 -0
  49. adam/commands/kubectl.py +41 -0
  50. adam/commands/login.py +6 -3
  51. adam/commands/logs.py +2 -1
  52. adam/commands/ls.py +43 -31
  53. adam/commands/medusa/medusa_backup.py +2 -2
  54. adam/commands/medusa/medusa_restore.py +2 -2
  55. adam/commands/medusa/medusa_show_backupjobs.py +3 -2
  56. adam/commands/medusa/medusa_show_restorejobs.py +2 -2
  57. adam/commands/nodetool.py +11 -16
  58. adam/commands/postgres/postgres.py +4 -4
  59. adam/commands/postgres/{postgres_session.py → postgres_context.py} +29 -30
  60. adam/commands/postgres/postgres_utils.py +5 -5
  61. adam/commands/postgres/psql_completions.py +1 -1
  62. adam/commands/preview_table.py +18 -32
  63. adam/commands/pwd.py +4 -3
  64. adam/commands/reaper/reaper.py +3 -0
  65. adam/commands/reaper/reaper_restart.py +1 -1
  66. adam/commands/reaper/reaper_session.py +1 -1
  67. adam/commands/repair/repair.py +3 -3
  68. adam/commands/repair/repair_log.py +1 -1
  69. adam/commands/repair/repair_run.py +2 -2
  70. adam/commands/repair/repair_scan.py +1 -1
  71. adam/commands/repair/repair_stop.py +1 -1
  72. adam/commands/report.py +6 -0
  73. adam/commands/restart.py +2 -2
  74. adam/commands/rollout.py +1 -1
  75. adam/commands/show/show.py +3 -1
  76. adam/commands/show/show_app_actions.py +3 -0
  77. adam/commands/show/show_app_id.py +1 -1
  78. adam/commands/show/show_app_queues.py +3 -2
  79. adam/commands/show/show_cassandra_status.py +3 -3
  80. adam/commands/show/show_cassandra_version.py +3 -3
  81. adam/commands/show/show_login.py +3 -0
  82. adam/commands/show/show_processes.py +1 -1
  83. adam/commands/show/show_repairs.py +2 -2
  84. adam/commands/show/show_storage.py +1 -1
  85. adam/commands/watch.py +1 -1
  86. adam/config.py +2 -1
  87. adam/embedded_params.py +1 -1
  88. adam/pod_exec_result.py +7 -1
  89. adam/repl.py +125 -99
  90. adam/repl_commands.py +29 -17
  91. adam/repl_state.py +229 -49
  92. adam/sql/sql_completer.py +86 -62
  93. adam/sql/sql_state_machine.py +563 -0
  94. adam/sql/term_completer.py +3 -0
  95. adam/sso/cred_cache.py +1 -1
  96. adam/sso/idp.py +1 -1
  97. adam/utils_athena.py +108 -74
  98. adam/utils_audits.py +104 -0
  99. adam/utils_export.py +42 -0
  100. adam/utils_k8s/__init__.py +0 -0
  101. adam/utils_k8s/app_clusters.py +33 -0
  102. adam/utils_k8s/app_pods.py +31 -0
  103. adam/{k8s_utils → utils_k8s}/cassandra_clusters.py +5 -6
  104. adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +11 -4
  105. adam/{k8s_utils → utils_k8s}/deployment.py +2 -2
  106. adam/{k8s_utils → utils_k8s}/pods.py +54 -11
  107. adam/{k8s_utils → utils_k8s}/statefulsets.py +2 -2
  108. adam/version.py +1 -1
  109. {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/METADATA +1 -1
  110. kaqing-2.0.115.dist-info/RECORD +203 -0
  111. adam/commands/bash.py +0 -91
  112. adam/commands/cql/cql_table_completer.py +0 -8
  113. adam/commands/describe/describe.py +0 -46
  114. adam/commands/describe/describe_keyspace.py +0 -60
  115. adam/commands/describe/describe_keyspaces.py +0 -50
  116. adam/commands/describe/describe_table.py +0 -60
  117. adam/commands/describe/describe_tables.py +0 -50
  118. adam/commands/postgres/psql_table_completer.py +0 -11
  119. adam/sql/state_machine.py +0 -460
  120. kaqing-2.0.93.dist-info/RECORD +0 -190
  121. /adam/commands/{describe → bash}/__init__.py +0 -0
  122. /adam/{k8s_utils → commands/export}/__init__.py +0 -0
  123. /adam/{k8s_utils → utils_k8s}/config_maps.py +0 -0
  124. /adam/{k8s_utils → utils_k8s}/custom_resources.py +0 -0
  125. /adam/{k8s_utils → utils_k8s}/ingresses.py +0 -0
  126. /adam/{k8s_utils → utils_k8s}/jobs.py +0 -0
  127. /adam/{k8s_utils → utils_k8s}/kube_context.py +0 -0
  128. /adam/{k8s_utils → utils_k8s}/secrets.py +0 -0
  129. /adam/{k8s_utils → utils_k8s}/service_accounts.py +0 -0
  130. /adam/{k8s_utils → utils_k8s}/services.py +0 -0
  131. /adam/{k8s_utils → utils_k8s}/volumes.py +0 -0
  132. {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/WHEEL +0 -0
  133. {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/entry_points.txt +0 -0
  134. {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/top_level.txt +0 -0
adam/repl.py CHANGED
@@ -1,29 +1,30 @@
1
- import getpass
1
+ from copy import copy
2
2
  import os
3
3
  import re
4
4
  import time
5
5
  import traceback
6
+ from typing import cast
6
7
  import click
7
8
  import concurrent
8
- from prompt_toolkit.completion import NestedCompleter
9
9
  from prompt_toolkit.key_binding import KeyBindings
10
- import requests
11
10
 
12
11
  from adam.cli_group import cli
13
12
  from adam.commands.command import Command
14
13
  from adam.commands.command_helpers import ClusterCommandHelper
15
14
  from adam.commands.help import Help
16
- from adam.commands.postgres.postgres_session import PostgresSession
15
+ from adam.commands.postgres.postgres_context import PostgresContext
17
16
  from adam.config import Config
18
- from adam.k8s_utils.kube_context import KubeContext
19
- from adam.k8s_utils.statefulsets import StatefulSets
17
+ from adam.utils_audits import Audits
18
+ from adam.utils_k8s.app_pods import AppPods
19
+ from adam.utils_k8s.kube_context import KubeContext
20
+ from adam.utils_k8s.statefulsets import StatefulSets
20
21
  from adam.log import Log
21
22
  from adam.repl_commands import ReplCommands
22
23
  from adam.repl_session import ReplSession
23
24
  from adam.repl_state import ReplState
24
25
  from adam.utils import deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2
25
26
  from adam.apps import Apps
26
- from adam.utils_net import get_my_host
27
+ from adam.utils_repl.repl_completer import ReplCompleter
27
28
  from . import __version__
28
29
 
29
30
  def enter_repl(state: ReplState):
@@ -37,63 +38,52 @@ def enter_repl(state: ReplState):
37
38
  session = ReplSession().prompt_session
38
39
 
39
40
  def prompt_msg():
40
- msg = ''
41
- if state.device == ReplState.P:
42
- msg = f'{ReplState.P}:'
43
- pg = PostgresSession(state.namespace, state.pg_path) if state.pg_path else None
44
- if pg and pg.db:
45
- msg += pg.db
46
- elif pg and pg.host:
47
- msg += pg.host
48
- elif state.device == ReplState.A:
49
- msg = f'{ReplState.A}:'
50
- if state.app_env:
51
- msg += state.app_env
52
- if state.app_app:
53
- msg += f'/{state.app_app}'
54
- elif state.device == ReplState.L:
55
- msg = f'{ReplState.L}:'
56
- else:
57
- msg = f'{ReplState.C}:'
58
- if state.pod:
59
- # cs-d0767a536f-cs-d0767a536f-default-sts-0
60
- group = re.match(r".*?-.*?-(.*)", state.pod)
61
- msg += group[1]
62
- elif state.sts:
63
- # cs-d0767a536f-cs-d0767a536f-default-sts
64
- group = re.match(r".*?-.*?-(.*)", state.sts)
65
- msg += group[1]
41
+ msg = state.__str__()
66
42
 
67
43
  return f"{msg}$ " if state.bash_session else f"{msg}> "
68
44
 
69
45
  Log.log2(f'kaqing {__version__}')
70
46
 
71
47
  if state.device == ReplState.C:
72
- auto_enter = Config().get('repl.auto-enter-only-cluster', 'cluster')
73
- ss = StatefulSets.list_sts_name_and_ns()
74
- if not ss:
75
- raise Exception("no Cassandra clusters found")
76
- elif not state.sts and len(ss) == 1 and auto_enter in ['cluster', 'first-pod']:
77
- cluster = ss[0]
78
- state.sts = cluster[0]
79
- state.namespace = cluster[1]
80
- if auto_enter == 'first-pod':
81
- state.pod = f'{state.sts}-0'
82
- if KubeContext().in_cluster_namespace:
83
- Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}...')
84
- else:
85
- Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}@{state.namespace}...')
48
+ auto_enter = Config().get('repl.c.auto-enter', 'cluster')
49
+ if auto_enter and auto_enter in ['cluster', 'first-pod']:
50
+ ss = StatefulSets.list_sts_name_and_ns()
51
+ if not ss:
52
+ log2("No Cassandra clusters found.")
53
+ elif not state.sts and len(ss) == 1:
54
+ cluster = ss[0]
55
+ state.sts = cluster[0]
56
+ state.namespace = cluster[1]
57
+ if auto_enter == 'first-pod':
58
+ state.pod = f'{state.sts}-0'
59
+ if KubeContext().in_cluster_namespace:
60
+ Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}...')
61
+ else:
62
+ Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}@{state.namespace}...')
86
63
  elif state.device == ReplState.A:
87
64
  if not state.app_env:
88
- if app := Config().get('repl.auto-enter-app', 'c3/c3'):
89
- if app != 'no':
90
- ea = app.split('/')
65
+ if auto_enter := Config().get('repl.a.auto-enter-app', 'c3/c3/*'):
66
+ if auto_enter != 'no':
67
+ ea = auto_enter.split('/')
91
68
  state.app_env = ea[0]
92
- if len(ea) > 1:
69
+ if len(ea) > 2:
70
+ state.app_app = ea[1]
71
+ state.app_pod = ea[2]
72
+ if state.app_pod == '*':
73
+ if (pods := AppPods.pod_names(state.namespace, ea[0], ea[1])):
74
+ state.app_pod = pods[0]
75
+ Config().wait_log(f'Moving to {state.app_env}/{state.app_app}/{state.app_pod}...')
76
+ else:
77
+ Config().wait_log(f'No pods found, moving to {state.app_env}/{state.app_app}...')
78
+ else:
79
+ Config().wait_log(f'Moving to {state.app_env}/{state.app_app}/{state.app_pod}...')
80
+ elif len(ea) > 1:
93
81
  state.app_app = ea[1]
94
82
  Config().wait_log(f'Moving to {state.app_env}/{state.app_app}...')
95
83
  else:
96
84
  Config().wait_log(f'Moving to {state.app_env}...')
85
+ elif state.device == ReplState.P:
86
+ Config().wait_log('Inspecting postgres database instances...')
97
87
 
98
88
  kb = KeyBindings()
99
89
 
@@ -103,13 +93,16 @@ def enter_repl(state: ReplState):
103
93
 
104
94
  with concurrent.futures.ThreadPoolExecutor(max_workers=Config().get('audit.workers', 3)) as executor:
105
95
  # warm up AWS lambda - this log line may timeout and get lost, which is fine
106
- executor.submit(audit_log, 'entering kaqing repl', state)
96
+ executor.submit(Audits.log, 'entering kaqing repl', state.namespace, 'z', 0.0)
97
+
98
+ s0 = time.time()
107
99
 
108
100
  # use sorted command list only for auto-completion
109
101
  sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
110
102
  while True:
103
+ result = None
111
104
  try:
112
- completer = NestedCompleter.from_nested_dict({})
105
+ completer = ReplCompleter.from_nested_dict({})
113
106
  if not state.bash_session:
114
107
  completions = {}
115
108
  # app commands are available only on a: drive
@@ -125,7 +118,7 @@ def enter_repl(state: ReplState):
125
118
  log2(f'Timing auto-completion-calc {cmd.command()}: {time.time() - s1:.2f}')
126
119
 
127
120
  # print(json.dumps(completions, indent=4))
128
- completer = NestedCompleter.from_nested_dict(completions)
121
+ completer = ReplCompleter.from_nested_dict(completions)
129
122
 
130
123
  cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
131
124
  s0 = time.time()
@@ -137,33 +130,29 @@ def enter_repl(state: ReplState):
137
130
 
138
131
  cmd = f'bash {cmd}'
139
132
 
140
- if cmd and cmd.strip(' ') and not cmds.run(cmd, state):
141
- c_sql_tried = False
142
- if state.device == ReplState.P:
143
- pg = PostgresSession(state.namespace, state.pg_path)
144
- if pg.db:
145
- c_sql_tried = True
146
- cmd = f'pg {cmd}'
147
- cmds.run(cmd, state)
148
- elif state.device == ReplState.A:
149
- if state.app_app:
150
- c_sql_tried = True
151
- cmd = f'app {cmd}'
152
- cmds.run(cmd, state)
153
- elif state.device == ReplState.L:
154
- c_sql_tried = True
155
- cmd = f'audit {cmd}'
156
- cmds.run(cmd, state)
133
+ def targetted(state: ReplState, cmd: str):
134
+ if not (cmd.startswith('@') and len(arry := cmd.split(' ')) > 1):
135
+ return state, cmd
136
+
137
+ if state.device == ReplState.A and state.app_app:
138
+ state.push()
139
+
140
+ state.app_pod = arry[0].strip('@')
141
+ cmd = ' '.join(arry[1:])
157
142
  elif state.sts:
158
- c_sql_tried = True
159
- cmd = f'cql {cmd}'
160
- cmds.run(cmd, state)
161
-
162
- if not c_sql_tried:
163
- log2(f'* Invalid command: {cmd}')
164
- log2()
165
- lines = [c.help(state) for c in cmd_list if c.help(state)]
166
- log2(lines_to_tabular(lines, separator='\t'))
143
+ state.push()
144
+
145
+ state.pod = arry[0].strip('@')
146
+ cmd = ' '.join(arry[1:])
147
+
148
+ return (state, cmd)
149
+
150
+ target, cmd = targetted(state, cmd)
151
+ if cmd and cmd.strip(' ') and not (result := cmds.run(cmd, target)):
152
+ result = try_device_default_action(target, cmds, cmd_list, cmd)
153
+
154
+ if result and type(result) is ReplState and (s := cast(ReplState, result).export_session):
155
+ state.export_session = s
167
156
  except EOFError: # Handle Ctrl+D (EOF) for graceful exit
168
157
  break
169
158
  except Exception as e:
@@ -173,31 +162,68 @@ def enter_repl(state: ReplState):
173
162
  log2(e)
174
163
  Config().debug(traceback.format_exc())
175
164
  finally:
165
+ if not state.bash_session:
166
+ state.pop()
167
+
176
168
  Config().clear_wait_log_flag()
177
169
  if Config().get('debugs.timings', False) and 'cmd' in locals() and 's0' in locals():
178
170
  log2(f'Timing command {cmd}: {time.time() - s0:.2f}')
179
171
 
180
172
  # offload audit logging
181
173
  if cmd and (state.device != ReplState.L or Config().get('audit.log-audit-queries', False)):
182
- executor.submit(audit_log, cmd, state)
183
-
184
- def audit_log(cmd: str, state: ReplState):
185
- payload = {
186
- 'cluster': state.namespace if state.namespace else 'NA',
187
- 'ts': time.time(),
188
- 'host': get_my_host(),
189
- 'user': getpass.getuser(),
190
- 'line': cmd.replace('"', '""').replace('\n', ' '),
191
- }
192
- audit_endpoint = Config().get("audit.endpoint", "https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/")
193
- try:
194
- response = requests.post(audit_endpoint, json=payload, timeout=Config().get("audit.timeout", 10))
195
- if response.status_code in [200, 201]:
196
- Config().debug(response.text)
197
- else:
198
- log2(f"Error: {response.status_code} {response.text}")
199
- except requests.exceptions.Timeout as e:
200
- log2(f"Timeout occurred: {e}")
174
+ executor.submit(Audits.log, cmd, state.namespace, state.device, time.time() - s0, get_audit_extra(result))
175
+
176
+ def try_device_default_action(state: ReplState, cmds: Command, cmd_list: list[Command], cmd: str):
177
+ result = None
178
+
179
+ c_sql_tried = False
180
+ if state.device == ReplState.P:
181
+ pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path)
182
+ if pg.db:
183
+ c_sql_tried = True
184
+ cmd = f'pg {cmd}'
185
+ result = cmds.run(cmd, state)
186
+ elif state.device == ReplState.A:
187
+ if state.app_app:
188
+ c_sql_tried = True
189
+ cmd = f'app {cmd}'
190
+ result = cmds.run(cmd, state)
191
+ elif state.device == ReplState.L:
192
+ c_sql_tried = True
193
+ cmd = f'audit {cmd}'
194
+ result = cmds.run(cmd, state)
195
+ elif state.device == ReplState.X:
196
+ c_sql_tried = True
197
+ cmd = f'&{cmd}'
198
+ result = cmds.run(cmd, state)
199
+ elif state.sts:
200
+ c_sql_tried = True
201
+ cmd = f'cql {cmd}'
202
+ result = cmds.run(cmd, state)
203
+
204
+ if not c_sql_tried:
205
+ log2(f'* Invalid command: {cmd}')
206
+ log2()
207
+ lines = [c.help(state) for c in cmd_list if c.help(state)]
208
+ log2(lines_to_tabular(lines, separator='\t'))
209
+
210
+ return result
211
+
212
+ def get_audit_extra(result: any):
213
+ if not result:
214
+ return None
215
+
216
+ if type(result) is list:
217
+ extras = set()
218
+
219
+ for r in result:
220
+ if hasattr(r, '__audit_extra__') and (x := r.__audit_extra__()):
221
+ extras.add(x)
222
+
223
+ return ','.join(list(extras))
224
+
225
+ if hasattr(result, '__audit_extra__') and (x := result.__audit_extra__()):
226
+ return x
201
227
 
202
228
  @cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=ClusterCommandHelper, help="Enter interactive shell.")
203
229
  @click.option('--kubeconfig', '-k', required=False, metavar='path', help='path to kubeconfig file')
adam/repl_commands.py CHANGED
@@ -2,7 +2,8 @@ from adam.commands.alter_tables import AlterTables
2
2
  from adam.commands.app import App
3
3
  from adam.commands.app_ping import AppPing
4
4
  from adam.commands.audit.audit import Audit
5
- from adam.commands.audit.audit_repair_tables import AuditRepairTables
5
+ from adam.commands.cat import Cat
6
+ from adam.commands.code import Code
6
7
  from adam.commands.deploy.code_start import CodeStart
7
8
  from adam.commands.deploy.code_stop import CodeStop
8
9
  from adam.commands.deploy.deploy import Deploy
@@ -13,16 +14,21 @@ from adam.commands.deploy.undeploy import Undeploy
13
14
  from adam.commands.deploy.undeploy_frontend import UndeployFrontend
14
15
  from adam.commands.deploy.undeploy_pg_agent import UndeployPgAgent
15
16
  from adam.commands.deploy.undeploy_pod import UndeployPod
16
- from adam.commands.describe.describe import Describe
17
+ from adam.commands.export.export import ExportTables
18
+ from adam.commands.export.export_rmdbs import RemoveExportDatabases
19
+ from adam.commands.export.export_select import ExportSelect
20
+ from adam.commands.export.export_use import ExportUse
21
+ from adam.commands.export.export_on_x import ExportSelectX, ExportUseX
22
+ from adam.commands.kubectl import Kubectl
17
23
  from adam.commands.shell import Shell
18
24
  from adam.commands.show.show_app_queues import ShowAppQueues
19
25
  from adam.commands.cp import ClipboardCopy
20
- from adam.commands.bash import Bash
26
+ from adam.commands.bash.bash import Bash
21
27
  from adam.commands.cd import Cd
22
28
  from adam.commands.check import Check
23
29
  from adam.commands.command import Command
24
30
  from adam.commands.cql.cqlsh import Cqlsh
25
- from adam.commands.devices import DeviceApp, DeviceAuditLog, DeviceCass, DevicePostgres
31
+ from adam.commands.devices import DeviceApp, DeviceAuditLog, DeviceCass, DeviceExport, DevicePostgres
26
32
  from adam.commands.exit import Exit
27
33
  from adam.commands.medusa.medusa import Medusa
28
34
  from adam.commands.param_get import GetParam
@@ -55,10 +61,10 @@ from adam.commands.watch import Watch
55
61
 
56
62
  class ReplCommands:
57
63
  def repl_cmd_list() -> list[Command]:
58
- cmds: list[Command] = ReplCommands.navigation() + ReplCommands.cassandra_check() + ReplCommands.cassandra_ops() + \
59
- ReplCommands.tools() + ReplCommands.app() + ReplCommands.exit()
64
+ cmds: list[Command] = ReplCommands.navigation() + ReplCommands.cassandra_ops() + ReplCommands.postgres_ops() + \
65
+ ReplCommands.app_ops() + ReplCommands.audit_ops() + ReplCommands.export_ops() + ReplCommands.tools() + ReplCommands.exit()
60
66
 
61
- intermediate_cmds: list[Command] = [App(), Reaper(), Repair(), Deploy(), Describe(), Show(), Undeploy()]
67
+ intermediate_cmds: list[Command] = [App(), Audit(), Reaper(), Repair(), Deploy(), Show(), Undeploy()]
62
68
  ic = [c.command() for c in intermediate_cmds]
63
69
  # 1. dedup commands
64
70
  deduped = []
@@ -75,22 +81,28 @@ class ReplCommands:
75
81
  return deduped
76
82
 
77
83
  def navigation() -> list[Command]:
78
- return [Ls(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), DeviceAuditLog(), Cd(), Pwd(), ClipboardCopy(),
84
+ return [Ls(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), DeviceAuditLog(), DeviceExport(), Cd(), Cat(), Pwd(), ClipboardCopy(),
79
85
  GetParam(), SetParam(), ShowParams(), ShowKubectlCommands(), ShowLogin(), ShowAdam(), ShowHost()]
80
86
 
81
- def cassandra_check() -> list[Command]:
82
- return Describe.cmd_list() + [ShowCassandraStatus(),
83
- ShowCassandraVersion(), ShowRepairs(), ShowStorage(), ShowProcesses(), Check(), Issues(), NodeTool(), Report()]
84
-
85
87
  def cassandra_ops() -> list[Command]:
86
- return [AlterTables()] + Medusa.cmd_list() + [Restart(), RollOut(), Watch()] + Reaper.cmd_list() + Repair.cmd_list()
88
+ return [Cqlsh(), ShowCassandraStatus(), ShowCassandraVersion(), ShowRepairs(), ShowStorage(), ShowProcesses(), Check(), Issues(), NodeTool(), Report()] + \
89
+ [AlterTables(), Bash(), ExportTables(), ExportSelect(), ExportUse(), RemoveExportDatabases()] + \
90
+ Medusa.cmd_list() + [Restart(), RollOut(), Watch()] + Reaper.cmd_list() + Repair.cmd_list()
87
91
 
88
- def tools() -> list[Command]:
89
- return [Cqlsh(), Postgres(), Bash(), Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(),
90
- DeployPod(), UndeployPod(), DeployPgAgent(), UndeployPgAgent(), AuditRepairTables(), Audit()]
92
+ def postgres_ops() -> list[Command]:
93
+ return [Postgres(), DeployPgAgent(), UndeployPgAgent()]
91
94
 
92
- def app() -> list[Command]:
95
+ def app_ops() -> list[Command]:
93
96
  return [ShowAppActions(), ShowAppId(), ShowAppQueues(), AppPing(), App()]
94
97
 
98
+ def audit_ops() -> list[Command]:
99
+ return [Audit()] + Audit.cmd_list()
100
+
101
+ def export_ops() -> list[Command]:
102
+ return [ExportUseX(), ExportSelectX()]
103
+
104
+ def tools() -> list[Command]:
105
+ return [Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(), DeployPod(), UndeployPod(), Kubectl(), Code()]
106
+
95
107
  def exit() -> list[Command]:
96
108
  return [Exit()]