kaqing 2.0.115__py3-none-any.whl → 2.0.172__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 (187) hide show
  1. adam/__init__.py +0 -2
  2. adam/app_session.py +8 -11
  3. adam/batch.py +3 -3
  4. adam/checks/check_utils.py +14 -46
  5. adam/checks/cpu.py +7 -1
  6. adam/checks/cpu_metrics.py +52 -0
  7. adam/checks/disk.py +2 -3
  8. adam/columns/columns.py +3 -1
  9. adam/columns/cpu.py +3 -1
  10. adam/columns/cpu_metrics.py +22 -0
  11. adam/columns/memory.py +3 -4
  12. adam/commands/__init__.py +18 -0
  13. adam/commands/alter_tables.py +43 -47
  14. adam/commands/audit/audit.py +24 -25
  15. adam/commands/audit/audit_repair_tables.py +14 -17
  16. adam/commands/audit/audit_run.py +15 -23
  17. adam/commands/audit/show_last10.py +10 -13
  18. adam/commands/audit/show_slow10.py +10 -13
  19. adam/commands/audit/show_top10.py +10 -14
  20. adam/commands/audit/utils_show_top10.py +2 -3
  21. adam/commands/bash/__init__.py +5 -0
  22. adam/commands/bash/bash.py +8 -96
  23. adam/commands/bash/utils_bash.py +16 -0
  24. adam/commands/cat.py +14 -19
  25. adam/commands/cd.py +12 -100
  26. adam/commands/check.py +20 -21
  27. adam/commands/cli_commands.py +2 -3
  28. adam/commands/code.py +20 -23
  29. adam/commands/command.py +123 -39
  30. adam/commands/commands_utils.py +8 -17
  31. adam/commands/cp.py +33 -39
  32. adam/commands/cql/cql_completions.py +28 -10
  33. adam/commands/cql/cqlsh.py +10 -30
  34. adam/commands/cql/utils_cql.py +343 -0
  35. adam/commands/deploy/code_start.py +7 -10
  36. adam/commands/deploy/code_stop.py +4 -21
  37. adam/commands/deploy/code_utils.py +3 -3
  38. adam/commands/deploy/deploy.py +4 -27
  39. adam/commands/deploy/deploy_frontend.py +14 -17
  40. adam/commands/deploy/deploy_pg_agent.py +2 -5
  41. adam/commands/deploy/deploy_pod.py +65 -73
  42. adam/commands/deploy/deploy_utils.py +14 -24
  43. adam/commands/deploy/undeploy.py +4 -27
  44. adam/commands/deploy/undeploy_frontend.py +4 -7
  45. adam/commands/deploy/undeploy_pg_agent.py +5 -7
  46. adam/commands/deploy/undeploy_pod.py +11 -12
  47. adam/commands/devices/__init__.py +0 -0
  48. adam/commands/devices/device.py +118 -0
  49. adam/commands/devices/device_app.py +173 -0
  50. adam/commands/devices/device_auit_log.py +49 -0
  51. adam/commands/devices/device_cass.py +185 -0
  52. adam/commands/devices/device_export.py +86 -0
  53. adam/commands/devices/device_postgres.py +144 -0
  54. adam/commands/devices/devices.py +25 -0
  55. adam/commands/exit.py +1 -4
  56. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  57. adam/commands/export/clean_up_export_sessions.py +51 -0
  58. adam/commands/export/drop_export_database.py +55 -0
  59. adam/commands/export/drop_export_databases.py +43 -0
  60. adam/commands/export/export.py +19 -26
  61. adam/commands/export/export_databases.py +174 -0
  62. adam/commands/export/export_handlers.py +71 -0
  63. adam/commands/export/export_select.py +48 -22
  64. adam/commands/export/export_select_x.py +54 -0
  65. adam/commands/export/export_use.py +19 -23
  66. adam/commands/export/exporter.py +353 -0
  67. adam/commands/export/import_session.py +40 -0
  68. adam/commands/export/importer.py +67 -0
  69. adam/commands/export/importer_athena.py +77 -0
  70. adam/commands/export/importer_sqlite.py +39 -0
  71. adam/commands/export/show_column_counts.py +54 -0
  72. adam/commands/export/show_export_databases.py +36 -0
  73. adam/commands/export/show_export_session.py +48 -0
  74. adam/commands/export/show_export_sessions.py +44 -0
  75. adam/commands/export/utils_export.py +223 -162
  76. adam/commands/help.py +1 -1
  77. adam/commands/intermediate_command.py +49 -0
  78. adam/commands/issues.py +11 -43
  79. adam/commands/kubectl.py +3 -6
  80. adam/commands/login.py +22 -24
  81. adam/commands/logs.py +3 -6
  82. adam/commands/ls.py +11 -128
  83. adam/commands/medusa/medusa.py +4 -22
  84. adam/commands/medusa/medusa_backup.py +20 -24
  85. adam/commands/medusa/medusa_restore.py +29 -33
  86. adam/commands/medusa/medusa_show_backupjobs.py +14 -18
  87. adam/commands/medusa/medusa_show_restorejobs.py +11 -18
  88. adam/commands/nodetool.py +6 -15
  89. adam/commands/param_get.py +11 -12
  90. adam/commands/param_set.py +9 -10
  91. adam/commands/postgres/postgres.py +41 -34
  92. adam/commands/postgres/postgres_context.py +57 -24
  93. adam/commands/postgres/postgres_ls.py +4 -8
  94. adam/commands/postgres/postgres_preview.py +5 -9
  95. adam/commands/postgres/psql_completions.py +1 -1
  96. adam/commands/postgres/utils_postgres.py +66 -0
  97. adam/commands/preview_table.py +5 -44
  98. adam/commands/pwd.py +14 -47
  99. adam/commands/reaper/reaper.py +4 -27
  100. adam/commands/reaper/reaper_forward.py +48 -55
  101. adam/commands/reaper/reaper_forward_session.py +6 -0
  102. adam/commands/reaper/reaper_forward_stop.py +10 -16
  103. adam/commands/reaper/reaper_restart.py +7 -14
  104. adam/commands/reaper/reaper_run_abort.py +11 -30
  105. adam/commands/reaper/reaper_runs.py +42 -57
  106. adam/commands/reaper/reaper_runs_abort.py +29 -49
  107. adam/commands/reaper/reaper_schedule_activate.py +11 -30
  108. adam/commands/reaper/reaper_schedule_start.py +10 -29
  109. adam/commands/reaper/reaper_schedule_stop.py +10 -29
  110. adam/commands/reaper/reaper_schedules.py +4 -14
  111. adam/commands/reaper/reaper_status.py +8 -16
  112. adam/commands/reaper/utils_reaper.py +196 -0
  113. adam/commands/repair/repair.py +4 -22
  114. adam/commands/repair/repair_log.py +5 -11
  115. adam/commands/repair/repair_run.py +27 -34
  116. adam/commands/repair/repair_scan.py +32 -38
  117. adam/commands/repair/repair_stop.py +5 -11
  118. adam/commands/report.py +27 -29
  119. adam/commands/restart.py +25 -26
  120. adam/commands/rollout.py +19 -24
  121. adam/commands/shell.py +10 -4
  122. adam/commands/show/show.py +10 -25
  123. adam/commands/show/show_cassandra_repairs.py +35 -0
  124. adam/commands/show/show_cassandra_status.py +32 -43
  125. adam/commands/show/show_cassandra_version.py +5 -18
  126. adam/commands/show/show_commands.py +19 -24
  127. adam/commands/show/show_host.py +1 -1
  128. adam/commands/show/show_login.py +20 -27
  129. adam/commands/show/show_processes.py +15 -19
  130. adam/commands/show/show_storage.py +10 -20
  131. adam/commands/watch.py +26 -29
  132. adam/config.py +5 -14
  133. adam/embedded_params.py +1 -1
  134. adam/log.py +4 -4
  135. adam/pod_exec_result.py +3 -3
  136. adam/repl.py +40 -103
  137. adam/repl_commands.py +32 -16
  138. adam/repl_state.py +57 -28
  139. adam/sql/sql_completer.py +44 -28
  140. adam/sql/sql_state_machine.py +89 -28
  141. adam/sso/authn_ad.py +6 -8
  142. adam/sso/authn_okta.py +4 -6
  143. adam/sso/cred_cache.py +3 -5
  144. adam/sso/idp.py +9 -12
  145. adam/utils.py +435 -6
  146. adam/utils_athena.py +57 -37
  147. adam/utils_audits.py +12 -14
  148. adam/utils_issues.py +32 -0
  149. adam/utils_k8s/app_clusters.py +13 -18
  150. adam/utils_k8s/app_pods.py +2 -0
  151. adam/utils_k8s/cassandra_clusters.py +22 -19
  152. adam/utils_k8s/cassandra_nodes.py +2 -2
  153. adam/utils_k8s/custom_resources.py +16 -17
  154. adam/utils_k8s/ingresses.py +2 -2
  155. adam/utils_k8s/jobs.py +7 -11
  156. adam/utils_k8s/k8s.py +87 -0
  157. adam/utils_k8s/pods.py +40 -77
  158. adam/utils_k8s/secrets.py +4 -4
  159. adam/utils_k8s/service_accounts.py +5 -4
  160. adam/utils_k8s/services.py +2 -2
  161. adam/utils_k8s/statefulsets.py +1 -12
  162. adam/utils_net.py +4 -4
  163. adam/utils_repl/__init__.py +0 -0
  164. adam/utils_repl/automata_completer.py +48 -0
  165. adam/utils_repl/repl_completer.py +46 -0
  166. adam/utils_repl/state_machine.py +173 -0
  167. adam/utils_sqlite.py +137 -0
  168. adam/version.py +1 -1
  169. {kaqing-2.0.115.dist-info → kaqing-2.0.172.dist-info}/METADATA +1 -1
  170. kaqing-2.0.172.dist-info/RECORD +230 -0
  171. adam/commands/app.py +0 -67
  172. adam/commands/app_ping.py +0 -44
  173. adam/commands/cql/cql_utils.py +0 -204
  174. adam/commands/devices.py +0 -147
  175. adam/commands/export/export_on_x.py +0 -76
  176. adam/commands/export/export_rmdbs.py +0 -65
  177. adam/commands/postgres/postgres_utils.py +0 -31
  178. adam/commands/reaper/reaper_session.py +0 -159
  179. adam/commands/show/show_app_actions.py +0 -56
  180. adam/commands/show/show_app_id.py +0 -47
  181. adam/commands/show/show_app_queues.py +0 -45
  182. adam/commands/show/show_repairs.py +0 -47
  183. adam/utils_export.py +0 -42
  184. kaqing-2.0.115.dist-info/RECORD +0 -203
  185. {kaqing-2.0.115.dist-info → kaqing-2.0.172.dist-info}/WHEEL +0 -0
  186. {kaqing-2.0.115.dist-info → kaqing-2.0.172.dist-info}/entry_points.txt +0 -0
  187. {kaqing-2.0.115.dist-info → kaqing-2.0.172.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,7 @@
1
+ from adam.commands import extract_options, extract_sequence
1
2
  from adam.commands.command import Command
2
3
  from adam.commands.commands_utils import show_table
4
+ from adam.commands.cql.utils_cql import cassandra
3
5
  from adam.config import Config
4
6
  from adam.utils_k8s.statefulsets import StatefulSets
5
7
  from adam.repl_state import ReplState, RequiredState
@@ -26,28 +28,22 @@ class ShowProcesses(Command):
26
28
  if not(args := self.args(cmd)):
27
29
  return super().run(cmd, state)
28
30
 
29
- state, args = self.apply_state(args, state)
30
- if not self.validate_state(state):
31
- return state
31
+ with self.validate(args, state) as (args, state):
32
+ with extract_options(args, ['-s', '--show']) as (args, show_out):
33
+ with extract_sequence(args, ['with', 'recipe', '=', 'qing']) as (_, recipe_qing):
34
+ cols = Config().get('processes.columns', 'pod,cpu-metrics,mem')
35
+ header = Config().get('processes.header', 'POD_NAME,M_CPU(USAGE/LIMIT),MEM/LIMIT')
36
+ if recipe_qing:
37
+ cols = Config().get('processes-qing.columns', 'pod,cpu,mem')
38
+ header = Config().get('processes-qing.header', 'POD_NAME,Q_CPU/TOTAL,MEM/LIMIT')
32
39
 
33
- args, show_output = Command.extract_options(args, ['-s', '--show'])
40
+ with cassandra(state) as pods:
41
+ pods.display_table(cols, header, show_out=show_out)
34
42
 
35
- cols = Config().get('processes.columns', 'pod,cpu,mem')
36
- header = Config().get('processes.header', 'POD_NAME,CPU,MEM/LIMIT')
37
-
38
- if state.pod:
39
- show_table(state, [state.pod], cols, header, show_output=show_output)
40
- elif state.sts:
41
- pod_names = [pod.metadata.name for pod in StatefulSets.pods(state.sts, state.namespace)]
42
- show_table(state, pod_names, cols, header, show_output=show_output)
43
-
44
- return state
43
+ return state
45
44
 
46
45
  def completion(self, state: ReplState):
47
- if not state.sts:
48
- return {}
49
-
50
- return super().completion(state)
46
+ return super().completion(state, {'with': {'recipe': {'=': {'metrics': {'-s': None}, 'qing': {'-s': None}}}}, '-s': None})
51
47
 
52
48
  def help(self, _: ReplState):
53
- return f'{ShowProcesses.COMMAND} [-s]\t show process overview -s show commands on nodes'
49
+ return f'{ShowProcesses.COMMAND} [with recipe qing|metrics] [-s]\t show process overview -s show commands on nodes'
@@ -1,7 +1,7 @@
1
+ from adam.commands import extract_options
1
2
  from adam.commands.command import Command
2
- from adam.commands.commands_utils import show_table
3
+ from adam.commands.cql.utils_cql import cassandra
3
4
  from adam.config import Config
4
- from adam.utils_k8s.statefulsets import StatefulSets
5
5
  from adam.repl_state import ReplState, RequiredState
6
6
 
7
7
  class ShowStorage(Command):
@@ -26,27 +26,17 @@ class ShowStorage(Command):
26
26
  if not(args := self.args(cmd)):
27
27
  return super().run(cmd, state)
28
28
 
29
- state, args = self.apply_state(args, state)
30
- if not self.validate_state(state):
31
- return state
29
+ with self.validate(args, state) as (args, state):
30
+ with extract_options(args, ['-s', '--show']) as (args, show_out):
31
+ cols = Config().get('storage.columns', 'pod,volume_root,volume_cassandra,snapshots,data,compactions')
32
+ header = Config().get('storage.header', 'POD_NAME,VOLUME /,VOLUME CASS,SNAPSHOTS,DATA,COMPACTIONS')
33
+ with cassandra(state) as pods:
34
+ pods.display_table(cols, header, show_out=show_out)
32
35
 
33
- args, show_output = Command.extract_options(args, ['-s', '--show'])
34
-
35
- cols = Config().get('storage.columns', 'pod,volume_root,volume_cassandra,snapshots,data,compactions')
36
- header = Config().get('storage.header', 'POD_NAME,VOLUME /,VOLUME CASS,SNAPSHOTS,DATA,COMPACTIONS')
37
- if state.pod:
38
- show_table(state, [state.pod], cols, header, show_output=show_output)
39
- elif state.sts:
40
- pod_names = [pod.metadata.name for pod in StatefulSets.pods(state.sts, state.namespace)]
41
- show_table(state, pod_names, cols, header, show_output=show_output)
42
-
43
- return state
36
+ return state
44
37
 
45
38
  def completion(self, state: ReplState):
46
- if not state.sts:
47
- return {}
48
-
49
- return super().completion(state)
39
+ return super().completion(state, {'-s': None})
50
40
 
51
41
  def help(self, _: ReplState):
52
42
  return f'{ShowStorage.COMMAND} [-s]\t show storage overview -s show commands on nodes'
adam/commands/watch.py CHANGED
@@ -8,10 +8,10 @@ from adam.commands.commands_utils import show_pods, show_rollout
8
8
  from adam.config import Config
9
9
  from adam.utils_k8s.statefulsets import StatefulSets
10
10
  from adam.repl_state import ReplState, RequiredState
11
- from adam.utils import convert_seconds, log2
11
+ from adam.utils import log2
12
12
 
13
13
  class Watch(Command):
14
- COMMAND = 'watch'
14
+ COMMAND = 'watch cassandra pods'
15
15
 
16
16
  # the singleton pattern
17
17
  def __new__(cls, *args, **kwargs):
@@ -26,37 +26,34 @@ class Watch(Command):
26
26
  return Watch.COMMAND
27
27
 
28
28
  def required(self):
29
- return RequiredState.CLUSTER_OR_POD
29
+ return RequiredState.NAMESPACE
30
30
 
31
31
  def run(self, cmd: str, state: ReplState):
32
32
  if not(args := self.args(cmd)):
33
33
  return super().run(cmd, state)
34
34
 
35
- state, args = self.apply_state(args, state)
36
- if not self.validate_state(state):
37
- return state
38
-
39
- pods = StatefulSets.pods(state.sts, state.namespace)
40
- if not pods:
41
- log2("No pods are found.")
42
- return state
35
+ with self.validate(args, state) as (args, state):
36
+ pods = StatefulSets.pods(state.sts, state.namespace)
37
+ if not pods:
38
+ log2("No pods are found.")
39
+ return state
43
40
 
44
- stop_event = threading.Event()
45
- thread = threading.Thread(target=self.loop, args=(stop_event, state.sts, pods, state.namespace), daemon=True)
46
- thread.start()
41
+ stop_event = threading.Event()
42
+ thread = threading.Thread(target=self.loop, args=(stop_event, state.sts, pods, state.namespace), daemon=True)
43
+ thread.start()
47
44
 
48
- try:
49
- log2(f"Press Ctrl+C to break.")
45
+ try:
46
+ log2(f"Press Ctrl+C to break.")
50
47
 
51
- time.sleep(Config().get('watch.timeout', 3600 * 1))
52
- except KeyboardInterrupt:
53
- pass
48
+ time.sleep(Config().get('watch.timeout', 3600 * 1))
49
+ except KeyboardInterrupt:
50
+ pass
54
51
 
55
- log2("Stopping watch...")
56
- stop_event.set()
57
- thread.join()
52
+ log2("Stopping watch...")
53
+ stop_event.set()
54
+ thread.join()
58
55
 
59
- return state
56
+ return state
60
57
 
61
58
  def loop(self, stop_flag: threading.Event, sts: str, pods: List[client.V1Pod], ns: str):
62
59
  show_pods(pods, ns)
@@ -73,13 +70,13 @@ class Watch(Command):
73
70
  cnt = Config().get('watch.interval', 10)
74
71
 
75
72
  def completion(self, state: ReplState):
76
- if state.pod:
77
- return {}
73
+ if sc := super().completion(state):
74
+ if state.sts:
75
+ return sc
78
76
 
79
- if not state.sts:
80
- return {Watch.COMMAND: {n: None for n in StatefulSets.list_sts_names()}}
77
+ return super().completion(state, {n: None for n in StatefulSets.list_sts_names()})
81
78
 
82
- return {Watch.COMMAND: None}
79
+ return {}
83
80
 
84
81
  def help(self, _: ReplState):
85
- return f'{Watch.COMMAND}\t watch pod changes'
82
+ return f'{Watch.COMMAND}\t watch Cassandra pod changes'
adam/config.py CHANGED
@@ -3,13 +3,16 @@ from typing import TypeVar, cast
3
3
  import yaml
4
4
 
5
5
  from . import __version__
6
- from adam.utils import copy_config_file, get_deep_keys, log2
6
+ from adam.utils import LogConfig, copy_config_file, get_deep_keys, log2
7
7
 
8
8
  T = TypeVar('T')
9
9
 
10
10
  class Config:
11
11
  EMBEDDED_PARAMS = {}
12
12
 
13
+ LogConfig.is_debug = lambda: Config().is_debug()
14
+ LogConfig.is_debug_timing = lambda: Config().get('debugs.timings', False)
15
+
13
16
  # the singleton pattern
14
17
  def __new__(cls, *args, **kwargs):
15
18
  if not hasattr(cls, 'instance'): cls.instance = super(Config, cls).__new__(cls)
@@ -41,10 +44,6 @@ class Config:
41
44
  def is_debug(self):
42
45
  return os.getenv('QING_DEV', 'false').lower() == 'true' or Config().get('debug', False)
43
46
 
44
- def debug(self, s: None):
45
- if self.is_debug():
46
- log2(f'DEBUG {s}')
47
-
48
47
  def get(self, key: str, default: T) -> T:
49
48
  # params['nodetool']['status']['max-nodes']
50
49
  d = self.params
@@ -85,12 +84,4 @@ class Config:
85
84
  log2(f'incorrect path: {key}')
86
85
  return None
87
86
 
88
- return v if v else 'false'
89
-
90
- def wait_log(self, msg: str):
91
- if hasattr(self, 'wait_log_flag') and not self.wait_log_flag:
92
- log2(msg)
93
- self.wait_log_flag = True
94
-
95
- def clear_wait_log_flag(self):
96
- self.wait_log_flag = False
87
+ return v if v else 'false'
adam/embedded_params.py CHANGED
@@ -1,2 +1,2 @@
1
1
  def config():
2
- return {'app': {'console-endpoint': 'https://{host}/{env}/{app}/static/console/index.html', 'container-name': 'c3-server', 'cr': {'cluster-regex': '(.*?-.*?)-.*', 'group': 'ops.c3.ai', 'v': 'v2', 'plural': 'c3cassandras'}, 'label': 'c3__app_id-0', 'login': {'admin-group': '{host}/C3.ClusterAdmin', 'ingress': '{app_id}-k8singr-appleader-001', 'timeout': 5, 'session-check-url': 'https://{host}/{env}/{app}/api/8/C3/userSessionToken', 'cache-creds': True, 'cache-username': True, 'url': 'https://{host}/{env}/{app}', 'another': "You're logged in to {has}. However, for this app, you need to log in to {need}.", 'token-server-url': 'http://localhost:{port}', 'password-max-length': 128}, 'strip': '0'}, 'audit': {'endpoint': 'https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/', 'workers': 3, 'timeout': 10, 'log-audit-queries': False, 'athena': {'auto-repair': {'elapsed_hours': 12}, 'region': 'us-west-2', 'catalog': 'AwsDataCatalog', 'database': 'audit', 'repair-partition-tables': 'audit', 'output': 's3://s3.ops--audit/ddl/results', 'repair-cluster-tables': 'cluster'}}, 'bash': {'workers': 32}, 'cassandra': {'service-name': 'all-pods-service'}, 'cql': {'workers': 32, 'samples': 3, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-superuser', 'password-item': 'password'}, 'alter-tables': {'excludes': 'system_auth,system_traces,reaper_db,system_distributed,system_views,system,system_schema,system_virtual_schema', 'gc-grace-periods': '3600,86400,864000,7776000', 'batching': True}}, 'export': {'workers': 8, 'temp_dir': '/c3/cassandra/tmp', 'columns': '<keys>'}, 'checks': {'compactions-threshold': 250, 'cpu-busy-threshold': 98.0, 'cpu-threshold': 0.0, 'cassandra-data-path': '/c3/cassandra', 'root-disk-threshold': 50, 'cassandra-disk-threshold': 50, 'snapshot-size-cmd': "ls /c3/cassandra/data/data/*/*/snapshots | grep snapshots | sed 's/:$//g' | xargs -I {} du -sk {} | awk '{print $1}' | awk '{s+=$1} END {print s}'", 'snapshot-size-threshold': '40G', 'table-sizes-cmd': "ls -Al /c3/cassandra/data/data/ | awk '{print $9}' | sed 's/\\^r//g' | xargs -I {} du -sk /c3/cassandra/data/data/{}"}, 'get-host-id': {'workers': 32}, 'idps': {'ad': {'email-pattern': '.*@c3.ai', 'uri': 'https://login.microsoftonline.com/53ad779a-93e7-485c-ba20-ac8290d7252b/oauth2/v2.0/authorize?response_type=id_token&response_mode=form_post&client_id=00ff94a8-6b0a-4715-98e0-95490012d818&scope=openid+email+profile&redirect_uri=https%3A%2F%2Fplat.c3ci.cloud%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://login.microsoftonline.com/common/discovery/keys', 'contact': 'Please contact ted.tran@c3.ai.', 'whitelist-file': '/kaqing/members'}, 'okta': {'default': True, 'email-pattern': '.*@c3iot.com', 'uri': 'https://c3energy.okta.com/oauth2/v1/authorize?response_type=id_token&response_mode=form_post&client_id={client_id}&scope=openid+email+profile+groups&redirect_uri=https%3A%2F%2F{host}%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://c3energy.okta.com/oauth2/v1/keys'}}, 'issues': {'workers': 32}, 'logs': {'path': '/c3/cassandra/logs/system.log'}, 'medusa': {'restore-auto-complete': False}, 'nodetool': {'workers': 32, 'samples': 3, 'commands_in_line': 40}, 'pg': {'name-pattern': '^{namespace}.*-k8spg-.*', 'excludes': '.helm., -admin-secret', 'agent': {'name': 'ops-pg-agent', 'just-in-time': False, 'timeout': 86400, 'image': 'seanahnsf/kaqing'}, 'default-db': 'postgres', 'default-schema': 'postgres', 'secret': {'endpoint-key': 'postgres-db-endpoint', 'port-key': 'postgres-db-port', 'username-key': 'postgres-admin-username', 'password-key': 'postgres-admin-password'}}, 'pod': {'name': 'ops', 'image': 'seanahnsf/kaqing-cloud', 'sa': {'name': 'ops', 'proto': 'c3', 'additional-cluster-roles': 'c3aiops-k8ssandra-operator'}, 'label-selector': 'run=ops'}, 'preview': {'rows': 10}, 'processes': {'columns': 'pod,cpu,mem', 'header': 'POD_NAME,CPU,MEM/LIMIT'}, 'reaper': {'service-name': 'reaper-service', 'port-forward': {'timeout': 86400, 'local-port': 9001}, 'abort-runs-batch': 10, 'show-runs-batch': 100, 'pod': {'cluster-regex': '(.*?-.*?-.*?-.*?)-.*', 'label-selector': 'k8ssandra.io/reaper={cluster}-reaper'}, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-reaper-ui', 'password-item': 'password'}}, 'repair': {'log-path': '/home/cassrepair/logs/', 'image': 'ci-registry.c3iot.io/cloudops/cassrepair:2.0.14', 'secret': 'ciregistryc3iotio', 'env': {'interval': 24, 'timeout': 60, 'pr': False, 'runs': 1}}, 'repl': {'start-drive': 'a', 'a': {'auto-enter': 'c3/c3/*'}, 'c': {'auto-enter': 'cluster'}, 'history': {'push-cat-remote-log-file': True}, 'background-process': {'auto-nohup': True}}, 'status': {'columns': 'status,address,load,tokens,owns,host_id,gossip,compactions', 'header': '--,Address,Load,Tokens,Owns,Host ID,GOSSIP,COMPACTIONS'}, 'storage': {'columns': 'pod,volume_root,volume_cassandra,snapshots,data,compactions', 'header': 'POD_NAME,VOLUME /,VOLUME CASS,SNAPSHOTS,DATA,COMPACTIONS'}, 'watch': {'auto': 'rollout', 'timeout': 3600, 'interval': 10}, 'debug': False, 'debugs': {'timings': False, 'exit-on-error': False, 'show-parallelism': False}}
2
+ return {'app': {'console-endpoint': 'https://{host}/{env}/{app}/static/console/index.html', 'container-name': 'c3-server', 'cr': {'cluster-regex': '(.*?-.*?)-.*', 'group': 'ops.c3.ai', 'v': 'v2', 'plural': 'c3cassandras'}, 'label': 'c3__app_id-0', 'login': {'admin-group': '{host}/C3.ClusterAdmin', 'ingress': '{app_id}-k8singr-appleader-001', 'timeout': 5, 'session-check-url': 'https://{host}/{env}/{app}/api/8/C3/userSessionToken', 'cache-creds': True, 'cache-username': True, 'url': 'https://{host}/{env}/{app}', 'another': "You're logged in to {has}. However, for this app, you need to log in to {need}.", 'token-server-url': 'http://localhost:{port}', 'password-max-length': 128}, 'strip': '0'}, 'audit': {'endpoint': 'https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/', 'workers': 3, 'timeout': 10, 'log-audit-queries': False, 'athena': {'auto-repair': {'elapsed_hours': 12}, 'region': 'us-west-2', 'catalog': 'AwsDataCatalog', 'database': 'audit', 'repair-partition-tables': 'audit', 'output': 's3://s3.ops--audit/ddl/results', 'repair-cluster-tables': 'cluster'}}, 'bash': {'workers': 32}, 'cassandra': {'service-name': 'all-pods-service'}, 'cql': {'workers': 32, 'samples': 3, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-superuser', 'password-item': 'password'}, 'alter-tables': {'excludes': 'system_auth,system_traces,reaper_db,system_distributed,system_views,system,system_schema,system_virtual_schema', 'gc-grace-periods': '3600,86400,864000,7776000', 'batching': True}}, 'export': {'workers': 8, 'csv_dir': '/c3/cassandra/tmp', 'column_counts_query': 'select id, count(id) as columns from {table} group by id order by columns desc limit 10', 'default-importer': 'sqlite', 'sqlite': {'workers': 8, 'columns': '<row-key>', 'local-db-dir': '/tmp/qing-db'}, 'athena': {'workers': 8, 'columns': '<keys>', 'bucket': 'c3.ops--qing'}, 'csv': {'workers': 8, 'columns': '<row-key>'}, 'log-prefix': '/tmp/qing'}, 'checks': {'compactions-threshold': 250, 'cpu-busy-threshold': 98.0, 'cpu-threshold': 0.0, 'cassandra-data-path': '/c3/cassandra', 'root-disk-threshold': 50, 'cassandra-disk-threshold': 50, 'snapshot-size-cmd': "ls /c3/cassandra/data/data/*/*/snapshots | grep snapshots | sed 's/:$//g' | xargs -I {} du -sk {} | awk '{print $1}' | awk '{s+=$1} END {print s}'", 'snapshot-size-threshold': '40G', 'table-sizes-cmd': "ls -Al /c3/cassandra/data/data/ | awk '{print $9}' | sed 's/\\^r//g' | xargs -I {} du -sk /c3/cassandra/data/data/{}"}, 'get-host-id': {'workers': 32}, 'idps': {'ad': {'email-pattern': '.*@c3.ai', 'uri': 'https://login.microsoftonline.com/53ad779a-93e7-485c-ba20-ac8290d7252b/oauth2/v2.0/authorize?response_type=id_token&response_mode=form_post&client_id=00ff94a8-6b0a-4715-98e0-95490012d818&scope=openid+email+profile&redirect_uri=https%3A%2F%2Fplat.c3ci.cloud%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://login.microsoftonline.com/common/discovery/keys', 'contact': 'Please contact ted.tran@c3.ai.', 'whitelist-file': '/kaqing/members'}, 'okta': {'default': True, 'email-pattern': '.*@c3iot.com', 'uri': 'https://c3energy.okta.com/oauth2/v1/authorize?response_type=id_token&response_mode=form_post&client_id={client_id}&scope=openid+email+profile+groups&redirect_uri=https%3A%2F%2F{host}%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://c3energy.okta.com/oauth2/v1/keys'}}, 'issues': {'workers': 32}, 'logs': {'path': '/c3/cassandra/logs/system.log'}, 'log-prefix': '/tmp/qing', 'medusa': {'restore-auto-complete': False}, 'nodetool': {'workers': 32, 'samples': 3, 'commands_in_line': 40}, 'pg': {'name-pattern': '^{namespace}.*-k8spg-.*', 'excludes': '.helm., -admin-secret', 'agent': {'name': 'ops-pg-agent', 'just-in-time': False, 'timeout': 86400, 'image': 'seanahnsf/kaqing'}, 'default-db': 'postgres', 'default-schema': 'postgres', 'secret': {'endpoint-key': 'postgres-db-endpoint', 'port-key': 'postgres-db-port', 'username-key': 'postgres-admin-username', 'password-key': 'postgres-admin-password'}}, 'pod': {'name': 'ops', 'image': 'seanahnsf/kaqing-cloud', 'sa': {'name': 'ops', 'proto': 'c3', 'additional-cluster-roles': 'c3aiops-k8ssandra-operator'}, 'label-selector': 'run=ops'}, 'preview': {'rows': 10}, 'processes': {'columns': 'pod,cpu-metrics,mem', 'header': 'POD_NAME,M_CPU(USAGE/LIMIT),MEM/LIMIT'}, 'processes-qing': {'columns': 'pod,cpu,mem', 'header': 'POD_NAME,Q_CPU/TOTAL,MEM/LIMIT'}, 'reaper': {'service-name': 'reaper-service', 'port-forward': {'timeout': 86400, 'local-port': 9001}, 'abort-runs-batch': 10, 'show-runs-batch': 100, 'pod': {'cluster-regex': '(.*?-.*?-.*?-.*?)-.*', 'label-selector': 'k8ssandra.io/reaper={cluster}-reaper'}, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-reaper-ui', 'password-item': 'password'}}, 'repair': {'log-path': '/home/cassrepair/logs/', 'image': 'ci-registry.c3iot.io/cloudops/cassrepair:2.0.14', 'secret': 'ciregistryc3iotio', 'env': {'interval': 24, 'timeout': 60, 'pr': False, 'runs': 1}}, 'repl': {'start-drive': 'c', 'a': {'auto-enter': 'c3/c3/*'}, 'c': {'auto-enter': 'cluster'}, 'x': {'auto-enter': 'latest'}, 'history': {'push-cat-log-file': True, 'push-cat-remote-log-file': True}, 'background-process': {'auto-nohup': True}}, 'status': {'columns': 'status,address,load,tokens,owns,host_id,gossip,compactions', 'header': '--,Address,Load,Tokens,Owns,Host ID,GOSSIP,COMPACTIONS'}, 'storage': {'columns': 'pod,volume_root,volume_cassandra,snapshots,data,compactions', 'header': 'POD_NAME,VOLUME /,VOLUME CASS,SNAPSHOTS,DATA,COMPACTIONS'}, 'watch': {'auto': 'rollout', 'timeout': 3600, 'interval': 10}, 'debug': False, 'debugs': {'timings': False, 'exit-on-error': False, 'show-parallelism': False}}
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': {},
@@ -27,10 +29,8 @@ class PodExecResult:
27
29
  def exit_code(self) -> int:
28
30
  code = 0
29
31
 
30
- try:
32
+ with log_exc(False):
31
33
  code = self.error['details']['causes'][0]['message']
32
- except:
33
- pass
34
34
 
35
35
  return code
36
36
 
adam/repl.py CHANGED
@@ -1,28 +1,22 @@
1
- from copy import copy
2
1
  import os
3
- import re
4
2
  import time
5
- import traceback
6
3
  from typing import cast
7
4
  import click
8
- import concurrent
9
5
  from prompt_toolkit.key_binding import KeyBindings
10
6
 
11
7
  from adam.cli_group import cli
12
- from adam.commands.command import Command
8
+ from adam.commands.command import Command, InvalidState
13
9
  from adam.commands.command_helpers import ClusterCommandHelper
10
+ from adam.commands.devices.devices import Devices
14
11
  from adam.commands.help import Help
15
- from adam.commands.postgres.postgres_context import PostgresContext
16
12
  from adam.config import Config
17
13
  from adam.utils_audits import Audits
18
- from adam.utils_k8s.app_pods import AppPods
19
14
  from adam.utils_k8s.kube_context import KubeContext
20
- from adam.utils_k8s.statefulsets import StatefulSets
21
15
  from adam.log import Log
22
16
  from adam.repl_commands import ReplCommands
23
17
  from adam.repl_session import ReplSession
24
18
  from adam.repl_state import ReplState
25
- from adam.utils import deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2
19
+ from adam.utils import clear_wait_log_flag, debug, debug_trace, deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2, log_exc, log_timing
26
20
  from adam.apps import Apps
27
21
  from adam.utils_repl.repl_completer import ReplCompleter
28
22
  from . import __version__
@@ -44,46 +38,7 @@ def enter_repl(state: ReplState):
44
38
 
45
39
  Log.log2(f'kaqing {__version__}')
46
40
 
47
- if state.device == ReplState.C:
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}...')
63
- elif state.device == ReplState.A:
64
- if not state.app_env:
65
- if auto_enter := Config().get('repl.a.auto-enter-app', 'c3/c3/*'):
66
- if auto_enter != 'no':
67
- ea = auto_enter.split('/')
68
- state.app_env = ea[0]
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:
81
- state.app_app = ea[1]
82
- Config().wait_log(f'Moving to {state.app_env}/{state.app_app}...')
83
- else:
84
- Config().wait_log(f'Moving to {state.app_env}...')
85
- elif state.device == ReplState.P:
86
- Config().wait_log('Inspecting postgres database instances...')
41
+ Devices.device(state).enter(state)
87
42
 
88
43
  kb = KeyBindings()
89
44
 
@@ -91,34 +46,32 @@ def enter_repl(state: ReplState):
91
46
  def _(event):
92
47
  event.app.current_buffer.text = ''
93
48
 
94
- with concurrent.futures.ThreadPoolExecutor(max_workers=Config().get('audit.workers', 3)) as executor:
49
+ with Audits.offload() as exec:
95
50
  # warm up AWS lambda - this log line may timeout and get lost, which is fine
96
- executor.submit(Audits.log, 'entering kaqing repl', state.namespace, 'z', 0.0)
51
+ exec.submit(Audits.log, 'entering kaqing repl', state.namespace, 'z', 0.0)
97
52
 
98
53
  s0 = time.time()
99
54
 
100
55
  # use sorted command list only for auto-completion
101
56
  sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
102
57
  while True:
58
+ cmd: str = None
103
59
  result = None
104
60
  try:
105
61
  completer = ReplCompleter.from_nested_dict({})
106
62
  if not state.bash_session:
107
- completions = {}
108
- # app commands are available only on a: drive
109
- if state.device == ReplState.A and state.app_app:
110
- completions = Apps(path='apps.yaml').commands()
111
-
112
- for cmd in sorted_cmds:
113
- s1 = time.time()
114
- try:
115
- completions = deep_sort_dict(deep_merge_dicts(completions, cmd.completion(state)))
116
- finally:
117
- if Config().get('debugs.timings', False):
118
- log2(f'Timing auto-completion-calc {cmd.command()}: {time.time() - s1:.2f}')
119
-
120
- # print(json.dumps(completions, indent=4))
121
- completer = ReplCompleter.from_nested_dict(completions)
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)
122
75
 
123
76
  cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
124
77
  s0 = time.time()
@@ -134,7 +87,12 @@ def enter_repl(state: ReplState):
134
87
  if not (cmd.startswith('@') and len(arry := cmd.split(' ')) > 1):
135
88
  return state, cmd
136
89
 
137
- if state.device == ReplState.A and state.app_app:
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:
138
96
  state.push()
139
97
 
140
98
  state.app_pod = arry[0].strip('@')
@@ -148,11 +106,15 @@ def enter_repl(state: ReplState):
148
106
  return (state, cmd)
149
107
 
150
108
  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)
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 InvalidState:
113
+ pass
153
114
 
154
- if result and type(result) is ReplState and (s := cast(ReplState, result).export_session):
115
+ if result and type(result) is ReplState and (s := cast(ReplState, result).export_session) != state.export_session:
155
116
  state.export_session = s
117
+
156
118
  except EOFError: # Handle Ctrl+D (EOF) for graceful exit
157
119
  break
158
120
  except Exception as e:
@@ -160,48 +122,23 @@ def enter_repl(state: ReplState):
160
122
  raise e
161
123
  else:
162
124
  log2(e)
163
- Config().debug(traceback.format_exc())
125
+ debug_trace()
164
126
  finally:
165
127
  if not state.bash_session:
166
128
  state.pop()
167
129
 
168
- Config().clear_wait_log_flag()
169
- if Config().get('debugs.timings', False) and 'cmd' in locals() and 's0' in locals():
170
- log2(f'Timing command {cmd}: {time.time() - s0:.2f}')
130
+ clear_wait_log_flag()
131
+ if cmd:
132
+ log_timing(f'command {cmd}', s0=s0)
171
133
 
172
134
  # offload audit logging
173
135
  if cmd and (state.device != ReplState.L or Config().get('audit.log-audit-queries', False)):
174
- executor.submit(Audits.log, cmd, state.namespace, state.device, time.time() - s0, get_audit_extra(result))
136
+ exec.submit(Audits.log, cmd, state.namespace, state.device, time.time() - s0, get_audit_extra(result))
175
137
 
176
138
  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:
139
+ action_taken, result = Devices.device(state).try_fallback_action(cmds, state, cmd)
140
+
141
+ if not action_taken:
205
142
  log2(f'* Invalid command: {cmd}')
206
143
  log2()
207
144
  lines = [c.help(state) for c in cmd_list if c.help(state)]
adam/repl_commands.py CHANGED
@@ -1,6 +1,9 @@
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
4
7
  from adam.commands.audit.audit import Audit
5
8
  from adam.commands.cat import Cat
6
9
  from adam.commands.code import Code
@@ -14,28 +17,39 @@ from adam.commands.deploy.undeploy import Undeploy
14
17
  from adam.commands.deploy.undeploy_frontend import UndeployFrontend
15
18
  from adam.commands.deploy.undeploy_pg_agent import UndeployPgAgent
16
19
  from adam.commands.deploy.undeploy_pod import UndeployPod
20
+ from adam.commands.devices.device_app import DeviceApp
21
+ from adam.commands.devices.device_auit_log import DeviceAuditLog
22
+ from adam.commands.devices.device_cass import DeviceCass
23
+ from adam.commands.devices.device_export import DeviceExport
24
+ from adam.commands.devices.device_postgres import DevicePostgres
25
+ from adam.commands.export.drop_export_database import DropExportDatabase
17
26
  from adam.commands.export.export import ExportTables
18
- from adam.commands.export.export_rmdbs import RemoveExportDatabases
27
+ from adam.commands.export.import_session import ImportSession
28
+ from adam.commands.export.clean_up_export_sessions import CleanUpExportSessions
29
+ from adam.commands.export.clean_up_all_export_sessions import CleanUpAllExportSessions
30
+ from adam.commands.export.drop_export_databases import DropExportDatabases
19
31
  from adam.commands.export.export_select import ExportSelect
20
32
  from adam.commands.export.export_use import ExportUse
21
- from adam.commands.export.export_on_x import ExportSelectX, ExportUseX
33
+ from adam.commands.export.export_select_x import ExportSelectX
34
+ from adam.commands.export.show_column_counts import ShowColumnCounts
35
+ from adam.commands.export.show_export_databases import ShowExportDatabases
36
+ from adam.commands.export.show_export_session import ShowExportSession
37
+ from adam.commands.export.show_export_sessions import ShowExportSessions
22
38
  from adam.commands.kubectl import Kubectl
23
39
  from adam.commands.shell import Shell
24
- from adam.commands.show.show_app_queues import ShowAppQueues
25
40
  from adam.commands.cp import ClipboardCopy
26
41
  from adam.commands.bash.bash import Bash
27
42
  from adam.commands.cd import Cd
28
43
  from adam.commands.check import Check
29
44
  from adam.commands.command import Command
30
45
  from adam.commands.cql.cqlsh import Cqlsh
31
- from adam.commands.devices import DeviceApp, DeviceAuditLog, DeviceCass, DeviceExport, DevicePostgres
32
46
  from adam.commands.exit import Exit
33
47
  from adam.commands.medusa.medusa import Medusa
34
48
  from adam.commands.param_get import GetParam
35
49
  from adam.commands.issues import Issues
36
50
  from adam.commands.ls import Ls
37
51
  from adam.commands.nodetool import NodeTool
38
- from adam.commands.postgres.postgres import Postgres
52
+ from adam.commands.postgres.postgres import Postgres, PostgresPg
39
53
  from adam.commands.preview_table import PreviewTable
40
54
  from adam.commands.pwd import Pwd
41
55
  from adam.commands.reaper.reaper import Reaper
@@ -45,8 +59,6 @@ from adam.commands.restart import Restart
45
59
  from adam.commands.rollout import RollOut
46
60
  from adam.commands.param_set import SetParam
47
61
  from adam.commands.show.show import Show
48
- from adam.commands.show.show_app_actions import ShowAppActions
49
- from adam.commands.show.show_app_id import ShowAppId
50
62
  from adam.commands.show.show_cassandra_status import ShowCassandraStatus
51
63
  from adam.commands.show.show_cassandra_version import ShowCassandraVersion
52
64
  from adam.commands.show.show_commands import ShowKubectlCommands
@@ -54,7 +66,7 @@ from adam.commands.show.show_host import ShowHost
54
66
  from adam.commands.show.show_login import ShowLogin
55
67
  from adam.commands.show.show_params import ShowParams
56
68
  from adam.commands.show.show_processes import ShowProcesses
57
- from adam.commands.show.show_repairs import ShowRepairs
69
+ from adam.commands.show.show_cassandra_repairs import ShowCassandraRepairs
58
70
  from adam.commands.show.show_storage import ShowStorage
59
71
  from adam.commands.show.show_adam import ShowAdam
60
72
  from adam.commands.watch import Watch
@@ -85,21 +97,25 @@ class ReplCommands:
85
97
  GetParam(), SetParam(), ShowParams(), ShowKubectlCommands(), ShowLogin(), ShowAdam(), ShowHost()]
86
98
 
87
99
  def cassandra_ops() -> list[Command]:
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()
100
+ return [Cqlsh(), ShowCassandraStatus(), ShowCassandraVersion(), ShowCassandraRepairs(), ShowStorage(), ShowProcesses(),
101
+ Check(), Issues(), NodeTool(), Report(), AlterTables(), Bash(),
102
+ ExportTables(), ExportSelect(), ExportUse(), ShowExportDatabases(), ShowColumnCounts(),
103
+ DropExportDatabase(), DropExportDatabases(),
104
+ ShowExportSessions(), ShowExportSession(),
105
+ CleanUpExportSessions(), CleanUpAllExportSessions(), ImportSession()] + \
106
+ Medusa().cmd_list() + [Restart(), RollOut(), Watch()] + Reaper().cmd_list() + Repair().cmd_list()
91
107
 
92
108
  def postgres_ops() -> list[Command]:
93
- return [Postgres(), DeployPgAgent(), UndeployPgAgent()]
109
+ return [Postgres(), DeployPgAgent(), UndeployPgAgent(), PostgresPg()]
94
110
 
95
111
  def app_ops() -> list[Command]:
96
112
  return [ShowAppActions(), ShowAppId(), ShowAppQueues(), AppPing(), App()]
97
113
 
98
114
  def audit_ops() -> list[Command]:
99
- return [Audit()] + Audit.cmd_list()
115
+ return [Audit()] + Audit().cmd_list()
100
116
 
101
117
  def export_ops() -> list[Command]:
102
- return [ExportUseX(), ExportSelectX()]
118
+ return [ExportSelectX(), DropExportDatabase(), DropExportDatabases(), ShowColumnCounts()]
103
119
 
104
120
  def tools() -> list[Command]:
105
121
  return [Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(), DeployPod(), UndeployPod(), Kubectl(), Code()]