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
walker/commands/user_entry.py
DELETED
|
@@ -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()]
|