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.
- adam/__init__.py +1 -0
- adam/app_session.py +182 -0
- {walker → adam}/apps.py +8 -24
- {walker → adam}/batch.py +54 -97
- {walker → adam}/checks/check.py +3 -3
- {walker → adam}/checks/check_result.py +1 -1
- adam/checks/check_utils.py +65 -0
- {walker → adam}/checks/compactionstats.py +6 -6
- {walker → adam}/checks/cpu.py +14 -8
- adam/checks/cpu_metrics.py +52 -0
- {walker → adam}/checks/disk.py +6 -6
- {walker → adam}/checks/gossip.py +5 -5
- {walker → adam}/checks/memory.py +7 -7
- {walker → adam}/checks/status.py +5 -5
- {walker → adam}/cli.py +3 -3
- {walker → adam}/columns/column.py +1 -1
- adam/columns/columns.py +45 -0
- {walker → adam}/columns/compactions.py +5 -5
- {walker → adam}/columns/cpu.py +6 -4
- adam/columns/cpu_metrics.py +22 -0
- {walker → adam}/columns/dir_data.py +3 -3
- {walker → adam}/columns/dir_snapshots.py +3 -3
- {walker → adam}/columns/gossip.py +5 -5
- {walker → adam}/columns/host_id.py +3 -3
- {walker → adam}/columns/memory.py +3 -3
- {walker → adam}/columns/node_address.py +3 -3
- {walker → adam}/columns/node_load.py +3 -3
- {walker → adam}/columns/node_owns.py +3 -3
- {walker → adam}/columns/node_status.py +3 -3
- {walker → adam}/columns/node_tokens.py +3 -3
- {walker → adam}/columns/node_utils.py +2 -2
- {walker → adam}/columns/pod_name.py +2 -2
- {walker → adam}/columns/volume_cassandra.py +4 -4
- {walker → adam}/columns/volume_root.py +3 -3
- adam/commands/__init__.py +15 -0
- adam/commands/alter_tables.py +81 -0
- adam/commands/app_cmd.py +38 -0
- {walker → adam}/commands/app_ping.py +10 -16
- adam/commands/audit/audit.py +84 -0
- adam/commands/audit/audit_repair_tables.py +74 -0
- adam/commands/audit/audit_run.py +50 -0
- adam/commands/audit/show_last10.py +48 -0
- adam/commands/audit/show_slow10.py +47 -0
- adam/commands/audit/show_top10.py +45 -0
- adam/commands/audit/utils_show_top10.py +59 -0
- adam/commands/bash/__init__.py +5 -0
- adam/commands/bash/bash.py +36 -0
- adam/commands/bash/bash_completer.py +93 -0
- adam/commands/bash/utils_bash.py +16 -0
- adam/commands/cat.py +50 -0
- adam/commands/cd.py +43 -0
- adam/commands/check.py +73 -0
- {walker → adam}/commands/cli_commands.py +7 -8
- adam/commands/code.py +57 -0
- adam/commands/command.py +190 -0
- {walker → adam}/commands/command_helpers.py +1 -1
- {walker → adam}/commands/commands_utils.py +15 -25
- adam/commands/cp.py +89 -0
- adam/commands/cql/cql_completions.py +33 -0
- {walker/commands → adam/commands/cql}/cqlsh.py +20 -35
- adam/commands/cql/utils_cql.py +343 -0
- {walker/commands/frontend → adam/commands/deploy}/code_start.py +11 -14
- adam/commands/deploy/code_stop.py +40 -0
- {walker/commands/frontend → adam/commands/deploy}/code_utils.py +7 -9
- adam/commands/deploy/deploy.py +25 -0
- adam/commands/deploy/deploy_frontend.py +49 -0
- adam/commands/deploy/deploy_pg_agent.py +35 -0
- adam/commands/deploy/deploy_pod.py +108 -0
- adam/commands/deploy/deploy_utils.py +29 -0
- adam/commands/deploy/undeploy.py +25 -0
- adam/commands/deploy/undeploy_frontend.py +38 -0
- adam/commands/deploy/undeploy_pg_agent.py +39 -0
- adam/commands/deploy/undeploy_pod.py +48 -0
- adam/commands/devices/device.py +118 -0
- adam/commands/devices/device_app.py +173 -0
- adam/commands/devices/device_auit_log.py +49 -0
- adam/commands/devices/device_cass.py +185 -0
- adam/commands/devices/device_export.py +86 -0
- adam/commands/devices/device_postgres.py +144 -0
- adam/commands/devices/devices.py +25 -0
- {walker → adam}/commands/exit.py +3 -6
- adam/commands/export/clean_up_all_export_sessions.py +37 -0
- adam/commands/export/clean_up_export_sessions.py +51 -0
- adam/commands/export/drop_export_database.py +55 -0
- adam/commands/export/drop_export_databases.py +43 -0
- adam/commands/export/export.py +53 -0
- adam/commands/export/export_databases.py +170 -0
- adam/commands/export/export_handlers.py +71 -0
- adam/commands/export/export_select.py +81 -0
- adam/commands/export/export_select_x.py +54 -0
- adam/commands/export/export_use.py +52 -0
- adam/commands/export/exporter.py +352 -0
- adam/commands/export/import_session.py +40 -0
- adam/commands/export/importer.py +67 -0
- adam/commands/export/importer_athena.py +80 -0
- adam/commands/export/importer_sqlite.py +47 -0
- adam/commands/export/show_column_counts.py +54 -0
- adam/commands/export/show_export_databases.py +36 -0
- adam/commands/export/show_export_session.py +48 -0
- adam/commands/export/show_export_sessions.py +44 -0
- adam/commands/export/utils_export.py +314 -0
- {walker → adam}/commands/help.py +17 -12
- adam/commands/intermediate_command.py +49 -0
- adam/commands/issues.py +43 -0
- adam/commands/kubectl.py +38 -0
- adam/commands/login.py +70 -0
- {walker → adam}/commands/logs.py +8 -10
- adam/commands/ls.py +41 -0
- adam/commands/medusa/medusa.py +27 -0
- adam/commands/medusa/medusa_backup.py +57 -0
- adam/commands/medusa/medusa_restore.py +83 -0
- adam/commands/medusa/medusa_show_backupjobs.py +51 -0
- adam/commands/medusa/medusa_show_restorejobs.py +47 -0
- {walker → adam}/commands/nodetool.py +17 -21
- {walker → adam}/commands/param_get.py +15 -16
- adam/commands/param_set.py +43 -0
- adam/commands/postgres/postgres.py +104 -0
- adam/commands/postgres/postgres_context.py +274 -0
- {walker → adam}/commands/postgres/postgres_ls.py +7 -11
- {walker → adam}/commands/postgres/postgres_preview.py +8 -13
- adam/commands/postgres/psql_completions.py +10 -0
- adam/commands/postgres/utils_postgres.py +66 -0
- adam/commands/preview_table.py +37 -0
- adam/commands/pwd.py +47 -0
- adam/commands/reaper/reaper.py +35 -0
- adam/commands/reaper/reaper_forward.py +93 -0
- adam/commands/reaper/reaper_forward_session.py +6 -0
- {walker → adam}/commands/reaper/reaper_forward_stop.py +13 -19
- {walker → adam}/commands/reaper/reaper_restart.py +10 -17
- adam/commands/reaper/reaper_run_abort.py +46 -0
- adam/commands/reaper/reaper_runs.py +82 -0
- adam/commands/reaper/reaper_runs_abort.py +63 -0
- adam/commands/reaper/reaper_schedule_activate.py +45 -0
- adam/commands/reaper/reaper_schedule_start.py +45 -0
- adam/commands/reaper/reaper_schedule_stop.py +45 -0
- {walker → adam}/commands/reaper/reaper_schedules.py +6 -16
- {walker → adam}/commands/reaper/reaper_status.py +11 -19
- adam/commands/reaper/utils_reaper.py +196 -0
- adam/commands/repair/repair.py +26 -0
- {walker → adam}/commands/repair/repair_log.py +7 -10
- adam/commands/repair/repair_run.py +70 -0
- adam/commands/repair/repair_scan.py +71 -0
- {walker → adam}/commands/repair/repair_stop.py +8 -11
- adam/commands/report.py +61 -0
- adam/commands/restart.py +60 -0
- {walker → adam}/commands/rollout.py +25 -30
- adam/commands/shell.py +34 -0
- adam/commands/show/show.py +39 -0
- walker/commands/show/show_version.py → adam/commands/show/show_adam.py +14 -10
- adam/commands/show/show_app_actions.py +57 -0
- {walker → adam}/commands/show/show_app_id.py +12 -15
- {walker → adam}/commands/show/show_app_queues.py +9 -12
- adam/commands/show/show_cassandra_repairs.py +38 -0
- adam/commands/show/show_cassandra_status.py +124 -0
- {walker → adam}/commands/show/show_cassandra_version.py +6 -16
- adam/commands/show/show_commands.py +59 -0
- walker/commands/show/show_storage.py → adam/commands/show/show_host.py +11 -13
- adam/commands/show/show_login.py +62 -0
- {walker → adam}/commands/show/show_params.py +4 -4
- adam/commands/show/show_processes.py +51 -0
- adam/commands/show/show_storage.py +42 -0
- adam/commands/watch.py +82 -0
- {walker → adam}/config.py +10 -22
- {walker → adam}/embedded_apps.py +1 -1
- adam/embedded_params.py +2 -0
- adam/log.py +47 -0
- {walker → adam}/pod_exec_result.py +10 -2
- adam/repl.py +182 -0
- adam/repl_commands.py +124 -0
- adam/repl_state.py +458 -0
- adam/sql/__init__.py +0 -0
- adam/sql/sql_completer.py +120 -0
- adam/sql/sql_state_machine.py +618 -0
- adam/sql/term_completer.py +76 -0
- adam/sso/__init__.py +0 -0
- {walker → adam}/sso/authenticator.py +5 -1
- adam/sso/authn_ad.py +170 -0
- {walker → adam}/sso/authn_okta.py +39 -22
- adam/sso/cred_cache.py +60 -0
- adam/sso/id_token.py +23 -0
- adam/sso/idp.py +143 -0
- adam/sso/idp_login.py +50 -0
- adam/sso/idp_session.py +55 -0
- adam/sso/sso_config.py +63 -0
- adam/utils.py +679 -0
- adam/utils_app.py +98 -0
- adam/utils_athena.py +145 -0
- adam/utils_audits.py +106 -0
- adam/utils_issues.py +32 -0
- adam/utils_k8s/__init__.py +0 -0
- adam/utils_k8s/app_clusters.py +28 -0
- adam/utils_k8s/app_pods.py +33 -0
- adam/utils_k8s/cassandra_clusters.py +36 -0
- adam/utils_k8s/cassandra_nodes.py +33 -0
- adam/utils_k8s/config_maps.py +34 -0
- {walker/k8s_utils → adam/utils_k8s}/custom_resources.py +7 -2
- adam/utils_k8s/deployment.py +56 -0
- {walker/k8s_utils → adam/utils_k8s}/ingresses.py +3 -4
- {walker/k8s_utils → adam/utils_k8s}/jobs.py +3 -3
- adam/utils_k8s/k8s.py +87 -0
- {walker/k8s_utils → adam/utils_k8s}/kube_context.py +4 -4
- adam/utils_k8s/pods.py +290 -0
- {walker/k8s_utils → adam/utils_k8s}/secrets.py +8 -4
- adam/utils_k8s/service_accounts.py +170 -0
- {walker/k8s_utils → adam/utils_k8s}/services.py +3 -4
- {walker/k8s_utils → adam/utils_k8s}/statefulsets.py +6 -16
- {walker/k8s_utils → adam/utils_k8s}/volumes.py +10 -1
- adam/utils_net.py +24 -0
- adam/utils_repl/__init__.py +0 -0
- adam/utils_repl/automata_completer.py +48 -0
- adam/utils_repl/repl_completer.py +46 -0
- adam/utils_repl/state_machine.py +173 -0
- adam/utils_sqlite.py +109 -0
- adam/version.py +5 -0
- {kaqing-1.77.0.dist-info → kaqing-2.0.171.dist-info}/METADATA +1 -1
- kaqing-2.0.171.dist-info/RECORD +236 -0
- kaqing-2.0.171.dist-info/entry_points.txt +3 -0
- kaqing-2.0.171.dist-info/top_level.txt +1 -0
- kaqing-1.77.0.dist-info/RECORD +0 -159
- kaqing-1.77.0.dist-info/entry_points.txt +0 -3
- kaqing-1.77.0.dist-info/top_level.txt +0 -1
- walker/__init__.py +0 -3
- walker/app_session.py +0 -168
- walker/checks/check_utils.py +0 -97
- walker/columns/columns.py +0 -43
- walker/commands/add_user.py +0 -68
- walker/commands/app.py +0 -67
- walker/commands/bash.py +0 -87
- walker/commands/cd.py +0 -115
- walker/commands/check.py +0 -68
- walker/commands/command.py +0 -104
- walker/commands/cp.py +0 -95
- walker/commands/cql_utils.py +0 -53
- walker/commands/devices.py +0 -89
- walker/commands/frontend/code_stop.py +0 -57
- walker/commands/frontend/setup.py +0 -60
- walker/commands/frontend/setup_frontend.py +0 -58
- walker/commands/frontend/teardown.py +0 -61
- walker/commands/frontend/teardown_frontend.py +0 -42
- walker/commands/issues.py +0 -69
- walker/commands/login.py +0 -72
- walker/commands/ls.py +0 -145
- walker/commands/medusa/medusa.py +0 -69
- walker/commands/medusa/medusa_backup.py +0 -61
- walker/commands/medusa/medusa_restore.py +0 -86
- walker/commands/medusa/medusa_show_backupjobs.py +0 -52
- walker/commands/medusa/medusa_show_restorejobs.py +0 -52
- walker/commands/param_set.py +0 -44
- walker/commands/postgres/postgres.py +0 -113
- walker/commands/postgres/postgres_session.py +0 -225
- walker/commands/preview_table.py +0 -98
- walker/commands/processes.py +0 -53
- walker/commands/pwd.py +0 -64
- walker/commands/reaper/reaper.py +0 -78
- walker/commands/reaper/reaper_forward.py +0 -100
- walker/commands/reaper/reaper_run_abort.py +0 -65
- walker/commands/reaper/reaper_runs.py +0 -97
- walker/commands/reaper/reaper_runs_abort.py +0 -83
- walker/commands/reaper/reaper_schedule_activate.py +0 -64
- walker/commands/reaper/reaper_schedule_start.py +0 -64
- walker/commands/reaper/reaper_schedule_stop.py +0 -64
- walker/commands/reaper/reaper_session.py +0 -159
- walker/commands/repair/repair.py +0 -68
- walker/commands/repair/repair_run.py +0 -72
- walker/commands/repair/repair_scan.py +0 -79
- walker/commands/report.py +0 -57
- walker/commands/restart.py +0 -61
- walker/commands/show/show.py +0 -72
- walker/commands/show/show_app_actions.py +0 -53
- walker/commands/show/show_cassandra_status.py +0 -35
- walker/commands/show/show_commands.py +0 -58
- walker/commands/show/show_processes.py +0 -35
- walker/commands/show/show_repairs.py +0 -47
- walker/commands/status.py +0 -128
- walker/commands/storage.py +0 -52
- walker/commands/user_entry.py +0 -69
- walker/commands/watch.py +0 -85
- walker/embedded_params.py +0 -2
- walker/k8s_utils/cassandra_clusters.py +0 -48
- walker/k8s_utils/cassandra_nodes.py +0 -26
- walker/k8s_utils/pods.py +0 -211
- walker/repl.py +0 -165
- walker/repl_commands.py +0 -58
- walker/repl_state.py +0 -211
- walker/sso/authn_ad.py +0 -94
- walker/sso/idp.py +0 -150
- walker/sso/idp_login.py +0 -29
- walker/sso/sso_config.py +0 -45
- walker/utils.py +0 -194
- walker/version.py +0 -5
- {walker → adam}/checks/__init__.py +0 -0
- {walker → adam}/checks/check_context.py +0 -0
- {walker → adam}/checks/issue.py +0 -0
- {walker → adam}/cli_group.py +0 -0
- {walker → adam}/columns/__init__.py +0 -0
- {walker/commands → adam/commands/audit}/__init__.py +0 -0
- {walker/commands/frontend → adam/commands/cql}/__init__.py +0 -0
- {walker/commands/medusa → adam/commands/deploy}/__init__.py +0 -0
- {walker/commands/postgres → adam/commands/devices}/__init__.py +0 -0
- {walker/commands/reaper → adam/commands/export}/__init__.py +0 -0
- {walker/commands/repair → adam/commands/medusa}/__init__.py +0 -0
- {walker → adam}/commands/nodetool_commands.py +0 -0
- {walker/commands/show → adam/commands/postgres}/__init__.py +0 -0
- {walker/k8s_utils → adam/commands/reaper}/__init__.py +0 -0
- {walker/sso → adam/commands/repair}/__init__.py +0 -0
- /walker/medusa_show_restorejobs.py → /adam/commands/show/__init__.py +0 -0
- {walker → adam}/repl_session.py +0 -0
- {kaqing-1.77.0.dist-info → kaqing-2.0.171.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from adam.commands import extract_options
|
|
2
|
+
from adam.commands.command import Command
|
|
3
|
+
from adam.commands.cql.utils_cql import cassandra
|
|
4
|
+
from adam.config import Config
|
|
5
|
+
from adam.repl_state import ReplState, RequiredState
|
|
6
|
+
|
|
7
|
+
class ShowStorage(Command):
|
|
8
|
+
COMMAND = 'show storage'
|
|
9
|
+
|
|
10
|
+
# the singleton pattern
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
if not hasattr(cls, 'instance'): cls.instance = super(ShowStorage, cls).__new__(cls)
|
|
13
|
+
|
|
14
|
+
return cls.instance
|
|
15
|
+
|
|
16
|
+
def __init__(self, successor: Command=None):
|
|
17
|
+
super().__init__(successor)
|
|
18
|
+
|
|
19
|
+
def command(self):
|
|
20
|
+
return ShowStorage.COMMAND
|
|
21
|
+
|
|
22
|
+
def required(self):
|
|
23
|
+
return RequiredState.CLUSTER_OR_POD
|
|
24
|
+
|
|
25
|
+
def run(self, cmd: str, state: ReplState):
|
|
26
|
+
if not(args := self.args(cmd)):
|
|
27
|
+
return super().run(cmd, state)
|
|
28
|
+
|
|
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.show_table(cols, header, show_out=show_out)
|
|
35
|
+
|
|
36
|
+
return state
|
|
37
|
+
|
|
38
|
+
def completion(self, state: ReplState):
|
|
39
|
+
return super().completion(state, {'-s': None})
|
|
40
|
+
|
|
41
|
+
def help(self, _: ReplState):
|
|
42
|
+
return f'{ShowStorage.COMMAND} [-s]\t show storage overview -s show commands on nodes'
|
adam/commands/watch.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
import time
|
|
3
|
+
from kubernetes import client
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
from adam.commands.command import Command
|
|
7
|
+
from adam.commands.commands_utils import show_pods, show_rollout
|
|
8
|
+
from adam.config import Config
|
|
9
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
10
|
+
from adam.repl_state import ReplState, RequiredState
|
|
11
|
+
from adam.utils import log2
|
|
12
|
+
|
|
13
|
+
class Watch(Command):
|
|
14
|
+
COMMAND = 'watch cassandra pods'
|
|
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.NAMESPACE
|
|
30
|
+
|
|
31
|
+
def run(self, cmd: str, state: ReplState):
|
|
32
|
+
if not(args := self.args(cmd)):
|
|
33
|
+
return super().run(cmd, state)
|
|
34
|
+
|
|
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
|
|
40
|
+
|
|
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()
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
log2(f"Press Ctrl+C to break.")
|
|
47
|
+
|
|
48
|
+
time.sleep(Config().get('watch.timeout', 3600 * 1))
|
|
49
|
+
except KeyboardInterrupt:
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
log2("Stopping watch...")
|
|
53
|
+
stop_event.set()
|
|
54
|
+
thread.join()
|
|
55
|
+
|
|
56
|
+
return state
|
|
57
|
+
|
|
58
|
+
def loop(self, stop_flag: threading.Event, sts: str, pods: List[client.V1Pod], ns: str):
|
|
59
|
+
show_pods(pods, ns)
|
|
60
|
+
show_rollout(sts, ns)
|
|
61
|
+
|
|
62
|
+
cnt = Config().get('watch.interval', 10)
|
|
63
|
+
while not stop_flag.is_set():
|
|
64
|
+
time.sleep(1)
|
|
65
|
+
cnt -= 1
|
|
66
|
+
|
|
67
|
+
if not cnt:
|
|
68
|
+
show_pods(pods, ns)
|
|
69
|
+
show_rollout(sts, ns)
|
|
70
|
+
cnt = Config().get('watch.interval', 10)
|
|
71
|
+
|
|
72
|
+
def completion(self, state: ReplState):
|
|
73
|
+
if sc := super().completion(state):
|
|
74
|
+
if state.sts:
|
|
75
|
+
return sc
|
|
76
|
+
|
|
77
|
+
return super().completion(state, {n: None for n in StatefulSets.list_sts_names()})
|
|
78
|
+
|
|
79
|
+
return {}
|
|
80
|
+
|
|
81
|
+
def help(self, _: ReplState):
|
|
82
|
+
return f'{Watch.COMMAND}\t watch Cassandra pod changes'
|
{walker → adam}/config.py
RENAMED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import importlib
|
|
2
1
|
import os
|
|
3
2
|
from typing import TypeVar, cast
|
|
4
3
|
import yaml
|
|
5
|
-
from pathlib import Path
|
|
6
4
|
|
|
7
5
|
from . import __version__
|
|
8
|
-
from
|
|
6
|
+
from adam.utils import LogConfig, copy_config_file, get_deep_keys, log2
|
|
9
7
|
|
|
10
8
|
T = TypeVar('T')
|
|
11
9
|
|
|
12
10
|
class Config:
|
|
13
11
|
EMBEDDED_PARAMS = {}
|
|
14
12
|
|
|
13
|
+
LogConfig.is_debug = lambda: Config().is_debug()
|
|
14
|
+
LogConfig.is_debug_timing = lambda: Config().get('debugs.timings', False)
|
|
15
|
+
|
|
15
16
|
# the singleton pattern
|
|
16
17
|
def __new__(cls, *args, **kwargs):
|
|
17
18
|
if not hasattr(cls, 'instance'): cls.instance = super(Config, cls).__new__(cls)
|
|
@@ -20,29 +21,16 @@ class Config:
|
|
|
20
21
|
|
|
21
22
|
def __init__(self, path: str = None, is_user_entry = False):
|
|
22
23
|
if path:
|
|
24
|
+
self.wait_log_flag = False
|
|
23
25
|
try:
|
|
24
26
|
with open(path) as f:
|
|
25
27
|
self.params = cast(dict[str, any], yaml.safe_load(f))
|
|
26
28
|
except:
|
|
27
|
-
|
|
29
|
+
with open(copy_config_file(f'params.yaml.{__version__}', 'adam.embedded_params', show_out=not is_user_entry)) as f:
|
|
30
|
+
self.params = cast(dict[str, any], yaml.safe_load(f))
|
|
28
31
|
elif not hasattr(self, 'params'):
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def copy_config_file(self, is_user_entry = False):
|
|
32
|
-
dir = f'{Path.home()}/.kaqing'
|
|
33
|
-
path = f'{dir}/params.yaml.{__version__}'
|
|
34
|
-
if not os.path.exists(path):
|
|
35
|
-
os.makedirs(dir, exist_ok=True)
|
|
36
|
-
module = importlib.import_module('walker.embedded_params')
|
|
37
|
-
with open(path, 'w') as f:
|
|
38
|
-
yaml.dump(module.params(), f, default_flow_style=False)
|
|
39
|
-
if not is_user_entry:
|
|
40
|
-
log2(f'Default params.yaml has been written to {path}.')
|
|
41
|
-
|
|
42
|
-
with open(path) as f:
|
|
43
|
-
self.params = cast(dict[str, any], yaml.safe_load(f))
|
|
44
|
-
|
|
45
|
-
return path
|
|
32
|
+
with open(copy_config_file(f'params.yaml.{__version__}', 'adam.embedded_params', show_out=not is_user_entry)) as f:
|
|
33
|
+
self.params = cast(dict[str, any], yaml.safe_load(f))
|
|
46
34
|
|
|
47
35
|
def action_node_samples(self, action: str, default: T):
|
|
48
36
|
return self.get(f'{action}.samples', default)
|
|
@@ -54,7 +42,7 @@ class Config:
|
|
|
54
42
|
return get_deep_keys(self.params)
|
|
55
43
|
|
|
56
44
|
def is_debug(self):
|
|
57
|
-
return Config().get('debug
|
|
45
|
+
return os.getenv('QING_DEV', 'false').lower() == 'true' or Config().get('debug', False)
|
|
58
46
|
|
|
59
47
|
def get(self, key: str, default: T) -> T:
|
|
60
48
|
# params['nodetool']['status']['max-nodes']
|
{walker → adam}/embedded_apps.py
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
def
|
|
1
|
+
def config():
|
|
2
2
|
return {'Echo': [{'echo': {'help': 'echo the message', 'payload': '{"thisArg":{"type":"Echo","message":"{ARG1}"}}', 'ARG1': 'string'}}, {'echoStatic': 'show random message'}], 'InvalidationQueue': [{'countAll': 'show queue counts'}, {'count': 'show queue count'}, {'pause': 'pause queue'}, {'resume': 'resume queue'}, {'isPaused': 'return true if paused'}], 'MapReduceQueue(InvalidationQueue)': None}
|
adam/embedded_params.py
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
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, '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>'}}, '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-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
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
class Log:
|
|
8
|
+
DEBUG = False
|
|
9
|
+
|
|
10
|
+
def is_debug():
|
|
11
|
+
return Log.DEBUG
|
|
12
|
+
|
|
13
|
+
def debug(s: None):
|
|
14
|
+
if Log.DEBUG:
|
|
15
|
+
Log.log2(f'DEBUG {s}')
|
|
16
|
+
|
|
17
|
+
def log(s = None):
|
|
18
|
+
# want to print empty line for False or empty collection
|
|
19
|
+
if s == None:
|
|
20
|
+
print()
|
|
21
|
+
else:
|
|
22
|
+
click.echo(s)
|
|
23
|
+
|
|
24
|
+
def log2(s = None):
|
|
25
|
+
if s:
|
|
26
|
+
click.echo(s, err=True)
|
|
27
|
+
else:
|
|
28
|
+
print(file=sys.stderr)
|
|
29
|
+
|
|
30
|
+
def log_to_file(config: dict[any, any]):
|
|
31
|
+
try:
|
|
32
|
+
base = f"/tmp/logs"
|
|
33
|
+
os.makedirs(base, exist_ok=True)
|
|
34
|
+
|
|
35
|
+
now = datetime.now()
|
|
36
|
+
timestamp_str = now.strftime("%Y%m%d-%H%M%S")
|
|
37
|
+
filename = f"{base}/login.{timestamp_str}.txt"
|
|
38
|
+
with open(filename, 'w') as f:
|
|
39
|
+
if isinstance(config, dict):
|
|
40
|
+
try:
|
|
41
|
+
json.dump(config, f, indent=4)
|
|
42
|
+
except:
|
|
43
|
+
f.write(config)
|
|
44
|
+
else:
|
|
45
|
+
f.write(config)
|
|
46
|
+
except:
|
|
47
|
+
pass
|
|
@@ -15,12 +15,14 @@ class PodExecResult:
|
|
|
15
15
|
# ]
|
|
16
16
|
# }
|
|
17
17
|
# }
|
|
18
|
-
def __init__(self, stdout: str, stderr: str, command: str = None, error_output: str = None):
|
|
18
|
+
def __init__(self, stdout: str, stderr: str, command: str = None, error_output: str = None, pod: str = None, log_file: str = None):
|
|
19
19
|
self.stdout: str = stdout
|
|
20
20
|
self.stderr: str = stderr
|
|
21
21
|
self.command: str = command
|
|
22
22
|
if error_output:
|
|
23
23
|
self.error = yaml.safe_load(error_output)
|
|
24
|
+
self.pod = pod
|
|
25
|
+
self.log_file = log_file
|
|
24
26
|
|
|
25
27
|
def exit_code(self) -> int:
|
|
26
28
|
code = 0
|
|
@@ -30,4 +32,10 @@ class PodExecResult:
|
|
|
30
32
|
except:
|
|
31
33
|
pass
|
|
32
34
|
|
|
33
|
-
return code
|
|
35
|
+
return code
|
|
36
|
+
|
|
37
|
+
def __str__(self):
|
|
38
|
+
return f'{"OK" if self.exit_code() == 0 else self.exit_code()} {self.command}'
|
|
39
|
+
|
|
40
|
+
def __audit_extra__(self):
|
|
41
|
+
return self.log_file if self.log_file else None
|
adam/repl.py
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
import traceback
|
|
4
|
+
from typing import cast
|
|
5
|
+
import click
|
|
6
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
7
|
+
|
|
8
|
+
from adam.cli_group import cli
|
|
9
|
+
from adam.commands.command import Command, InvalidState
|
|
10
|
+
from adam.commands.command_helpers import ClusterCommandHelper
|
|
11
|
+
from adam.commands.devices.devices import Devices
|
|
12
|
+
from adam.commands.help import Help
|
|
13
|
+
from adam.config import Config
|
|
14
|
+
from adam.utils_audits import Audits
|
|
15
|
+
from adam.utils_k8s.kube_context import KubeContext
|
|
16
|
+
from adam.log import Log
|
|
17
|
+
from adam.repl_commands import ReplCommands
|
|
18
|
+
from adam.repl_session import ReplSession
|
|
19
|
+
from adam.repl_state import ReplState
|
|
20
|
+
from adam.utils import clear_wait_log_flag, debug, deep_merge_dicts, deep_sort_dict, lines_to_tabular, log2, log_timing
|
|
21
|
+
from adam.apps import Apps
|
|
22
|
+
from adam.utils_repl.repl_completer import ReplCompleter
|
|
23
|
+
from . import __version__
|
|
24
|
+
|
|
25
|
+
def enter_repl(state: ReplState):
|
|
26
|
+
if os.getenv('QING_DROPPED', 'false') == 'true':
|
|
27
|
+
log2('You have dropped to bash from another qing instance. Please enter "exit" to go back to qing.')
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
cmd_list: list[Command] = ReplCommands.repl_cmd_list() + [Help()]
|
|
31
|
+
# head with the Chain of Responsibility pattern
|
|
32
|
+
cmds: Command = Command.chain(cmd_list)
|
|
33
|
+
session = ReplSession().prompt_session
|
|
34
|
+
|
|
35
|
+
def prompt_msg():
|
|
36
|
+
msg = state.__str__()
|
|
37
|
+
|
|
38
|
+
return f"{msg}$ " if state.bash_session else f"{msg}> "
|
|
39
|
+
|
|
40
|
+
Log.log2(f'kaqing {__version__}')
|
|
41
|
+
|
|
42
|
+
Devices.device(state).enter(state)
|
|
43
|
+
|
|
44
|
+
kb = KeyBindings()
|
|
45
|
+
|
|
46
|
+
@kb.add('c-c')
|
|
47
|
+
def _(event):
|
|
48
|
+
event.app.current_buffer.text = ''
|
|
49
|
+
|
|
50
|
+
with Audits.offload() as exec:
|
|
51
|
+
# warm up AWS lambda - this log line may timeout and get lost, which is fine
|
|
52
|
+
exec.submit(Audits.log, 'entering kaqing repl', state.namespace, 'z', 0.0)
|
|
53
|
+
|
|
54
|
+
s0 = time.time()
|
|
55
|
+
|
|
56
|
+
# use sorted command list only for auto-completion
|
|
57
|
+
sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
|
|
58
|
+
while True:
|
|
59
|
+
cmd: str = None
|
|
60
|
+
result = None
|
|
61
|
+
try:
|
|
62
|
+
completer = ReplCompleter.from_nested_dict({})
|
|
63
|
+
if not state.bash_session:
|
|
64
|
+
with log_timing('completion-calcs'):
|
|
65
|
+
completions = {}
|
|
66
|
+
# app commands are available only on a: drive
|
|
67
|
+
if state.device == ReplState.A and state.app_app:
|
|
68
|
+
completions = log_timing('actions', lambda: Apps(path='apps.yaml').commands())
|
|
69
|
+
|
|
70
|
+
for c in sorted_cmds:
|
|
71
|
+
try:
|
|
72
|
+
completions = log_timing(c.command(), lambda: deep_sort_dict(deep_merge_dicts(completions, c.completion(state))))
|
|
73
|
+
except:
|
|
74
|
+
log2(f'* {c.command()} command returned None completions.')
|
|
75
|
+
|
|
76
|
+
# print(json.dumps(completions, indent=4))
|
|
77
|
+
completer = ReplCompleter.from_nested_dict(completions)
|
|
78
|
+
|
|
79
|
+
cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
|
|
80
|
+
s0 = time.time()
|
|
81
|
+
|
|
82
|
+
if state.bash_session:
|
|
83
|
+
if cmd.strip(' ') == 'exit':
|
|
84
|
+
state.exit_bash()
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
cmd = f'bash {cmd}'
|
|
88
|
+
|
|
89
|
+
def targetted(state: ReplState, cmd: str):
|
|
90
|
+
if not (cmd.startswith('@') and len(arry := cmd.split(' ')) > 1):
|
|
91
|
+
return state, cmd
|
|
92
|
+
|
|
93
|
+
if state.device == ReplState.A and state.app_app or state.device == ReplState.P:
|
|
94
|
+
state.push()
|
|
95
|
+
|
|
96
|
+
state.app_pod = arry[0].strip('@')
|
|
97
|
+
cmd = ' '.join(arry[1:])
|
|
98
|
+
elif state.device == ReplState.P:
|
|
99
|
+
state.push()
|
|
100
|
+
|
|
101
|
+
state.app_pod = arry[0].strip('@')
|
|
102
|
+
cmd = ' '.join(arry[1:])
|
|
103
|
+
elif state.sts:
|
|
104
|
+
state.push()
|
|
105
|
+
|
|
106
|
+
state.pod = arry[0].strip('@')
|
|
107
|
+
cmd = ' '.join(arry[1:])
|
|
108
|
+
|
|
109
|
+
return (state, cmd)
|
|
110
|
+
|
|
111
|
+
target, cmd = targetted(state, cmd)
|
|
112
|
+
try:
|
|
113
|
+
if cmd and cmd.strip(' ') and not (result := cmds.run(cmd, target)):
|
|
114
|
+
result = try_device_default_action(target, cmds, cmd_list, cmd)
|
|
115
|
+
except InvalidState:
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
if result and type(result) is ReplState and (s := cast(ReplState, result).export_session) != state.export_session:
|
|
119
|
+
state.export_session = s
|
|
120
|
+
|
|
121
|
+
except EOFError: # Handle Ctrl+D (EOF) for graceful exit
|
|
122
|
+
break
|
|
123
|
+
except Exception as e:
|
|
124
|
+
if Config().get('debugs.exit-on-error', False):
|
|
125
|
+
raise e
|
|
126
|
+
else:
|
|
127
|
+
log2(e)
|
|
128
|
+
debug(traceback.format_exc())
|
|
129
|
+
finally:
|
|
130
|
+
if not state.bash_session:
|
|
131
|
+
state.pop()
|
|
132
|
+
|
|
133
|
+
clear_wait_log_flag()
|
|
134
|
+
if cmd:
|
|
135
|
+
log_timing(f'command {cmd}', s0=s0)
|
|
136
|
+
|
|
137
|
+
# offload audit logging
|
|
138
|
+
if cmd and (state.device != ReplState.L or Config().get('audit.log-audit-queries', False)):
|
|
139
|
+
exec.submit(Audits.log, cmd, state.namespace, state.device, time.time() - s0, get_audit_extra(result))
|
|
140
|
+
|
|
141
|
+
def try_device_default_action(state: ReplState, cmds: Command, cmd_list: list[Command], cmd: str):
|
|
142
|
+
action_taken, result = Devices.device(state).try_fallback_action(cmds, state, cmd)
|
|
143
|
+
|
|
144
|
+
if not action_taken:
|
|
145
|
+
log2(f'* Invalid command: {cmd}')
|
|
146
|
+
log2()
|
|
147
|
+
lines = [c.help(state) for c in cmd_list if c.help(state)]
|
|
148
|
+
log2(lines_to_tabular(lines, separator='\t'))
|
|
149
|
+
|
|
150
|
+
return result
|
|
151
|
+
|
|
152
|
+
def get_audit_extra(result: any):
|
|
153
|
+
if not result:
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
if type(result) is list:
|
|
157
|
+
extras = set()
|
|
158
|
+
|
|
159
|
+
for r in result:
|
|
160
|
+
if hasattr(r, '__audit_extra__') and (x := r.__audit_extra__()):
|
|
161
|
+
extras.add(x)
|
|
162
|
+
|
|
163
|
+
return ','.join(list(extras))
|
|
164
|
+
|
|
165
|
+
if hasattr(result, '__audit_extra__') and (x := result.__audit_extra__()):
|
|
166
|
+
return x
|
|
167
|
+
|
|
168
|
+
@cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=ClusterCommandHelper, help="Enter interactive shell.")
|
|
169
|
+
@click.option('--kubeconfig', '-k', required=False, metavar='path', help='path to kubeconfig file')
|
|
170
|
+
@click.option('--config', default='params.yaml', metavar='path', help='path to kaqing parameters file')
|
|
171
|
+
@click.option('--param', '-v', multiple=True, metavar='<key>=<value>', help='parameter override')
|
|
172
|
+
@click.option('--cluster', '-c', required=False, metavar='statefulset', help='Kubernetes statefulset name')
|
|
173
|
+
@click.option('--namespace', '-n', required=False, metavar='namespace', help='Kubernetes namespace')
|
|
174
|
+
@click.argument('extra_args', nargs=-1, metavar='[cluster]', type=click.UNPROCESSED)
|
|
175
|
+
def repl(kubeconfig: str, config: str, param: list[str], cluster:str, namespace: str, extra_args):
|
|
176
|
+
KubeContext.init_config(kubeconfig)
|
|
177
|
+
if not KubeContext.init_params(config, param):
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
state = ReplState(device=Config().get('repl.start-drive', 'a'), ns_sts=cluster, namespace=namespace, in_repl=True)
|
|
181
|
+
state, _ = state.apply_device_arg(extra_args)
|
|
182
|
+
enter_repl(state)
|
adam/repl_commands.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from adam.commands.alter_tables import AlterTables
|
|
2
|
+
from adam.commands.app_cmd import App
|
|
3
|
+
from adam.commands.app_ping import AppPing
|
|
4
|
+
from adam.commands.audit.audit import Audit
|
|
5
|
+
from adam.commands.cat import Cat
|
|
6
|
+
from adam.commands.code import Code
|
|
7
|
+
from adam.commands.deploy.code_start import CodeStart
|
|
8
|
+
from adam.commands.deploy.code_stop import CodeStop
|
|
9
|
+
from adam.commands.deploy.deploy import Deploy
|
|
10
|
+
from adam.commands.deploy.deploy_frontend import DeployFrontend
|
|
11
|
+
from adam.commands.deploy.deploy_pg_agent import DeployPgAgent
|
|
12
|
+
from adam.commands.deploy.deploy_pod import DeployPod
|
|
13
|
+
from adam.commands.deploy.undeploy import Undeploy
|
|
14
|
+
from adam.commands.deploy.undeploy_frontend import UndeployFrontend
|
|
15
|
+
from adam.commands.deploy.undeploy_pg_agent import UndeployPgAgent
|
|
16
|
+
from adam.commands.deploy.undeploy_pod import UndeployPod
|
|
17
|
+
from adam.commands.devices.device_app import DeviceApp
|
|
18
|
+
from adam.commands.devices.device_auit_log import DeviceAuditLog
|
|
19
|
+
from adam.commands.devices.device_cass import DeviceCass
|
|
20
|
+
from adam.commands.devices.device_export import DeviceExport
|
|
21
|
+
from adam.commands.devices.device_postgres import DevicePostgres
|
|
22
|
+
from adam.commands.export.drop_export_database import DropExportDatabase
|
|
23
|
+
from adam.commands.export.export import ExportTables
|
|
24
|
+
from adam.commands.export.import_session import ImportSession
|
|
25
|
+
from adam.commands.export.clean_up_export_sessions import CleanUpExportSessions
|
|
26
|
+
from adam.commands.export.clean_up_all_export_sessions import CleanUpAllExportSessions
|
|
27
|
+
from adam.commands.export.drop_export_databases import DropExportDatabases
|
|
28
|
+
from adam.commands.export.export_select import ExportSelect
|
|
29
|
+
from adam.commands.export.export_use import ExportUse
|
|
30
|
+
from adam.commands.export.export_select_x import ExportSelectX
|
|
31
|
+
from adam.commands.export.show_column_counts import ShowColumnCounts
|
|
32
|
+
from adam.commands.export.show_export_databases import ShowExportDatabases
|
|
33
|
+
from adam.commands.export.show_export_session import ShowExportSession
|
|
34
|
+
from adam.commands.export.show_export_sessions import ShowExportSessions
|
|
35
|
+
from adam.commands.kubectl import Kubectl
|
|
36
|
+
from adam.commands.shell import Shell
|
|
37
|
+
from adam.commands.show.show_app_queues import ShowAppQueues
|
|
38
|
+
from adam.commands.cp import ClipboardCopy
|
|
39
|
+
from adam.commands.bash.bash import Bash
|
|
40
|
+
from adam.commands.cd import Cd
|
|
41
|
+
from adam.commands.check import Check
|
|
42
|
+
from adam.commands.command import Command
|
|
43
|
+
from adam.commands.cql.cqlsh import Cqlsh
|
|
44
|
+
from adam.commands.exit import Exit
|
|
45
|
+
from adam.commands.medusa.medusa import Medusa
|
|
46
|
+
from adam.commands.param_get import GetParam
|
|
47
|
+
from adam.commands.issues import Issues
|
|
48
|
+
from adam.commands.ls import Ls
|
|
49
|
+
from adam.commands.nodetool import NodeTool
|
|
50
|
+
from adam.commands.postgres.postgres import Postgres, PostgresPg
|
|
51
|
+
from adam.commands.preview_table import PreviewTable
|
|
52
|
+
from adam.commands.pwd import Pwd
|
|
53
|
+
from adam.commands.reaper.reaper import Reaper
|
|
54
|
+
from adam.commands.repair.repair import Repair
|
|
55
|
+
from adam.commands.report import Report
|
|
56
|
+
from adam.commands.restart import Restart
|
|
57
|
+
from adam.commands.rollout import RollOut
|
|
58
|
+
from adam.commands.param_set import SetParam
|
|
59
|
+
from adam.commands.show.show import Show
|
|
60
|
+
from adam.commands.show.show_app_actions import ShowAppActions
|
|
61
|
+
from adam.commands.show.show_app_id import ShowAppId
|
|
62
|
+
from adam.commands.show.show_cassandra_status import ShowCassandraStatus
|
|
63
|
+
from adam.commands.show.show_cassandra_version import ShowCassandraVersion
|
|
64
|
+
from adam.commands.show.show_commands import ShowKubectlCommands
|
|
65
|
+
from adam.commands.show.show_host import ShowHost
|
|
66
|
+
from adam.commands.show.show_login import ShowLogin
|
|
67
|
+
from adam.commands.show.show_params import ShowParams
|
|
68
|
+
from adam.commands.show.show_processes import ShowProcesses
|
|
69
|
+
from adam.commands.show.show_cassandra_repairs import ShowCassandraRepairs
|
|
70
|
+
from adam.commands.show.show_storage import ShowStorage
|
|
71
|
+
from adam.commands.show.show_adam import ShowAdam
|
|
72
|
+
from adam.commands.watch import Watch
|
|
73
|
+
|
|
74
|
+
class ReplCommands:
|
|
75
|
+
def repl_cmd_list() -> list[Command]:
|
|
76
|
+
cmds: list[Command] = ReplCommands.navigation() + ReplCommands.cassandra_ops() + ReplCommands.postgres_ops() + \
|
|
77
|
+
ReplCommands.app_ops() + ReplCommands.audit_ops() + ReplCommands.export_ops() + ReplCommands.tools() + ReplCommands.exit()
|
|
78
|
+
|
|
79
|
+
intermediate_cmds: list[Command] = [App(), Audit(), Reaper(), Repair(), Deploy(), Show(), Undeploy()]
|
|
80
|
+
ic = [c.command() for c in intermediate_cmds]
|
|
81
|
+
# 1. dedup commands
|
|
82
|
+
deduped = []
|
|
83
|
+
cs = set()
|
|
84
|
+
for cmd in cmds:
|
|
85
|
+
if cmd.command() not in cs and cmd.command() not in ic:
|
|
86
|
+
deduped.append(cmd)
|
|
87
|
+
cs.add(cmd.command())
|
|
88
|
+
# 2. intermediate commands must be added to the end
|
|
89
|
+
deduped.extend(intermediate_cmds)
|
|
90
|
+
|
|
91
|
+
# Command.print_chain(Command.chain(cmds))
|
|
92
|
+
|
|
93
|
+
return deduped
|
|
94
|
+
|
|
95
|
+
def navigation() -> list[Command]:
|
|
96
|
+
return [Ls(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), DeviceAuditLog(), DeviceExport(), Cd(), Cat(), Pwd(), ClipboardCopy(),
|
|
97
|
+
GetParam(), SetParam(), ShowParams(), ShowKubectlCommands(), ShowLogin(), ShowAdam(), ShowHost()]
|
|
98
|
+
|
|
99
|
+
def cassandra_ops() -> list[Command]:
|
|
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()
|
|
107
|
+
|
|
108
|
+
def postgres_ops() -> list[Command]:
|
|
109
|
+
return [Postgres(), DeployPgAgent(), UndeployPgAgent(), PostgresPg()]
|
|
110
|
+
|
|
111
|
+
def app_ops() -> list[Command]:
|
|
112
|
+
return [ShowAppActions(), ShowAppId(), ShowAppQueues(), AppPing(), App()]
|
|
113
|
+
|
|
114
|
+
def audit_ops() -> list[Command]:
|
|
115
|
+
return [Audit()] + Audit().cmd_list()
|
|
116
|
+
|
|
117
|
+
def export_ops() -> list[Command]:
|
|
118
|
+
return [ExportSelectX(), DropExportDatabase(), DropExportDatabases(), ShowColumnCounts()]
|
|
119
|
+
|
|
120
|
+
def tools() -> list[Command]:
|
|
121
|
+
return [Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(), DeployPod(), UndeployPod(), Kubectl(), Code()]
|
|
122
|
+
|
|
123
|
+
def exit() -> list[Command]:
|
|
124
|
+
return [Exit()]
|