kaqing 1.77.0__py3-none-any.whl → 2.0.171__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.
Files changed (308) hide show
  1. adam/__init__.py +1 -0
  2. adam/app_session.py +182 -0
  3. {walker → adam}/apps.py +8 -24
  4. {walker → adam}/batch.py +54 -97
  5. {walker → adam}/checks/check.py +3 -3
  6. {walker → adam}/checks/check_result.py +1 -1
  7. adam/checks/check_utils.py +65 -0
  8. {walker → adam}/checks/compactionstats.py +6 -6
  9. {walker → adam}/checks/cpu.py +14 -8
  10. adam/checks/cpu_metrics.py +52 -0
  11. {walker → adam}/checks/disk.py +6 -6
  12. {walker → adam}/checks/gossip.py +5 -5
  13. {walker → adam}/checks/memory.py +7 -7
  14. {walker → adam}/checks/status.py +5 -5
  15. {walker → adam}/cli.py +3 -3
  16. {walker → adam}/columns/column.py +1 -1
  17. adam/columns/columns.py +45 -0
  18. {walker → adam}/columns/compactions.py +5 -5
  19. {walker → adam}/columns/cpu.py +6 -4
  20. adam/columns/cpu_metrics.py +22 -0
  21. {walker → adam}/columns/dir_data.py +3 -3
  22. {walker → adam}/columns/dir_snapshots.py +3 -3
  23. {walker → adam}/columns/gossip.py +5 -5
  24. {walker → adam}/columns/host_id.py +3 -3
  25. {walker → adam}/columns/memory.py +3 -3
  26. {walker → adam}/columns/node_address.py +3 -3
  27. {walker → adam}/columns/node_load.py +3 -3
  28. {walker → adam}/columns/node_owns.py +3 -3
  29. {walker → adam}/columns/node_status.py +3 -3
  30. {walker → adam}/columns/node_tokens.py +3 -3
  31. {walker → adam}/columns/node_utils.py +2 -2
  32. {walker → adam}/columns/pod_name.py +2 -2
  33. {walker → adam}/columns/volume_cassandra.py +4 -4
  34. {walker → adam}/columns/volume_root.py +3 -3
  35. adam/commands/__init__.py +15 -0
  36. adam/commands/alter_tables.py +81 -0
  37. adam/commands/app_cmd.py +38 -0
  38. {walker → adam}/commands/app_ping.py +10 -16
  39. adam/commands/audit/audit.py +84 -0
  40. adam/commands/audit/audit_repair_tables.py +74 -0
  41. adam/commands/audit/audit_run.py +50 -0
  42. adam/commands/audit/show_last10.py +48 -0
  43. adam/commands/audit/show_slow10.py +47 -0
  44. adam/commands/audit/show_top10.py +45 -0
  45. adam/commands/audit/utils_show_top10.py +59 -0
  46. adam/commands/bash/__init__.py +5 -0
  47. adam/commands/bash/bash.py +36 -0
  48. adam/commands/bash/bash_completer.py +93 -0
  49. adam/commands/bash/utils_bash.py +16 -0
  50. adam/commands/cat.py +50 -0
  51. adam/commands/cd.py +43 -0
  52. adam/commands/check.py +73 -0
  53. {walker → adam}/commands/cli_commands.py +7 -8
  54. adam/commands/code.py +57 -0
  55. adam/commands/command.py +190 -0
  56. {walker → adam}/commands/command_helpers.py +1 -1
  57. {walker → adam}/commands/commands_utils.py +15 -25
  58. adam/commands/cp.py +89 -0
  59. adam/commands/cql/cql_completions.py +33 -0
  60. {walker/commands → adam/commands/cql}/cqlsh.py +20 -35
  61. adam/commands/cql/utils_cql.py +343 -0
  62. {walker/commands/frontend → adam/commands/deploy}/code_start.py +11 -14
  63. adam/commands/deploy/code_stop.py +40 -0
  64. {walker/commands/frontend → adam/commands/deploy}/code_utils.py +7 -9
  65. adam/commands/deploy/deploy.py +25 -0
  66. adam/commands/deploy/deploy_frontend.py +49 -0
  67. adam/commands/deploy/deploy_pg_agent.py +35 -0
  68. adam/commands/deploy/deploy_pod.py +108 -0
  69. adam/commands/deploy/deploy_utils.py +29 -0
  70. adam/commands/deploy/undeploy.py +25 -0
  71. adam/commands/deploy/undeploy_frontend.py +38 -0
  72. adam/commands/deploy/undeploy_pg_agent.py +39 -0
  73. adam/commands/deploy/undeploy_pod.py +48 -0
  74. adam/commands/devices/device.py +118 -0
  75. adam/commands/devices/device_app.py +173 -0
  76. adam/commands/devices/device_auit_log.py +49 -0
  77. adam/commands/devices/device_cass.py +185 -0
  78. adam/commands/devices/device_export.py +86 -0
  79. adam/commands/devices/device_postgres.py +144 -0
  80. adam/commands/devices/devices.py +25 -0
  81. {walker → adam}/commands/exit.py +3 -6
  82. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  83. adam/commands/export/clean_up_export_sessions.py +51 -0
  84. adam/commands/export/drop_export_database.py +55 -0
  85. adam/commands/export/drop_export_databases.py +43 -0
  86. adam/commands/export/export.py +53 -0
  87. adam/commands/export/export_databases.py +170 -0
  88. adam/commands/export/export_handlers.py +71 -0
  89. adam/commands/export/export_select.py +81 -0
  90. adam/commands/export/export_select_x.py +54 -0
  91. adam/commands/export/export_use.py +52 -0
  92. adam/commands/export/exporter.py +352 -0
  93. adam/commands/export/import_session.py +40 -0
  94. adam/commands/export/importer.py +67 -0
  95. adam/commands/export/importer_athena.py +80 -0
  96. adam/commands/export/importer_sqlite.py +47 -0
  97. adam/commands/export/show_column_counts.py +54 -0
  98. adam/commands/export/show_export_databases.py +36 -0
  99. adam/commands/export/show_export_session.py +48 -0
  100. adam/commands/export/show_export_sessions.py +44 -0
  101. adam/commands/export/utils_export.py +314 -0
  102. {walker → adam}/commands/help.py +17 -12
  103. adam/commands/intermediate_command.py +49 -0
  104. adam/commands/issues.py +43 -0
  105. adam/commands/kubectl.py +38 -0
  106. adam/commands/login.py +70 -0
  107. {walker → adam}/commands/logs.py +8 -10
  108. adam/commands/ls.py +41 -0
  109. adam/commands/medusa/medusa.py +27 -0
  110. adam/commands/medusa/medusa_backup.py +57 -0
  111. adam/commands/medusa/medusa_restore.py +83 -0
  112. adam/commands/medusa/medusa_show_backupjobs.py +51 -0
  113. adam/commands/medusa/medusa_show_restorejobs.py +47 -0
  114. {walker → adam}/commands/nodetool.py +17 -21
  115. {walker → adam}/commands/param_get.py +15 -16
  116. adam/commands/param_set.py +43 -0
  117. adam/commands/postgres/postgres.py +104 -0
  118. adam/commands/postgres/postgres_context.py +274 -0
  119. {walker → adam}/commands/postgres/postgres_ls.py +7 -11
  120. {walker → adam}/commands/postgres/postgres_preview.py +8 -13
  121. adam/commands/postgres/psql_completions.py +10 -0
  122. adam/commands/postgres/utils_postgres.py +66 -0
  123. adam/commands/preview_table.py +37 -0
  124. adam/commands/pwd.py +47 -0
  125. adam/commands/reaper/reaper.py +35 -0
  126. adam/commands/reaper/reaper_forward.py +93 -0
  127. adam/commands/reaper/reaper_forward_session.py +6 -0
  128. {walker → adam}/commands/reaper/reaper_forward_stop.py +13 -19
  129. {walker → adam}/commands/reaper/reaper_restart.py +10 -17
  130. adam/commands/reaper/reaper_run_abort.py +46 -0
  131. adam/commands/reaper/reaper_runs.py +82 -0
  132. adam/commands/reaper/reaper_runs_abort.py +63 -0
  133. adam/commands/reaper/reaper_schedule_activate.py +45 -0
  134. adam/commands/reaper/reaper_schedule_start.py +45 -0
  135. adam/commands/reaper/reaper_schedule_stop.py +45 -0
  136. {walker → adam}/commands/reaper/reaper_schedules.py +6 -16
  137. {walker → adam}/commands/reaper/reaper_status.py +11 -19
  138. adam/commands/reaper/utils_reaper.py +196 -0
  139. adam/commands/repair/repair.py +26 -0
  140. {walker → adam}/commands/repair/repair_log.py +7 -10
  141. adam/commands/repair/repair_run.py +70 -0
  142. adam/commands/repair/repair_scan.py +71 -0
  143. {walker → adam}/commands/repair/repair_stop.py +8 -11
  144. adam/commands/report.py +61 -0
  145. adam/commands/restart.py +60 -0
  146. {walker → adam}/commands/rollout.py +25 -30
  147. adam/commands/shell.py +34 -0
  148. adam/commands/show/show.py +39 -0
  149. walker/commands/show/show_version.py → adam/commands/show/show_adam.py +14 -10
  150. adam/commands/show/show_app_actions.py +57 -0
  151. {walker → adam}/commands/show/show_app_id.py +12 -15
  152. {walker → adam}/commands/show/show_app_queues.py +9 -12
  153. adam/commands/show/show_cassandra_repairs.py +38 -0
  154. adam/commands/show/show_cassandra_status.py +124 -0
  155. {walker → adam}/commands/show/show_cassandra_version.py +6 -16
  156. adam/commands/show/show_commands.py +59 -0
  157. walker/commands/show/show_storage.py → adam/commands/show/show_host.py +11 -13
  158. adam/commands/show/show_login.py +62 -0
  159. {walker → adam}/commands/show/show_params.py +4 -4
  160. adam/commands/show/show_processes.py +51 -0
  161. adam/commands/show/show_storage.py +42 -0
  162. adam/commands/watch.py +82 -0
  163. {walker → adam}/config.py +10 -22
  164. {walker → adam}/embedded_apps.py +1 -1
  165. adam/embedded_params.py +2 -0
  166. adam/log.py +47 -0
  167. {walker → adam}/pod_exec_result.py +10 -2
  168. adam/repl.py +182 -0
  169. adam/repl_commands.py +124 -0
  170. adam/repl_state.py +458 -0
  171. adam/sql/__init__.py +0 -0
  172. adam/sql/sql_completer.py +120 -0
  173. adam/sql/sql_state_machine.py +618 -0
  174. adam/sql/term_completer.py +76 -0
  175. adam/sso/__init__.py +0 -0
  176. {walker → adam}/sso/authenticator.py +5 -1
  177. adam/sso/authn_ad.py +170 -0
  178. {walker → adam}/sso/authn_okta.py +39 -22
  179. adam/sso/cred_cache.py +60 -0
  180. adam/sso/id_token.py +23 -0
  181. adam/sso/idp.py +143 -0
  182. adam/sso/idp_login.py +50 -0
  183. adam/sso/idp_session.py +55 -0
  184. adam/sso/sso_config.py +63 -0
  185. adam/utils.py +679 -0
  186. adam/utils_app.py +98 -0
  187. adam/utils_athena.py +145 -0
  188. adam/utils_audits.py +106 -0
  189. adam/utils_issues.py +32 -0
  190. adam/utils_k8s/__init__.py +0 -0
  191. adam/utils_k8s/app_clusters.py +28 -0
  192. adam/utils_k8s/app_pods.py +33 -0
  193. adam/utils_k8s/cassandra_clusters.py +36 -0
  194. adam/utils_k8s/cassandra_nodes.py +33 -0
  195. adam/utils_k8s/config_maps.py +34 -0
  196. {walker/k8s_utils → adam/utils_k8s}/custom_resources.py +7 -2
  197. adam/utils_k8s/deployment.py +56 -0
  198. {walker/k8s_utils → adam/utils_k8s}/ingresses.py +3 -4
  199. {walker/k8s_utils → adam/utils_k8s}/jobs.py +3 -3
  200. adam/utils_k8s/k8s.py +87 -0
  201. {walker/k8s_utils → adam/utils_k8s}/kube_context.py +4 -4
  202. adam/utils_k8s/pods.py +290 -0
  203. {walker/k8s_utils → adam/utils_k8s}/secrets.py +8 -4
  204. adam/utils_k8s/service_accounts.py +170 -0
  205. {walker/k8s_utils → adam/utils_k8s}/services.py +3 -4
  206. {walker/k8s_utils → adam/utils_k8s}/statefulsets.py +6 -16
  207. {walker/k8s_utils → adam/utils_k8s}/volumes.py +10 -1
  208. adam/utils_net.py +24 -0
  209. adam/utils_repl/__init__.py +0 -0
  210. adam/utils_repl/automata_completer.py +48 -0
  211. adam/utils_repl/repl_completer.py +46 -0
  212. adam/utils_repl/state_machine.py +173 -0
  213. adam/utils_sqlite.py +109 -0
  214. adam/version.py +5 -0
  215. {kaqing-1.77.0.dist-info → kaqing-2.0.171.dist-info}/METADATA +1 -1
  216. kaqing-2.0.171.dist-info/RECORD +236 -0
  217. kaqing-2.0.171.dist-info/entry_points.txt +3 -0
  218. kaqing-2.0.171.dist-info/top_level.txt +1 -0
  219. kaqing-1.77.0.dist-info/RECORD +0 -159
  220. kaqing-1.77.0.dist-info/entry_points.txt +0 -3
  221. kaqing-1.77.0.dist-info/top_level.txt +0 -1
  222. walker/__init__.py +0 -3
  223. walker/app_session.py +0 -168
  224. walker/checks/check_utils.py +0 -97
  225. walker/columns/columns.py +0 -43
  226. walker/commands/add_user.py +0 -68
  227. walker/commands/app.py +0 -67
  228. walker/commands/bash.py +0 -87
  229. walker/commands/cd.py +0 -115
  230. walker/commands/check.py +0 -68
  231. walker/commands/command.py +0 -104
  232. walker/commands/cp.py +0 -95
  233. walker/commands/cql_utils.py +0 -53
  234. walker/commands/devices.py +0 -89
  235. walker/commands/frontend/code_stop.py +0 -57
  236. walker/commands/frontend/setup.py +0 -60
  237. walker/commands/frontend/setup_frontend.py +0 -58
  238. walker/commands/frontend/teardown.py +0 -61
  239. walker/commands/frontend/teardown_frontend.py +0 -42
  240. walker/commands/issues.py +0 -69
  241. walker/commands/login.py +0 -72
  242. walker/commands/ls.py +0 -145
  243. walker/commands/medusa/medusa.py +0 -69
  244. walker/commands/medusa/medusa_backup.py +0 -61
  245. walker/commands/medusa/medusa_restore.py +0 -86
  246. walker/commands/medusa/medusa_show_backupjobs.py +0 -52
  247. walker/commands/medusa/medusa_show_restorejobs.py +0 -52
  248. walker/commands/param_set.py +0 -44
  249. walker/commands/postgres/postgres.py +0 -113
  250. walker/commands/postgres/postgres_session.py +0 -225
  251. walker/commands/preview_table.py +0 -98
  252. walker/commands/processes.py +0 -53
  253. walker/commands/pwd.py +0 -64
  254. walker/commands/reaper/reaper.py +0 -78
  255. walker/commands/reaper/reaper_forward.py +0 -100
  256. walker/commands/reaper/reaper_run_abort.py +0 -65
  257. walker/commands/reaper/reaper_runs.py +0 -97
  258. walker/commands/reaper/reaper_runs_abort.py +0 -83
  259. walker/commands/reaper/reaper_schedule_activate.py +0 -64
  260. walker/commands/reaper/reaper_schedule_start.py +0 -64
  261. walker/commands/reaper/reaper_schedule_stop.py +0 -64
  262. walker/commands/reaper/reaper_session.py +0 -159
  263. walker/commands/repair/repair.py +0 -68
  264. walker/commands/repair/repair_run.py +0 -72
  265. walker/commands/repair/repair_scan.py +0 -79
  266. walker/commands/report.py +0 -57
  267. walker/commands/restart.py +0 -61
  268. walker/commands/show/show.py +0 -72
  269. walker/commands/show/show_app_actions.py +0 -53
  270. walker/commands/show/show_cassandra_status.py +0 -35
  271. walker/commands/show/show_commands.py +0 -58
  272. walker/commands/show/show_processes.py +0 -35
  273. walker/commands/show/show_repairs.py +0 -47
  274. walker/commands/status.py +0 -128
  275. walker/commands/storage.py +0 -52
  276. walker/commands/user_entry.py +0 -69
  277. walker/commands/watch.py +0 -85
  278. walker/embedded_params.py +0 -2
  279. walker/k8s_utils/cassandra_clusters.py +0 -48
  280. walker/k8s_utils/cassandra_nodes.py +0 -26
  281. walker/k8s_utils/pods.py +0 -211
  282. walker/repl.py +0 -165
  283. walker/repl_commands.py +0 -58
  284. walker/repl_state.py +0 -211
  285. walker/sso/authn_ad.py +0 -94
  286. walker/sso/idp.py +0 -150
  287. walker/sso/idp_login.py +0 -29
  288. walker/sso/sso_config.py +0 -45
  289. walker/utils.py +0 -194
  290. walker/version.py +0 -5
  291. {walker → adam}/checks/__init__.py +0 -0
  292. {walker → adam}/checks/check_context.py +0 -0
  293. {walker → adam}/checks/issue.py +0 -0
  294. {walker → adam}/cli_group.py +0 -0
  295. {walker → adam}/columns/__init__.py +0 -0
  296. {walker/commands → adam/commands/audit}/__init__.py +0 -0
  297. {walker/commands/frontend → adam/commands/cql}/__init__.py +0 -0
  298. {walker/commands/medusa → adam/commands/deploy}/__init__.py +0 -0
  299. {walker/commands/postgres → adam/commands/devices}/__init__.py +0 -0
  300. {walker/commands/reaper → adam/commands/export}/__init__.py +0 -0
  301. {walker/commands/repair → adam/commands/medusa}/__init__.py +0 -0
  302. {walker → adam}/commands/nodetool_commands.py +0 -0
  303. {walker/commands/show → adam/commands/postgres}/__init__.py +0 -0
  304. {walker/k8s_utils → adam/commands/reaper}/__init__.py +0 -0
  305. {walker/sso → adam/commands/repair}/__init__.py +0 -0
  306. /walker/medusa_show_restorejobs.py → /adam/commands/show/__init__.py +0 -0
  307. {walker → adam}/repl_session.py +0 -0
  308. {kaqing-1.77.0.dist-info → kaqing-2.0.171.dist-info}/WHEEL +0 -0
@@ -1,69 +0,0 @@
1
- import os
2
- import signal
3
- import traceback
4
-
5
- from walker.sso.idp import Idp
6
- from walker.app_session import AppSession, IdpLogin
7
- from walker.apps import Apps
8
- from walker.commands.command import Command
9
- from walker.repl_state import ReplState
10
- from walker.utils import log2
11
-
12
- class UserEntry(Command):
13
- COMMAND = 'entry'
14
-
15
- # the singleton pattern
16
- def __new__(cls, *args, **kwargs):
17
- if not hasattr(cls, 'instance'): cls.instance = super(UserEntry, cls).__new__(cls)
18
-
19
- return cls.instance
20
-
21
- def __init__(self, successor: Command=None):
22
- super().__init__(successor)
23
-
24
- def command(self):
25
- return UserEntry.COMMAND
26
-
27
- def run(self, cmd: str, state: ReplState):
28
- def custom_handler(signum, frame):
29
- AppSession.ctrl_c_entered = True
30
-
31
- signal.signal(signal.SIGINT, custom_handler)
32
-
33
- if not(args := self.args(cmd)):
34
- return super().run(cmd, state)
35
-
36
- state, args = self.apply_state(args, state)
37
-
38
- username: str = None
39
- if len(args) > 0:
40
- username = args[0]
41
-
42
- login: IdpLogin = None
43
- while not login:
44
- try:
45
- if not(host := Apps.app_host('c3', 'c3', state.namespace)):
46
- log2('Cannot locate ingress for app.')
47
- username = None
48
- continue
49
-
50
- if not (login := Idp.login(host, username=username, use_cached=False)):
51
- log2('Invalid username/password. Please try again.')
52
- username = None
53
- except:
54
- # log2(traceback.format_exc())
55
- pass
56
-
57
- sh = f'{os.getcwd()}/login.sh'
58
- if not os.path.exists(sh):
59
- sh = f'{os.getcwd()}/docker/login.sh'
60
-
61
- os.system(f'{sh} {login.shell_user()} {login.ser()}')
62
-
63
- return state
64
-
65
- def completion(self, _: ReplState):
66
- return {}
67
-
68
- def help(self, _: ReplState):
69
- return f'{UserEntry.COMMAND}\t ttyd user entry'
walker/commands/watch.py DELETED
@@ -1,85 +0,0 @@
1
- import threading
2
- import time
3
- from kubernetes import client
4
- from typing import List
5
-
6
- from walker.commands.command import Command
7
- from walker.commands.commands_utils import show_pods, show_rollout
8
- from walker.config import Config
9
- from walker.k8s_utils.statefulsets import StatefulSets
10
- from walker.repl_state import ReplState, RequiredState
11
- from walker.utils import convert_seconds, log2
12
-
13
- class Watch(Command):
14
- COMMAND = 'watch'
15
-
16
- # the singleton pattern
17
- def __new__(cls, *args, **kwargs):
18
- if not hasattr(cls, 'instance'): cls.instance = super(Watch, cls).__new__(cls)
19
-
20
- return cls.instance
21
-
22
- def __init__(self, successor: Command=None):
23
- super().__init__(successor)
24
-
25
- def command(self):
26
- return Watch.COMMAND
27
-
28
- def required(self):
29
- return RequiredState.CLUSTER_OR_POD
30
-
31
- def run(self, cmd: str, state: ReplState):
32
- if not(args := self.args(cmd)):
33
- return super().run(cmd, state)
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
43
-
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()
47
-
48
- try:
49
- log2(f"Press Ctrl+C to break.")
50
-
51
- time.sleep(Config().get('watch.timeout', 3600 * 1))
52
- except KeyboardInterrupt:
53
- pass
54
-
55
- log2("Stopping watch...")
56
- stop_event.set()
57
- thread.join()
58
-
59
- return state
60
-
61
- def loop(self, stop_flag: threading.Event, sts: str, pods: List[client.V1Pod], ns: str):
62
- show_pods(pods, ns)
63
- show_rollout(sts, ns)
64
-
65
- cnt = Config().get('watch.interval', 10)
66
- while not stop_flag.is_set():
67
- time.sleep(1)
68
- cnt -= 1
69
-
70
- if not cnt:
71
- show_pods(pods, ns)
72
- show_rollout(sts, ns)
73
- cnt = Config().get('watch.interval', 10)
74
-
75
- def completion(self, state: ReplState):
76
- if state.pod:
77
- return {}
78
-
79
- if not state.sts:
80
- return {Watch.COMMAND: {n: None for n in StatefulSets.list_sts_names()}}
81
-
82
- return {Watch.COMMAND: None}
83
-
84
- def help(self, _: ReplState):
85
- return f'{Watch.COMMAND}\t watch pod changes'
walker/embedded_params.py DELETED
@@ -1,2 +0,0 @@
1
- def params():
2
- return {'app': {'console-endpoint': 'https://{host}/{env}/{app}/static/console/index.html', '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, 'url': 'https://{host}/{env}/{app}'}, 'strip': '0'}, 'bash': {'workers': 32}, 'cassandra': {'service-name': 'all-pods-service'}, 'cql': {'workers': 32, 'samples': 3, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-superuser', 'password-item': 'password'}}, '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'}, 'okta': {'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'}}, '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': {'image': 'seanahnsf/kaqing', 'name': 'kaqing-agent', 'timeout': 86400}, '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'}}, '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.13', 'secret': 'ciregistryc3iotio', 'env': {'interval': 24, 'timeout': 60, 'pr': False, 'runs': 1}}, 'repl': {'start-drive': 'a', 'auto-enter-app': 'c3/c3', 'auto-enter-only-cluster': 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': {'timings': False, 'exit-on-error': False, 'show-parallelism': False, 'show-out': False}}
@@ -1,48 +0,0 @@
1
- from collections.abc import Callable
2
- from concurrent.futures import ThreadPoolExecutor
3
- import sys
4
- from typing import TypeVar
5
-
6
- from walker.k8s_utils.cassandra_nodes import CassandraNodes
7
- from walker.pod_exec_result import PodExecResult
8
- from walker.utils import log2
9
- from .statefulsets import StatefulSets
10
- from .pods import Pods
11
- from .kube_context import KubeContext
12
-
13
- T = TypeVar('T')
14
-
15
- # utility collection on cassandra clusters; methods are all static
16
- class CassandraClusters:
17
- def exec(statefulset: str, namespace: str, command: str, action: str = 'action', max_workers=0, show_out=True) -> list[PodExecResult]:
18
- def body(executor: ThreadPoolExecutor, pod: str, namespace: str, show_out: bool):
19
- if executor:
20
- return executor.submit(CassandraNodes.exec, pod, namespace, command, False, False,)
21
-
22
- return CassandraNodes.exec(pod, namespace, command, show_out=show_out)
23
-
24
- def post(result, show_out: bool):
25
- if KubeContext.show_out(show_out):
26
- print(result.command)
27
- if result.stdout:
28
- print(result.stdout)
29
- if result.stderr:
30
- log2(result.stderr, file=sys.stderr)
31
-
32
- return result
33
-
34
- return StatefulSets.on_cluster(statefulset, namespace, body, post=post, action=action, max_workers=max_workers, show_out=show_out)
35
-
36
- def on_cluster(statefulset: str,
37
- namespace: str,
38
- body: Callable[[ThreadPoolExecutor, str, str, bool], T],
39
- post: Callable[[T], T] = None,
40
- action: str = 'action', max_workers=0, show_out=True) -> list[T]:
41
- pods = StatefulSets.pod_names(statefulset, namespace)
42
-
43
- return Pods.on_pods(pods, namespace, body, post=post, action=action, max_workers=max_workers, show_out=show_out)
44
-
45
- def pod_names_by_host_id(ss: str, ns: str):
46
- pods = StatefulSets.pods(ss, ns)
47
-
48
- return {CassandraNodes.get_host_id(pod.metadata.name, ns): pod.metadata.name for pod in pods}
@@ -1,26 +0,0 @@
1
- from walker.config import Config
2
- from walker.k8s_utils.pods import Pods
3
- from walker.k8s_utils.secrets import Secrets
4
- from walker.pod_exec_result import PodExecResult
5
-
6
- # utility collection on cassandra nodes; methods are all static
7
- class CassandraNodes:
8
- def exec(pod_name: str, namespace: str, command: str, show_out = True, throw_err = False) -> PodExecResult:
9
- return Pods.exec(pod_name, "cassandra", namespace, command, show_out, throw_err)
10
-
11
- def get_host_id(pod_name: str, ns: str):
12
- try:
13
- user, pw = Secrets.get_user_pass(pod_name, ns)
14
- command = f'echo "SELECT host_id FROM system.local; exit" | cqlsh --no-color -u {user} -p {pw}'
15
- result: PodExecResult = CassandraNodes.exec(pod_name, ns, command, show_out=Config().get('debug.trace', False))
16
- next = False
17
- for line in result.stdout.splitlines():
18
- if next:
19
- return line.strip(' ')
20
- if line.startswith('----------'):
21
- next = True
22
- continue
23
- except Exception as e:
24
- return str(e)
25
-
26
- return 'Unknown'
walker/k8s_utils/pods.py DELETED
@@ -1,211 +0,0 @@
1
- from collections.abc import Callable
2
- from concurrent.futures import ThreadPoolExecutor, as_completed
3
- import sys
4
- import time
5
- from typing import TypeVar, cast
6
- from kubernetes import client
7
- from kubernetes.stream import stream
8
- from kubernetes.stream.ws_client import ERROR_CHANNEL
9
-
10
- from walker.config import Config
11
- from walker.pod_exec_result import PodExecResult
12
- from walker.utils import elapsed_time, log2
13
- from .kube_context import KubeContext
14
-
15
- T = TypeVar('T')
16
- _TEST_POD_EXEC_OUTS: PodExecResult = None
17
-
18
- # utility collection on pods; methods are all static
19
- class Pods:
20
- def set_test_pod_exec_outs(outs: PodExecResult):
21
- global _TEST_POD_EXEC_OUTS
22
- _TEST_POD_EXEC_OUTS = outs
23
-
24
- return _TEST_POD_EXEC_OUTS
25
-
26
- def delete(pod_name: str, namespace: str):
27
- try:
28
- v1 = client.CoreV1Api()
29
- api_response = v1.delete_namespaced_pod(pod_name, namespace)
30
- except Exception as e:
31
- log2("Exception when calling CoreV1Api->delete_namespaced_pod: %s\n" % e)
32
-
33
- def on_pods(pods: list[str],
34
- namespace: str,
35
- body: Callable[[ThreadPoolExecutor, str, str, bool], T],
36
- post: Callable[[T], T] = None,
37
- action: str = 'action', max_workers=0, show_out=True) -> list[T]:
38
- show_out = KubeContext.show_out(show_out)
39
-
40
- if not max_workers:
41
- max_workers = Config().action_workers(action, 0)
42
- if max_workers > 0:
43
- # if parallel, node sampling is suppressed
44
- if KubeContext.show_parallelism():
45
- log2(f'Executing on all nodes from statefulset in parallel...')
46
- start_time = time.time()
47
- try:
48
- with ThreadPoolExecutor(max_workers=max_workers) as executor:
49
- # disable stdout from the pod_exec, then show the output in a for loop
50
- futures = [body(executor, pod, namespace, show_out) for pod in pods]
51
- if len(futures) == 0:
52
- return cast(list[T], [])
53
-
54
- rs = [future.result() for future in as_completed(futures)]
55
- if post:
56
- rs = [post(r, show_out=show_out) for r in rs]
57
-
58
- return rs
59
- finally:
60
- if KubeContext.show_parallelism():
61
- log2(f"Parallel {action} elapsed time: {elapsed_time(start_time)} with {max_workers} workers")
62
- else:
63
- results: list[T] = []
64
-
65
- samples = Config().action_node_samples(action, sys.maxsize)
66
- l = min(len(pods), samples)
67
- adj = 'all'
68
- if l < len(pods):
69
- adj = f'{l} sample'
70
- if show_out:
71
- log2(f'Executing on {adj} nodes from statefulset...')
72
- for pod_name in pods:
73
- try:
74
- result = body(None, pod_name, namespace, show_out)
75
- if post:
76
- result = post(result, show_out=show_out)
77
- results.append(result)
78
- if result:
79
- l -= 1
80
- if not l:
81
- break
82
- except Exception as e:
83
- log2(e)
84
-
85
- return results
86
-
87
- def exec(pod_name: str, container: str, namespace: str, command: str, show_out = True, throw_err = False, interaction: Callable[[any, list[str]], any] = None):
88
- if _TEST_POD_EXEC_OUTS:
89
- return _TEST_POD_EXEC_OUTS
90
-
91
- show_out = KubeContext.show_out(show_out)
92
-
93
- api = client.CoreV1Api()
94
-
95
- exec_command = ["/bin/sh", "-c", command]
96
- k_command = f'kubectl exec {pod_name} -c {container} -n {namespace} -- {command}'
97
- if show_out:
98
- print(k_command)
99
-
100
- resp = stream(
101
- api.connect_get_namespaced_pod_exec,
102
- pod_name,
103
- namespace,
104
- command=exec_command,
105
- container=container,
106
- stderr=True,
107
- stdin=True,
108
- stdout=True,
109
- tty=True,
110
- _preload_content=False,
111
- )
112
-
113
- stdout = []
114
- stderr = []
115
- error_output = None
116
- try:
117
- while resp.is_open():
118
- resp.update(timeout=1)
119
- if resp.peek_stdout():
120
- frag = resp.read_stdout()
121
- stdout.append(frag)
122
- if show_out: print(frag, end="")
123
-
124
- if interaction:
125
- interaction(resp, stdout)
126
- if resp.peek_stderr():
127
- frag = resp.read_stderr()
128
- stderr.append(frag)
129
- if show_out: print(frag, end="")
130
-
131
- try:
132
- # get the exit code from server
133
- error_output = resp.read_channel(ERROR_CHANNEL)
134
- except Exception:
135
- pass
136
- except Exception as e:
137
- if throw_err:
138
- raise e
139
- else:
140
- log2(e)
141
- finally:
142
- resp.close()
143
-
144
- return PodExecResult("".join(stdout), "".join(stderr), k_command, error_output)
145
-
146
- def get_container(namespace: str, pod_name: str, container_name: str):
147
- pod = Pods.get(namespace, pod_name)
148
- if not pod:
149
- return None
150
-
151
- for container in pod.spec.containers:
152
- if container_name == container.name:
153
- return container
154
-
155
- return None
156
-
157
- def get(namespace: str, pod_name: str):
158
- v1 = client.CoreV1Api()
159
- return v1.read_namespaced_pod(name=pod_name, namespace=namespace)
160
-
161
- def create_pod_spec(name: str, image: str, image_pull_secret: str, envs: list, volume_name: str, pvc_name:str, mount_path:str, command: list[str]=None, sa_name=None):
162
- volume_mounts = []
163
- if volume_name and pvc_name and mount_path:
164
- volume_mounts=[client.V1VolumeMount(mount_path=mount_path, name=volume_name)]
165
-
166
- container = client.V1Container(name=name, image=image, env=envs, command=command,
167
- volume_mounts=volume_mounts)
168
-
169
- volumes = []
170
- if volume_name and pvc_name and mount_path:
171
- volumes=[client.V1Volume(name=volume_name, persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(claim_name=pvc_name))]
172
-
173
- security_context = None
174
- if not sa_name:
175
- security_context=client.V1PodSecurityContext(run_as_user=1001, run_as_group=1001, fs_group=1001)
176
-
177
- return client.V1PodSpec(
178
- restart_policy="Never",
179
- containers=[container],
180
- image_pull_secrets=[client.V1LocalObjectReference(name=image_pull_secret)],
181
- security_context=security_context,
182
- service_account_name=sa_name,
183
- volumes=volumes
184
- )
185
-
186
- def create(namespace: str, pod_name: str, image: str, command: list[str],
187
- secret: str = None,
188
- env: dict[str, any] = {},
189
- volume_name: str = None,
190
- pvc_name: str = None,
191
- mount_path: str = None,
192
- sa_name=None):
193
- v1 = client.CoreV1Api()
194
- envs = []
195
- for k, v in env.items():
196
- envs.append(client.V1EnvVar(name=str(k), value=str(v)))
197
- pod = Pods.create_pod_spec(pod_name, image, secret, envs, volume_name, pvc_name, mount_path, command=command, sa_name=sa_name)
198
- return v1.create_namespaced_pod(namespace=namespace,
199
- body=client.V1Pod(spec=pod, metadata=client.V1ObjectMeta(name=pod_name)))
200
-
201
- def wait_for_running(namespace: str, pod_name: str):
202
- msged = False
203
-
204
- while Pods.get(namespace, pod_name).status.phase != 'Running':
205
- if not msged:
206
- log2(f'Waiting for the {pod_name} pod to start up...')
207
- msged = True
208
- time.sleep(5)
209
-
210
- def completed(namespace: str, pod_name: str):
211
- return Pods.get(namespace, pod_name).status.phase in ['Succeeded', 'Failed']
walker/repl.py DELETED
@@ -1,165 +0,0 @@
1
- import re
2
- import time
3
- import traceback
4
- import click
5
- from prompt_toolkit.completion import NestedCompleter
6
- from prompt_toolkit.key_binding import KeyBindings
7
-
8
- from walker.cli_group import cli
9
- from walker.commands.command import Command
10
- from walker.commands.command_helpers import ClusterCommandHelper
11
- from walker.commands.help import Help
12
- from walker.commands.postgres.postgres_session import PostgresSession
13
- from walker.config import Config
14
- from walker.k8s_utils.kube_context import KubeContext
15
- from walker.k8s_utils.statefulsets import StatefulSets
16
- from walker.repl_commands import ReplCommands
17
- from walker.repl_session import ReplSession
18
- from walker.repl_state import ReplState
19
- from walker.utils import deep_merge_dicts, lines_to_tabular, log2
20
- from walker.apps import Apps
21
- from . import __version__
22
-
23
- def enter_repl(state: ReplState):
24
- cmd_list = ReplCommands.repl_cmd_list() + [Help()]
25
- # head with the Chain of Responsibility pattern
26
- cmds: Command = Command.chain(cmd_list)
27
- session = ReplSession().prompt_session
28
-
29
- def prompt_msg():
30
- msg = ''
31
- if state.device == ReplState.P:
32
- msg = f'{ReplState.P}:'
33
- pg = PostgresSession(state.namespace, state.pg_path) if state.pg_path else None
34
- if pg and pg.db:
35
- msg += pg.db
36
- elif pg and pg.host:
37
- msg += pg.host
38
- elif state.device == ReplState.A:
39
- msg = f'{ReplState.A}:'
40
- if state.app_env:
41
- msg += state.app_env
42
- if state.app_app:
43
- msg += f'/{state.app_app}'
44
- else:
45
- msg = f'{ReplState.C}:'
46
- if state.pod:
47
- # cs-d0767a536f-cs-d0767a536f-default-sts-0
48
- group = re.match(r".*?-.*?-(.*)", state.pod)
49
- msg += group[1]
50
- elif state.sts:
51
- # cs-d0767a536f-cs-d0767a536f-default-sts
52
- group = re.match(r".*?-.*?-(.*)", state.sts)
53
- msg += group[1]
54
-
55
- return f"{msg}$ " if state.bash_session else f"{msg}> "
56
-
57
- log2(f'kaqing {__version__}')
58
- ss = StatefulSets.list_sts_name_and_ns()
59
-
60
- if state.device == ReplState.C:
61
- if not ss:
62
- raise Exception("no Cassandra clusters found")
63
- elif len(ss) == 1 and Config().get('repl.auto-enter-only-cluster', True):
64
- cluster = ss[0]
65
- state.sts = cluster[0]
66
- state.namespace = cluster[1]
67
- state.wait_log(f'Moving to the only Cassandra cluster: {state.sts}@{state.namespace}...')
68
- elif state.device == ReplState.A:
69
- if app := Config().get('repl.auto-enter-app', 'c3/c3'):
70
- if app != 'no':
71
- ea = app.split('/')
72
- state.app_env = ea[0]
73
- if len(ea) > 1:
74
- state.app_app = ea[1]
75
- state.wait_log(f'Moving to {state.app_env}/{state.app_app}...')
76
- else:
77
- state.wait_log(f'Moving to {state.app_env}...')
78
-
79
- kb = KeyBindings()
80
-
81
- @kb.add('c-c')
82
- def _(event):
83
- event.app.current_buffer.text = ''
84
-
85
- while True:
86
- try:
87
- completer = NestedCompleter.from_nested_dict({})
88
- if not state.bash_session:
89
- completions = {}
90
- if state.app_app:
91
- completions = Apps(path='apps.yaml').commands()
92
- # completions = {k: None for k in Apps(path='apps.yaml').commands()}
93
-
94
- for cmd in cmd_list:
95
- s1 = time.time()
96
- try:
97
- completions = deep_merge_dicts(completions, cmd.completion(state))
98
- finally:
99
- if Config().get('debug.timings', False):
100
- print('Timing completion calc', cmd.command(), f'{time.time() - s1:.2f}')
101
- pass
102
-
103
- completer = NestedCompleter.from_nested_dict(completions)
104
-
105
- cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
106
- s0 = time.time()
107
-
108
- if state.bash_session:
109
- if cmd.strip(' ') == 'exit':
110
- state.exit_bash()
111
- continue
112
-
113
- cmd = f'bash {cmd}'
114
-
115
- if cmd and cmd.strip(' ') and not cmds.run(cmd, state):
116
- c_sql_tried = False
117
- if state.device == ReplState.P:
118
- pg = PostgresSession(state.namespace, state.pg_path)
119
- if pg.db:
120
- c_sql_tried = True
121
- cmd = f'pg {cmd}'
122
- cmds.run(cmd, state)
123
- elif state.device == ReplState.A:
124
- if state.app_app:
125
- c_sql_tried = True
126
- cmd = f'app {cmd}'
127
- cmds.run(cmd, state)
128
- elif state.sts:
129
- c_sql_tried = True
130
- cmd = f'cql {cmd}'
131
- cmds.run(cmd, state)
132
-
133
- if not c_sql_tried:
134
- log2(f'* Invalid command: {cmd}')
135
- log2()
136
- lines = [c.help(state) for c in cmd_list if c.help(state)]
137
- log2(lines_to_tabular(lines, separator='\t'))
138
- except EOFError: # Handle Ctrl+D (EOF) for graceful exit
139
- break
140
- except Exception as e:
141
- if Config().get('debug.exit-on-error', False):
142
- raise e
143
- else:
144
- # log2(e)
145
- traceback.print_exc()
146
- finally:
147
- state.clear_wait_log_flag()
148
- if Config().get('debug.timings', False) and 'cmd' in locals() and 's0' in locals():
149
- print('Timing command', cmd, f'{time.time() - s0:.2f}')
150
-
151
- @cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=ClusterCommandHelper, help="Enter interactive shell.")
152
- @click.option('--kubeconfig', '-k', required=False, metavar='path', help='path to kubeconfig file')
153
- @click.option('--config', default='params.yaml', metavar='path', help='path to kaqing parameters file')
154
- @click.option('--param', '-v', multiple=True, metavar='<key>=<value>', help='parameter override')
155
- @click.option('--cluster', '-c', required=False, metavar='statefulset', help='Kubernetes statefulset name')
156
- @click.option('--namespace', '-n', required=False, metavar='namespace', help='Kubernetes namespace')
157
- @click.argument('extra_args', nargs=-1, metavar='[cluster]', type=click.UNPROCESSED)
158
- def repl(kubeconfig: str, config: str, param: list[str], cluster:str, namespace: str, extra_args):
159
- KubeContext.init_config(kubeconfig)
160
- if not KubeContext.init_params(config, param):
161
- return
162
-
163
- state = ReplState(device=Config().get('repl.start-drive', 'a'), ns_sts=cluster, namespace=namespace, in_repl=True)
164
- state, _ = state.apply_args(extra_args)
165
- enter_repl(state)
walker/repl_commands.py DELETED
@@ -1,58 +0,0 @@
1
- from walker.commands.app import App
2
- from walker.commands.app_ping import AppPing
3
- from walker.commands.frontend.code_start import CodeStart
4
- from walker.commands.frontend.code_stop import CodeStop
5
- from walker.commands.show.show_app_queues import ShowAppQueues
6
- from walker.commands.cp import ClipboardCopy
7
- from walker.commands.bash import Bash
8
- from walker.commands.cd import Cd
9
- from walker.commands.check import Check
10
- from walker.commands.command import Command
11
- from walker.commands.cqlsh import Cqlsh
12
- from walker.commands.devices import DeviceApp, DeviceCass, DevicePostgres
13
- from walker.commands.exit import Exit
14
- from walker.commands.medusa.medusa import Medusa
15
- from walker.commands.param_get import GetParam
16
- from walker.commands.issues import Issues
17
- from walker.commands.ls import Ls
18
- from walker.commands.nodetool import NodeTool
19
- from walker.commands.postgres.postgres import Postgres
20
- from walker.commands.preview_table import PreviewTable
21
- from walker.commands.processes import Processes
22
- from walker.commands.pwd import Pwd
23
- from walker.commands.reaper.reaper import Reaper
24
- from walker.commands.repair.repair import Repair
25
- from walker.commands.report import Report
26
- from walker.commands.restart import Restart
27
- from walker.commands.rollout import RollOut
28
- from walker.commands.param_set import SetParam
29
- from walker.commands.show.show import Show
30
- from walker.commands.show.show_app_actions import ShowAppActions
31
- from walker.commands.show.show_app_id import ShowAppId
32
- from walker.commands.status import Status
33
- from walker.commands.storage import Storage
34
- from walker.commands.watch import Watch
35
-
36
- class ReplCommands:
37
- def repl_cmd_list() -> list[Command]:
38
- return ReplCommands.app() + [CodeStart(), CodeStop()] + [DeviceApp(), DevicePostgres(), DeviceCass()] + ReplCommands.navigation() + \
39
- ReplCommands.cassandra_check() + ReplCommands.cassandra_ops() + ReplCommands.tools() + ReplCommands.exit()
40
-
41
- def navigation() -> list[Command]:
42
- return [Ls(), PreviewTable(), Cd(), Pwd(), ClipboardCopy(), GetParam(), SetParam()] + Show.cmd_list()
43
-
44
- def cassandra_check() -> list[Command]:
45
- return [Check(), Issues(), NodeTool(), Processes(), Report(), Status(), Storage()]
46
-
47
- def cassandra_ops() -> list[Command]:
48
- return Medusa.cmd_list() + [Restart(), RollOut(), Watch()] + Reaper.cmd_list() + Repair.cmd_list()
49
-
50
- def tools() -> list[Command]:
51
- return [Cqlsh(), Postgres(), Bash()]
52
-
53
- def app() -> list[Command]:
54
- return [ShowAppActions(), ShowAppId(), ShowAppQueues(), AppPing(), App(), ]
55
- # return [C3Echo(), C3IqCount(), C3()]
56
-
57
- def exit() -> list[Command]:
58
- return [Exit()]