kaqing 1.98.15__py3-none-any.whl → 2.0.145__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kaqing might be problematic. Click here for more details.
- adam/app_session.py +1 -1
- adam/apps.py +2 -2
- adam/batch.py +30 -31
- adam/checks/check_utils.py +4 -4
- adam/checks/compactionstats.py +1 -1
- adam/checks/cpu.py +2 -2
- adam/checks/disk.py +1 -1
- adam/checks/gossip.py +1 -1
- adam/checks/memory.py +3 -3
- adam/checks/status.py +1 -1
- adam/commands/alter_tables.py +81 -0
- adam/commands/app.py +3 -3
- adam/commands/app_ping.py +2 -2
- adam/commands/audit/audit.py +86 -0
- adam/commands/audit/audit_repair_tables.py +77 -0
- adam/commands/audit/audit_run.py +58 -0
- adam/commands/audit/show_last10.py +51 -0
- adam/commands/audit/show_slow10.py +50 -0
- adam/commands/audit/show_top10.py +48 -0
- adam/commands/audit/utils_show_top10.py +59 -0
- adam/commands/bash/bash.py +133 -0
- adam/commands/bash/bash_completer.py +93 -0
- adam/commands/cat.py +56 -0
- adam/commands/cd.py +12 -82
- adam/commands/check.py +6 -0
- adam/commands/cli_commands.py +3 -3
- adam/commands/code.py +60 -0
- adam/commands/command.py +48 -12
- adam/commands/commands_utils.py +4 -5
- adam/commands/cql/cql_completions.py +28 -0
- adam/commands/cql/cql_utils.py +209 -0
- adam/commands/{cqlsh.py → cql/cqlsh.py} +15 -10
- adam/commands/deploy/__init__.py +0 -0
- adam/commands/{frontend → deploy}/code_start.py +1 -1
- adam/commands/{frontend → deploy}/code_stop.py +1 -1
- adam/commands/{frontend → deploy}/code_utils.py +2 -2
- adam/commands/deploy/deploy.py +48 -0
- adam/commands/deploy/deploy_frontend.py +52 -0
- adam/commands/deploy/deploy_pg_agent.py +38 -0
- adam/commands/deploy/deploy_pod.py +110 -0
- adam/commands/deploy/deploy_utils.py +29 -0
- adam/commands/deploy/undeploy.py +48 -0
- adam/commands/deploy/undeploy_frontend.py +41 -0
- adam/commands/deploy/undeploy_pg_agent.py +42 -0
- adam/commands/deploy/undeploy_pod.py +51 -0
- adam/commands/devices/__init__.py +0 -0
- adam/commands/devices/device.py +27 -0
- adam/commands/devices/device_app.py +146 -0
- adam/commands/devices/device_auit_log.py +43 -0
- adam/commands/devices/device_cass.py +145 -0
- adam/commands/devices/device_export.py +86 -0
- adam/commands/devices/device_postgres.py +109 -0
- adam/commands/devices/devices.py +25 -0
- adam/commands/export/__init__.py +0 -0
- adam/commands/export/clean_up_export_session.py +53 -0
- adam/commands/{frontend/teardown_frontend.py → export/clean_up_export_sessions.py} +9 -11
- adam/commands/export/drop_export_database.py +58 -0
- adam/commands/export/drop_export_databases.py +46 -0
- adam/commands/export/export.py +83 -0
- adam/commands/export/export_databases.py +170 -0
- adam/commands/export/export_select.py +85 -0
- adam/commands/export/export_select_x.py +54 -0
- adam/commands/export/export_use.py +55 -0
- adam/commands/export/exporter.py +364 -0
- adam/commands/export/import_session.py +68 -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 +63 -0
- adam/commands/export/show_export_databases.py +39 -0
- adam/commands/export/show_export_session.py +51 -0
- adam/commands/export/show_export_sessions.py +47 -0
- adam/commands/export/utils_export.py +291 -0
- adam/commands/help.py +12 -7
- adam/commands/issues.py +6 -0
- adam/commands/kubectl.py +41 -0
- adam/commands/login.py +9 -5
- adam/commands/logs.py +2 -1
- adam/commands/ls.py +4 -107
- adam/commands/medusa/medusa.py +2 -26
- adam/commands/medusa/medusa_backup.py +2 -2
- adam/commands/medusa/medusa_restore.py +3 -4
- adam/commands/medusa/medusa_show_backupjobs.py +4 -3
- adam/commands/medusa/medusa_show_restorejobs.py +3 -3
- adam/commands/nodetool.py +9 -4
- adam/commands/param_set.py +1 -1
- adam/commands/postgres/postgres.py +42 -43
- adam/commands/postgres/postgres_context.py +248 -0
- adam/commands/postgres/postgres_preview.py +0 -1
- adam/commands/postgres/postgres_utils.py +31 -0
- adam/commands/postgres/psql_completions.py +10 -0
- adam/commands/preview_table.py +18 -40
- adam/commands/pwd.py +2 -28
- adam/commands/reaper/reaper.py +4 -24
- adam/commands/reaper/reaper_restart.py +1 -1
- adam/commands/reaper/reaper_session.py +2 -2
- adam/commands/repair/repair.py +3 -27
- adam/commands/repair/repair_log.py +1 -1
- adam/commands/repair/repair_run.py +2 -2
- adam/commands/repair/repair_scan.py +2 -7
- adam/commands/repair/repair_stop.py +1 -1
- adam/commands/report.py +6 -0
- adam/commands/restart.py +2 -2
- adam/commands/rollout.py +1 -1
- adam/commands/shell.py +33 -0
- adam/commands/show/show.py +11 -26
- adam/commands/show/show_app_actions.py +3 -0
- adam/commands/show/show_app_id.py +1 -1
- adam/commands/show/show_app_queues.py +3 -2
- adam/commands/show/show_cassandra_status.py +3 -3
- adam/commands/show/show_cassandra_version.py +3 -3
- adam/commands/show/show_commands.py +4 -1
- adam/commands/show/show_host.py +33 -0
- adam/commands/show/show_login.py +3 -0
- adam/commands/show/show_processes.py +1 -1
- adam/commands/show/show_repairs.py +2 -2
- adam/commands/show/show_storage.py +1 -1
- adam/commands/watch.py +1 -1
- adam/config.py +16 -3
- adam/embedded_params.py +1 -1
- adam/pod_exec_result.py +10 -2
- adam/repl.py +132 -117
- adam/repl_commands.py +62 -18
- adam/repl_state.py +276 -55
- adam/sql/__init__.py +0 -0
- adam/sql/sql_completer.py +120 -0
- adam/sql/sql_state_machine.py +617 -0
- adam/sql/term_completer.py +76 -0
- adam/sso/authenticator.py +1 -1
- adam/sso/authn_ad.py +36 -56
- adam/sso/authn_okta.py +6 -32
- adam/sso/cred_cache.py +1 -1
- adam/sso/idp.py +74 -9
- adam/sso/idp_login.py +2 -2
- adam/sso/idp_session.py +10 -7
- adam/utils.py +85 -4
- adam/utils_athena.py +145 -0
- adam/utils_audits.py +102 -0
- adam/utils_k8s/__init__.py +0 -0
- adam/utils_k8s/app_clusters.py +33 -0
- adam/utils_k8s/app_pods.py +31 -0
- adam/{k8s_utils → utils_k8s}/cassandra_clusters.py +6 -21
- adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +12 -5
- adam/utils_k8s/config_maps.py +34 -0
- adam/utils_k8s/deployment.py +56 -0
- adam/{k8s_utils → utils_k8s}/jobs.py +1 -1
- adam/{k8s_utils → utils_k8s}/kube_context.py +1 -1
- adam/utils_k8s/pods.py +342 -0
- adam/{k8s_utils → utils_k8s}/secrets.py +4 -0
- adam/utils_k8s/service_accounts.py +169 -0
- adam/{k8s_utils → utils_k8s}/statefulsets.py +5 -4
- adam/{k8s_utils → utils_k8s}/volumes.py +9 -0
- 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 +101 -0
- adam/version.py +1 -1
- {kaqing-1.98.15.dist-info → kaqing-2.0.145.dist-info}/METADATA +1 -1
- kaqing-2.0.145.dist-info/RECORD +227 -0
- adam/commands/bash.py +0 -87
- adam/commands/cql_utils.py +0 -53
- adam/commands/devices.py +0 -89
- adam/commands/frontend/setup.py +0 -60
- adam/commands/frontend/setup_frontend.py +0 -58
- adam/commands/frontend/teardown.py +0 -61
- adam/commands/postgres/postgres_session.py +0 -225
- adam/commands/user_entry.py +0 -77
- adam/k8s_utils/pods.py +0 -211
- kaqing-1.98.15.dist-info/RECORD +0 -160
- /adam/commands/{frontend → audit}/__init__.py +0 -0
- /adam/{k8s_utils → commands/bash}/__init__.py +0 -0
- /adam/{medusa_show_restorejobs.py → commands/cql/__init__.py} +0 -0
- /adam/{k8s_utils → utils_k8s}/custom_resources.py +0 -0
- /adam/{k8s_utils → utils_k8s}/ingresses.py +0 -0
- /adam/{k8s_utils → utils_k8s}/services.py +0 -0
- {kaqing-1.98.15.dist-info → kaqing-2.0.145.dist-info}/WHEEL +0 -0
- {kaqing-1.98.15.dist-info → kaqing-2.0.145.dist-info}/entry_points.txt +0 -0
- {kaqing-1.98.15.dist-info → kaqing-2.0.145.dist-info}/top_level.txt +0 -0
adam/commands/help.py
CHANGED
|
@@ -23,20 +23,25 @@ class Help(Command):
|
|
|
23
23
|
return super().run(cmd, state)
|
|
24
24
|
|
|
25
25
|
def section(cmds : list[ReplCommands]):
|
|
26
|
-
|
|
26
|
+
sorted_cmds = sorted(cmds, key=lambda cmd: cmd.command())
|
|
27
|
+
return [f' {c.help(state)}' for c in sorted_cmds if c.help(state)]
|
|
27
28
|
|
|
28
29
|
lines = []
|
|
29
30
|
lines.append('NAVIGATION')
|
|
30
|
-
lines.append(' a: | c: | p:\t switch to another operational device: App, Cassandra or
|
|
31
|
+
lines.append(' a: | c: | l: | p: | x:\t switch to another operational device: App, Cassandra, Audit, Postgres or Export')
|
|
31
32
|
lines.extend(section(ReplCommands.navigation()))
|
|
32
|
-
lines.append('
|
|
33
|
-
lines.extend(section(ReplCommands.cassandra_check()))
|
|
34
|
-
lines.append('CASSANDRA OPERATIONS')
|
|
33
|
+
lines.append('CASSANDRA')
|
|
35
34
|
lines.extend(section(ReplCommands.cassandra_ops()))
|
|
35
|
+
lines.append('POSTGRES')
|
|
36
|
+
lines.extend(section(ReplCommands.postgres_ops()))
|
|
37
|
+
lines.append('APP')
|
|
38
|
+
lines.extend(section(ReplCommands.app_ops()))
|
|
39
|
+
lines.append('EXPORT DB')
|
|
40
|
+
lines.extend(section(ReplCommands.export_ops()))
|
|
41
|
+
lines.append('AUDIT')
|
|
42
|
+
lines.extend(section(ReplCommands.audit_ops()))
|
|
36
43
|
lines.append('TOOLS')
|
|
37
44
|
lines.extend(section(ReplCommands.tools()))
|
|
38
|
-
lines.append('APP')
|
|
39
|
-
lines.extend(section(ReplCommands.app()))
|
|
40
45
|
lines.append('')
|
|
41
46
|
lines.extend(section(ReplCommands.exit()))
|
|
42
47
|
|
adam/commands/issues.py
CHANGED
|
@@ -21,11 +21,17 @@ class Issues(Command):
|
|
|
21
21
|
def command(self):
|
|
22
22
|
return Issues.COMMAND
|
|
23
23
|
|
|
24
|
+
def required(self):
|
|
25
|
+
return ReplState.NON_L
|
|
26
|
+
|
|
24
27
|
def run(self, cmd: str, state: ReplState):
|
|
25
28
|
if not(args := self.args(cmd)):
|
|
26
29
|
return super().run(cmd, state)
|
|
27
30
|
|
|
28
31
|
state, args = self.apply_state(args, state)
|
|
32
|
+
if not self.validate_state(state):
|
|
33
|
+
return state
|
|
34
|
+
|
|
29
35
|
args, show = Command.extract_options(args, ['-s', '--show'])
|
|
30
36
|
|
|
31
37
|
results = run_checks(state.sts, state.namespace, state.pod, show_output=show)
|
adam/commands/kubectl.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.repl_state import ReplState, RequiredState
|
|
5
|
+
|
|
6
|
+
class Kubectl(Command):
|
|
7
|
+
COMMAND = 'k'
|
|
8
|
+
|
|
9
|
+
# the singleton pattern
|
|
10
|
+
def __new__(cls, *args, **kwargs):
|
|
11
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Kubectl, cls).__new__(cls)
|
|
12
|
+
|
|
13
|
+
return cls.instance
|
|
14
|
+
|
|
15
|
+
def __init__(self, successor: Command=None):
|
|
16
|
+
super().__init__(successor)
|
|
17
|
+
|
|
18
|
+
def command(self):
|
|
19
|
+
return Kubectl.COMMAND
|
|
20
|
+
|
|
21
|
+
def required(self):
|
|
22
|
+
return RequiredState.NAMESPACE
|
|
23
|
+
|
|
24
|
+
def run(self, cmd: str, state: ReplState):
|
|
25
|
+
if not(args := self.args(cmd)):
|
|
26
|
+
return super().run(cmd, state)
|
|
27
|
+
|
|
28
|
+
state, args = self.apply_state(args, state)
|
|
29
|
+
if not self.validate_state(state):
|
|
30
|
+
return state
|
|
31
|
+
|
|
32
|
+
subprocess.run(["kubectl"] + args)
|
|
33
|
+
|
|
34
|
+
return state
|
|
35
|
+
|
|
36
|
+
def completion(self, state: ReplState):
|
|
37
|
+
return super().completion(state)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def help(self, _: ReplState):
|
|
41
|
+
return f'{Kubectl.COMMAND} \t run a kubectl command'
|
adam/commands/login.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import signal
|
|
2
3
|
import traceback
|
|
3
4
|
|
|
@@ -7,7 +8,7 @@ from adam.config import Config
|
|
|
7
8
|
from adam.sso.idp import Idp
|
|
8
9
|
from adam.sso.idp_login import IdpLogin
|
|
9
10
|
from adam.commands.command import Command
|
|
10
|
-
from adam.repl_state import ReplState
|
|
11
|
+
from adam.repl_state import ReplState, RequiredState
|
|
11
12
|
from adam.utils import log, log2
|
|
12
13
|
|
|
13
14
|
class Login(Command):
|
|
@@ -25,6 +26,9 @@ class Login(Command):
|
|
|
25
26
|
def command(self):
|
|
26
27
|
return Login.COMMAND
|
|
27
28
|
|
|
29
|
+
def required(self):
|
|
30
|
+
return ReplState.NON_L
|
|
31
|
+
|
|
28
32
|
def run(self, cmd: str, state: ReplState):
|
|
29
33
|
def custom_handler(signum, frame):
|
|
30
34
|
AppSession.ctrl_c_entered = True
|
|
@@ -37,9 +41,9 @@ class Login(Command):
|
|
|
37
41
|
state, args = self.apply_state(args, state)
|
|
38
42
|
args, debug = Command.extract_options(args, ['d'])
|
|
39
43
|
if debug:
|
|
40
|
-
Config().set('debug
|
|
44
|
+
Config().set('debug', True)
|
|
41
45
|
|
|
42
|
-
username: str =
|
|
46
|
+
username: str = os.getenv('USERNAME')
|
|
43
47
|
if len(args) > 0:
|
|
44
48
|
username = args[0]
|
|
45
49
|
|
|
@@ -58,8 +62,8 @@ class Login(Command):
|
|
|
58
62
|
|
|
59
63
|
return state
|
|
60
64
|
|
|
61
|
-
def completion(self,
|
|
62
|
-
return
|
|
65
|
+
def completion(self, state: ReplState):
|
|
66
|
+
return super().completion(state)
|
|
63
67
|
|
|
64
68
|
def help(self, _: ReplState):
|
|
65
69
|
return f'{Login.COMMAND}\t SSO login'
|
adam/commands/logs.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.config import Config
|
|
3
|
-
from adam.
|
|
3
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
|
|
6
6
|
class Logs(Command):
|
|
@@ -33,6 +33,7 @@ class Logs(Command):
|
|
|
33
33
|
return CassandraNodes.exec(state.pod, state.namespace, f'cat {path}')
|
|
34
34
|
|
|
35
35
|
def completion(self, _: ReplState):
|
|
36
|
+
# available only on cli
|
|
36
37
|
return {}
|
|
37
38
|
|
|
38
39
|
def help(self, _: ReplState):
|
adam/commands/ls.py
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
1
|
import copy
|
|
2
|
-
import re
|
|
3
2
|
|
|
4
3
|
from adam.commands.command import Command
|
|
5
|
-
from adam.commands.
|
|
6
|
-
from adam.commands.cqlsh import Cqlsh
|
|
7
|
-
from adam.commands.postgres.postgres_session import PostgresSession
|
|
8
|
-
from adam.config import Config
|
|
9
|
-
from adam.k8s_utils.custom_resources import CustomResources
|
|
10
|
-
from adam.k8s_utils.ingresses import Ingresses
|
|
11
|
-
from adam.k8s_utils.kube_context import KubeContext
|
|
12
|
-
from adam.k8s_utils.services import Services
|
|
13
|
-
from adam.k8s_utils.statefulsets import StatefulSets
|
|
14
|
-
from adam.pod_exec_result import PodExecResult
|
|
4
|
+
from adam.commands.devices.devices import Devices
|
|
15
5
|
from adam.repl_state import ReplState
|
|
16
|
-
from adam.utils import lines_to_tabular, log, log2
|
|
17
|
-
from adam.apps import Apps
|
|
18
6
|
|
|
19
7
|
class Ls(Command):
|
|
20
8
|
COMMAND = 'ls'
|
|
@@ -43,103 +31,12 @@ class Ls(Command):
|
|
|
43
31
|
state = copy.copy(state)
|
|
44
32
|
state.device = arg.replace(':', '')
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
if state.pg_path:
|
|
48
|
-
pg = PostgresSession(state.namespace, state.pg_path)
|
|
49
|
-
if pg.db:
|
|
50
|
-
self.show_pg_tables(pg)
|
|
51
|
-
else:
|
|
52
|
-
self.show_pg_databases(pg)
|
|
53
|
-
else:
|
|
54
|
-
self.show_pg_hosts(state)
|
|
55
|
-
elif state.device == ReplState.A:
|
|
56
|
-
if state.app_env:
|
|
57
|
-
def line(n: str, ns: str):
|
|
58
|
-
host = Ingresses.get_host(Config().get('app.login.ingress', '{app_id}-k8singr-appleader-001').replace('{app_id}', f'{ns}-{n}'), ns)
|
|
59
|
-
if not host:
|
|
60
|
-
return None
|
|
61
|
-
|
|
62
|
-
endpoint = Config().get('app.login.url', 'https://{host}/{env}/{app}').replace('{host}', host).replace('{env}', state.app_env).replace('{app}', 'c3')
|
|
63
|
-
if not endpoint:
|
|
64
|
-
return None
|
|
65
|
-
|
|
66
|
-
return f"{n.split('-')[1]},{Ingresses.get_host(f'{ns}-{n}-k8singr-appleader-001', ns)},{endpoint}"
|
|
67
|
-
|
|
68
|
-
svcs = [l for l in [line(n, ns) for n, ns in Apps.apps(state.app_env)] if l]
|
|
69
|
-
|
|
70
|
-
log(lines_to_tabular(svcs, 'APP,HOST,ENDPOINT', separator=','))
|
|
71
|
-
else:
|
|
72
|
-
svcs = [n for n, ns in Apps.envs()]
|
|
73
|
-
|
|
74
|
-
log(lines_to_tabular(svcs, 'ENV', separator=','))
|
|
75
|
-
else:
|
|
76
|
-
if state.pod:
|
|
77
|
-
r: PodExecResult = Cqlsh().run(f'cql describe tables', state)
|
|
78
|
-
if r.stderr:
|
|
79
|
-
log(r.stderr)
|
|
80
|
-
log(r.stdout)
|
|
81
|
-
elif state.sts and state.namespace:
|
|
82
|
-
show_pods(StatefulSets.pods(state.sts, state.namespace), state.namespace, show_namespace=not KubeContext.in_cluster_namespace())
|
|
83
|
-
show_rollout(state.sts, state.namespace)
|
|
84
|
-
else:
|
|
85
|
-
self.show_statefulsets()
|
|
34
|
+
Devices.device(state).ls(cmd, state)
|
|
86
35
|
|
|
87
36
|
return state
|
|
88
37
|
|
|
89
|
-
def show_statefulsets(self):
|
|
90
|
-
ss = StatefulSets.list_sts_names(show_namespace=not KubeContext.in_cluster_namespace())
|
|
91
|
-
if len(ss) == 0:
|
|
92
|
-
log2('No cassandra statefulsets found.')
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
app_ids = CustomResources.get_app_ids()
|
|
96
|
-
list = []
|
|
97
|
-
for s in ss:
|
|
98
|
-
cr_name = CustomResources.get_cr_name(s)
|
|
99
|
-
app_id = 'Unknown'
|
|
100
|
-
if cr_name in app_ids:
|
|
101
|
-
app_id = app_ids[cr_name]
|
|
102
|
-
list.append(f"{s} {app_id}")
|
|
103
|
-
|
|
104
|
-
header = 'STATEFULSET_NAME@NAMESPACE APP_ID'
|
|
105
|
-
if KubeContext.in_cluster_namespace():
|
|
106
|
-
header = 'STATEFULSET_NAME APP_ID'
|
|
107
|
-
log(lines_to_tabular(list, header))
|
|
108
|
-
|
|
109
|
-
def show_pg_hosts(self, state: ReplState):
|
|
110
|
-
if state.namespace:
|
|
111
|
-
def line(pg: PostgresSession):
|
|
112
|
-
return f'{pg.directory()},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
|
|
113
|
-
|
|
114
|
-
lines = [line(PostgresSession(state.namespace, pg)) for pg in PostgresSession.hosts(state.namespace)]
|
|
115
|
-
|
|
116
|
-
log(lines_to_tabular(lines, 'NAME,ENDPOINT,USERNAME,PASSWORD', separator=','))
|
|
117
|
-
else:
|
|
118
|
-
def line(pg: PostgresSession):
|
|
119
|
-
return f'{pg.directory()},{pg.namespace},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
|
|
120
|
-
|
|
121
|
-
lines = [line(PostgresSession(state.namespace, pg)) for pg in PostgresSession.hosts(state.namespace)]
|
|
122
|
-
|
|
123
|
-
log(lines_to_tabular(lines, 'NAME,NAMESPACE,ENDPOINT,USERNAME,PASSWORD', separator=','))
|
|
124
|
-
|
|
125
|
-
def show_pg_databases(self, pg: PostgresSession):
|
|
126
|
-
lines = [db["name"] for db in pg.databases() if db["owner"] == PostgresSession.default_owner()]
|
|
127
|
-
|
|
128
|
-
log(lines_to_tabular(lines, 'DATABASE', separator=','))
|
|
129
|
-
|
|
130
|
-
def show_pg_tables(self, pg: PostgresSession):
|
|
131
|
-
lines = [db["name"] for db in pg.tables() if db["schema"] == PostgresSession.default_schema()]
|
|
132
|
-
|
|
133
|
-
log(lines_to_tabular(lines, 'NAME', separator=','))
|
|
134
|
-
|
|
135
38
|
def completion(self, state: ReplState):
|
|
136
|
-
|
|
137
|
-
return {}
|
|
138
|
-
|
|
139
|
-
if not state.sts:
|
|
140
|
-
return {Ls.COMMAND: {n: None for n in StatefulSets.list_sts_names()}}
|
|
141
|
-
|
|
142
|
-
return {Ls.COMMAND: None}
|
|
39
|
+
return Devices.device(state).ls_completion(Ls.COMMAND, state, default = super().completion(state))
|
|
143
40
|
|
|
144
41
|
def help(self, _: ReplState):
|
|
145
|
-
return f'{Ls.COMMAND} [device:]\t list apps, envs, clusters, nodes, pg hosts or
|
|
42
|
+
return f'{Ls.COMMAND} [device:]\t list apps, envs, clusters, nodes, pg hosts/databases or export databases'
|
adam/commands/medusa/medusa.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
3
|
from adam.commands.command import Command
|
|
4
|
-
from adam.commands.command_helpers import ClusterCommandHelper
|
|
5
4
|
from .medusa_backup import MedusaBackup
|
|
6
5
|
from .medusa_restore import MedusaRestore
|
|
7
6
|
from .medusa_show_backupjobs import MedusaShowBackupJobs
|
|
8
7
|
from .medusa_show_restorejobs import MedusaShowRestoreJobs
|
|
9
8
|
from adam.repl_state import ReplState, RequiredState
|
|
10
|
-
from adam.utils import lines_to_tabular, log, log2
|
|
11
9
|
|
|
12
10
|
class Medusa(Command):
|
|
13
11
|
COMMAND = 'medusa'
|
|
@@ -31,20 +29,7 @@ class Medusa(Command):
|
|
|
31
29
|
if not(args := self.args(cmd)):
|
|
32
30
|
return super().run(cmd, state)
|
|
33
31
|
|
|
34
|
-
state, args
|
|
35
|
-
if not self.validate_state(state):
|
|
36
|
-
return state
|
|
37
|
-
|
|
38
|
-
if state.in_repl:
|
|
39
|
-
log(lines_to_tabular([c.help(ReplState()) for c in Medusa.cmd_list()], separator=':'))
|
|
40
|
-
|
|
41
|
-
return 'command-missing'
|
|
42
|
-
else:
|
|
43
|
-
# head with the Chain of Responsibility pattern
|
|
44
|
-
cmds = Command.chain(Medusa.cmd_list())
|
|
45
|
-
if not cmds.run(cmd, state):
|
|
46
|
-
log2('* Command is missing.')
|
|
47
|
-
Command.display_help()
|
|
32
|
+
return super().intermediate_run(cmd, state, args, Medusa.cmd_list())
|
|
48
33
|
|
|
49
34
|
def cmd_list():
|
|
50
35
|
return [MedusaBackup(), MedusaRestore(), MedusaShowBackupJobs(), MedusaShowRestoreJobs()]
|
|
@@ -55,15 +40,6 @@ class Medusa(Command):
|
|
|
55
40
|
|
|
56
41
|
return {}
|
|
57
42
|
|
|
58
|
-
def help(self, _: ReplState):
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
43
|
class MedusaCommandHelper(click.Command):
|
|
62
44
|
def get_help(self, ctx: click.Context):
|
|
63
|
-
|
|
64
|
-
log()
|
|
65
|
-
log('Sub-Commands:')
|
|
66
|
-
|
|
67
|
-
log(lines_to_tabular([c.help(ReplState()).replace(f'{Medusa.COMMAND} ', ' ', 1) for c in Medusa.cmd_list()], separator=':'))
|
|
68
|
-
log()
|
|
69
|
-
ClusterCommandHelper.cluster_help()
|
|
45
|
+
Command.intermediate_help(super().get_help(ctx), Medusa.COMMAND, Medusa.cmd_list(), show_cluster_help=True)
|
|
@@ -2,9 +2,9 @@ from datetime import datetime
|
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
4
|
from adam.commands.command import Command
|
|
5
|
-
from adam.
|
|
5
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
6
6
|
from adam.repl_state import ReplState, RequiredState
|
|
7
|
-
from adam.
|
|
7
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
8
8
|
from adam.utils import log2
|
|
9
9
|
|
|
10
10
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
|
|
3
3
|
from adam.commands.command import Command
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
5
5
|
from adam.repl_state import ReplState, RequiredState
|
|
6
|
-
from adam.
|
|
6
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
7
7
|
from adam.config import Config
|
|
8
8
|
from adam.utils import lines_to_tabular, log2
|
|
9
9
|
|
|
@@ -59,8 +59,7 @@ class MedusaRestore(Command):
|
|
|
59
59
|
now_dtformat = datetime.now().strftime("%Y-%m-%d.%H.%M.%S")
|
|
60
60
|
rtname = 'medusa-' + now_dtformat + '-restore-from-' + bkname
|
|
61
61
|
try:
|
|
62
|
-
|
|
63
|
-
# CustomResources.create_medusa_restorejob(rtname, bkname, dc, ns)
|
|
62
|
+
CustomResources.create_medusa_restorejob(rtname, bkname, dc, ns)
|
|
64
63
|
except Exception as e:
|
|
65
64
|
log2("Exception: MedusaRestore failed: %s\n" % e)
|
|
66
65
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
3
3
|
from adam.repl_state import ReplState, RequiredState
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
5
5
|
from adam.utils import lines_to_tabular, log2
|
|
6
6
|
|
|
7
7
|
|
|
@@ -29,6 +29,7 @@ class MedusaShowBackupJobs(Command):
|
|
|
29
29
|
state, args = self.apply_state(args, state)
|
|
30
30
|
if not self.validate_state(state):
|
|
31
31
|
return state
|
|
32
|
+
|
|
32
33
|
ns = state.namespace
|
|
33
34
|
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
34
35
|
if not dc:
|
|
@@ -49,4 +50,4 @@ class MedusaShowBackupJobs(Command):
|
|
|
49
50
|
return {}
|
|
50
51
|
|
|
51
52
|
def help(self, _: ReplState):
|
|
52
|
-
return f'{MedusaShowBackupJobs.COMMAND}\t
|
|
53
|
+
return f'{MedusaShowBackupJobs.COMMAND}\t show Medusa backups'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
3
3
|
from adam.repl_state import ReplState, RequiredState
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
5
5
|
from adam.utils import lines_to_tabular, log2
|
|
6
6
|
|
|
7
7
|
class MedusaShowRestoreJobs(Command):
|
|
@@ -49,4 +49,4 @@ class MedusaShowRestoreJobs(Command):
|
|
|
49
49
|
return {}
|
|
50
50
|
|
|
51
51
|
def help(self, _: ReplState):
|
|
52
|
-
return f'{MedusaShowRestoreJobs.COMMAND}\t
|
|
52
|
+
return f'{MedusaShowRestoreJobs.COMMAND}\t show Medusa restores'
|
adam/commands/nodetool.py
CHANGED
|
@@ -4,10 +4,11 @@ from adam.commands.command import Command
|
|
|
4
4
|
from adam.commands.command_helpers import ClusterOrPodCommandHelper
|
|
5
5
|
from adam.commands.nodetool_commands import NODETOOL_COMMANDS
|
|
6
6
|
from adam.config import Config
|
|
7
|
-
from adam.
|
|
8
|
-
from adam.
|
|
7
|
+
from adam.utils_k8s.cassandra_clusters import CassandraClusters
|
|
8
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
9
9
|
from adam.repl_state import ReplState, RequiredState
|
|
10
10
|
from adam.utils import log
|
|
11
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
11
12
|
|
|
12
13
|
class NodeTool(Command):
|
|
13
14
|
COMMAND = 'nodetool'
|
|
@@ -43,14 +44,18 @@ class NodeTool(Command):
|
|
|
43
44
|
elif state.sts:
|
|
44
45
|
return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool', show_out=True)
|
|
45
46
|
|
|
47
|
+
return state
|
|
48
|
+
|
|
46
49
|
def completion(self, state: ReplState):
|
|
47
50
|
if state.pod or state.sts:
|
|
48
|
-
|
|
51
|
+
d = {c: {'&': None} for c in NODETOOL_COMMANDS}
|
|
52
|
+
return {NodeTool.COMMAND: {'help': None} | d} | \
|
|
53
|
+
{f'@{p}': {NodeTool.COMMAND: d} for p in StatefulSets.pod_names(state.sts, state.namespace)}
|
|
49
54
|
|
|
50
55
|
return {}
|
|
51
56
|
|
|
52
57
|
def help(self, _: ReplState):
|
|
53
|
-
return f'{NodeTool.COMMAND} <sub-command
|
|
58
|
+
return f'{NodeTool.COMMAND} <sub-command> [&]\t run nodetool with arguments'
|
|
54
59
|
|
|
55
60
|
class NodeToolCommandHelper(click.Command):
|
|
56
61
|
def get_help(self, ctx: click.Context):
|
adam/commands/param_set.py
CHANGED
|
@@ -38,7 +38,7 @@ class SetParam(Command):
|
|
|
38
38
|
return value
|
|
39
39
|
|
|
40
40
|
def completion(self, _: ReplState):
|
|
41
|
-
return {SetParam.COMMAND: {key: None for key in Config().keys()}}
|
|
41
|
+
return {SetParam.COMMAND: {key: ({'true': None, 'false': None} if Config().get(key, None) in [True, False] else None) for key in Config().keys()}}
|
|
42
42
|
|
|
43
43
|
def help(self, _: ReplState):
|
|
44
44
|
return f"{SetParam.COMMAND} <key> <value>\t sets a Kaqing parameter to a different value"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
3
|
from adam.commands.command import Command
|
|
4
|
-
from adam.commands.
|
|
4
|
+
from adam.commands.postgres.psql_completions import psql_completions
|
|
5
|
+
from adam.commands.postgres.postgres_utils import pg_table_names
|
|
5
6
|
from .postgres_ls import PostgresLs
|
|
6
7
|
from .postgres_preview import PostgresPreview
|
|
7
|
-
from .
|
|
8
|
+
from .postgres_context import PostgresContext
|
|
8
9
|
from adam.repl_state import ReplState
|
|
9
|
-
from adam.utils import
|
|
10
|
+
from adam.utils import log, log2
|
|
10
11
|
|
|
11
12
|
class Postgres(Command):
|
|
12
13
|
COMMAND = 'pg'
|
|
@@ -30,35 +31,27 @@ class Postgres(Command):
|
|
|
30
31
|
|
|
31
32
|
state, args = self.apply_state(args, state)
|
|
32
33
|
|
|
33
|
-
if
|
|
34
|
-
if
|
|
34
|
+
if not args:
|
|
35
|
+
if state.in_repl:
|
|
35
36
|
log2('Please use SQL statement. e.g. pg \l')
|
|
36
|
-
|
|
37
|
-
return 'command-missing'
|
|
38
37
|
else:
|
|
39
|
-
self.run_sql(state, args)
|
|
40
|
-
else:
|
|
41
|
-
if not args:
|
|
42
38
|
log2('* Command or SQL statements is missing.')
|
|
43
39
|
Command.display_help()
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
else:
|
|
47
|
-
# head with the Chain of Responsibility pattern
|
|
48
|
-
cmds = Command.chain(Postgres.cmd_list())
|
|
49
|
-
if not cmds.run(cmd, state) :
|
|
50
|
-
if not args:
|
|
51
|
-
log2('* Command or SQL statements is missing.')
|
|
52
|
-
Command.display_help()
|
|
41
|
+
return 'command-missing'
|
|
53
42
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
if state.in_repl:
|
|
44
|
+
self.run_sql(state, args)
|
|
45
|
+
else:
|
|
46
|
+
# head with the Chain of Responsibility pattern
|
|
47
|
+
cmds = Command.chain(Postgres.cmd_list())
|
|
48
|
+
if not cmds.run(cmd, state) :
|
|
49
|
+
self.run_sql(state, args)
|
|
57
50
|
|
|
58
51
|
return state
|
|
59
52
|
|
|
60
53
|
def cmd_list():
|
|
61
|
-
return [PostgresLs(), PostgresPreview()]
|
|
54
|
+
return [PostgresLs(), PostgresPreview(), PostgresPg()]
|
|
62
55
|
|
|
63
56
|
def run_sql(self, state: ReplState, args: list[str]):
|
|
64
57
|
if not state.pg_path:
|
|
@@ -69,21 +62,23 @@ class Postgres(Command):
|
|
|
69
62
|
|
|
70
63
|
return state
|
|
71
64
|
|
|
72
|
-
|
|
65
|
+
background = False
|
|
66
|
+
if args and args[-1] == '&':
|
|
67
|
+
args = args[:-1]
|
|
68
|
+
background = True
|
|
69
|
+
|
|
70
|
+
PostgresContext.apply(state.namespace, state.pg_path).run_sql(' '.join(args), background=background)
|
|
73
71
|
|
|
74
72
|
def completion(self, state: ReplState):
|
|
73
|
+
if state.device != state.P:
|
|
74
|
+
# conflicts with cql completions
|
|
75
|
+
return {}
|
|
76
|
+
|
|
75
77
|
leaf = {}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
'\dt': None,
|
|
81
|
-
'\du': None,
|
|
82
|
-
'delete': {'from': None},
|
|
83
|
-
'insert': {'into': None},
|
|
84
|
-
'select': None,
|
|
85
|
-
'update': None,
|
|
86
|
-
}
|
|
78
|
+
session = PostgresContext.apply(state.namespace, state.pg_path)
|
|
79
|
+
if session.db:
|
|
80
|
+
if pg_table_names(state.namespace, state.pg_path):
|
|
81
|
+
leaf = psql_completions(state.namespace, state.pg_path)
|
|
87
82
|
elif state.pg_path:
|
|
88
83
|
leaf = {
|
|
89
84
|
'\h': None,
|
|
@@ -96,18 +91,22 @@ class Postgres(Command):
|
|
|
96
91
|
return {}
|
|
97
92
|
|
|
98
93
|
def help(self, _: ReplState):
|
|
99
|
-
return f'
|
|
94
|
+
return f'<sql-statements> [&]\t run queries on Postgres databases'
|
|
100
95
|
|
|
101
96
|
class PostgresCommandHelper(click.Command):
|
|
102
97
|
def get_help(self, ctx: click.Context):
|
|
103
|
-
|
|
104
|
-
log()
|
|
105
|
-
log('Sub-Commands:')
|
|
106
|
-
|
|
107
|
-
log(lines_to_tabular([c.help(ReplState()).replace(f'{Postgres.COMMAND} ', ' ', 1) for c in Postgres.cmd_list()], separator='\t'))
|
|
108
|
-
log()
|
|
109
|
-
ClusterCommandHelper.cluster_help()
|
|
98
|
+
Command.intermediate_help(super().get_help(ctx), Postgres.COMMAND, Postgres.cmd_list(), show_cluster_help=True)
|
|
110
99
|
log('PG-Name: Kubernetes secret for Postgres credentials')
|
|
111
100
|
log(' e.g. stgawsscpsr-c3-c3-k8spg-cs-001')
|
|
112
101
|
log('Database: Postgres database name within a host')
|
|
113
|
-
log(' e.g. stgawsscpsr_c3_c3')
|
|
102
|
+
log(' e.g. stgawsscpsr_c3_c3')
|
|
103
|
+
|
|
104
|
+
# No action body, only for a help entry and auto-completion
|
|
105
|
+
class PostgresPg(Command):
|
|
106
|
+
COMMAND = 'pg'
|
|
107
|
+
|
|
108
|
+
def command(self):
|
|
109
|
+
return PostgresPg.COMMAND
|
|
110
|
+
|
|
111
|
+
def help(self, _: ReplState):
|
|
112
|
+
return f'pg <sql-statements>\t run queries on Postgres databases'
|