kaqing 2.0.110__py3-none-any.whl → 2.0.214__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/__init__.py +0 -2
- adam/app_session.py +9 -12
- adam/apps.py +18 -4
- adam/batch.py +19 -19
- adam/checks/check_utils.py +16 -46
- adam/checks/cpu.py +7 -1
- adam/checks/cpu_metrics.py +52 -0
- adam/checks/disk.py +2 -3
- adam/columns/columns.py +3 -1
- adam/columns/cpu.py +3 -1
- adam/columns/cpu_metrics.py +22 -0
- adam/columns/memory.py +3 -4
- adam/commands/__init__.py +24 -0
- adam/commands/app/app.py +38 -0
- adam/commands/{app_ping.py → app/app_ping.py} +7 -13
- adam/commands/{login.py → app/login.py} +22 -24
- adam/commands/app/show_app_actions.py +49 -0
- adam/commands/{show → app}/show_app_id.py +8 -11
- adam/commands/{show → app}/show_app_queues.py +7 -14
- adam/commands/app/show_login.py +56 -0
- adam/commands/app/utils_app.py +106 -0
- adam/commands/audit/audit.py +22 -40
- adam/commands/audit/audit_repair_tables.py +15 -19
- adam/commands/audit/audit_run.py +15 -22
- adam/commands/audit/completions_l.py +15 -0
- adam/commands/audit/show_last10.py +4 -18
- adam/commands/audit/show_slow10.py +4 -17
- adam/commands/audit/show_top10.py +4 -16
- adam/commands/audit/utils_show_top10.py +15 -3
- 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/cassandra/__init__.py +0 -0
- adam/commands/cassandra/download_cassandra_log.py +45 -0
- adam/commands/{restart.py → cassandra/restart_cluster.py} +12 -26
- adam/commands/cassandra/restart_node.py +51 -0
- adam/commands/cassandra/restart_nodes.py +47 -0
- adam/commands/{rollout.py → cassandra/rollout.py} +20 -25
- adam/commands/cassandra/show_cassandra_repairs.py +37 -0
- adam/commands/cassandra/show_cassandra_status.py +117 -0
- adam/commands/{show → cassandra}/show_cassandra_version.py +5 -18
- adam/commands/cassandra/show_processes.py +50 -0
- adam/commands/cassandra/show_storage.py +44 -0
- adam/commands/{watch.py → cassandra/watch.py} +26 -29
- adam/commands/cli/__init__.py +0 -0
- adam/commands/{cli_commands.py → cli/cli_commands.py} +8 -4
- adam/commands/cli/clipboard_copy.py +86 -0
- adam/commands/cli/show_cli_commands.py +56 -0
- adam/commands/code.py +57 -0
- adam/commands/command.py +211 -40
- adam/commands/commands_utils.py +20 -27
- adam/commands/config/__init__.py +0 -0
- adam/commands/{param_get.py → config/param_get.py} +11 -14
- adam/commands/{param_set.py → config/param_set.py} +8 -12
- adam/commands/{show → config}/show_params.py +2 -5
- adam/commands/cql/alter_tables.py +66 -0
- adam/commands/cql/completions_c.py +29 -0
- adam/commands/cql/cqlsh.py +10 -32
- adam/commands/cql/utils_cql.py +306 -0
- adam/commands/debug/__init__.py +0 -0
- adam/commands/debug/debug.py +22 -0
- adam/commands/debug/debug_completes.py +35 -0
- adam/commands/debug/debug_timings.py +35 -0
- adam/commands/debug/show_offloaded_completes.py +45 -0
- adam/commands/deploy/code_start.py +7 -10
- adam/commands/deploy/code_stop.py +4 -21
- adam/commands/deploy/code_utils.py +3 -3
- adam/commands/deploy/deploy.py +4 -27
- adam/commands/deploy/deploy_frontend.py +14 -17
- adam/commands/deploy/deploy_pg_agent.py +3 -6
- adam/commands/deploy/deploy_pod.py +65 -73
- adam/commands/deploy/deploy_utils.py +14 -24
- adam/commands/deploy/undeploy.py +4 -27
- adam/commands/deploy/undeploy_frontend.py +4 -7
- adam/commands/deploy/undeploy_pg_agent.py +6 -8
- adam/commands/deploy/undeploy_pod.py +11 -12
- adam/commands/devices/__init__.py +0 -0
- adam/commands/devices/device.py +149 -0
- adam/commands/devices/device_app.py +163 -0
- adam/commands/devices/device_auit_log.py +49 -0
- adam/commands/devices/device_cass.py +179 -0
- adam/commands/devices/device_export.py +87 -0
- adam/commands/devices/device_postgres.py +160 -0
- adam/commands/devices/devices.py +25 -0
- adam/commands/diag/__init__.py +0 -0
- adam/commands/{check.py → diag/check.py} +16 -25
- adam/commands/diag/generate_report.py +52 -0
- adam/commands/diag/issues.py +43 -0
- adam/commands/exit.py +1 -4
- adam/commands/export/__init__.py +0 -0
- adam/commands/export/clean_up_all_export_sessions.py +37 -0
- adam/commands/export/clean_up_export_sessions.py +39 -0
- adam/commands/export/completions_x.py +11 -0
- adam/commands/export/download_export_session.py +40 -0
- adam/commands/export/drop_export_database.py +39 -0
- adam/commands/export/drop_export_databases.py +37 -0
- adam/commands/export/export.py +37 -0
- adam/commands/export/export_databases.py +251 -0
- adam/commands/export/export_select.py +34 -0
- adam/commands/export/export_sessions.py +210 -0
- adam/commands/export/export_use.py +49 -0
- adam/commands/export/export_x_select.py +48 -0
- adam/commands/export/exporter.py +419 -0
- adam/commands/export/import_files.py +44 -0
- adam/commands/export/import_session.py +40 -0
- adam/commands/export/importer.py +81 -0
- adam/commands/export/importer_athena.py +157 -0
- adam/commands/export/importer_sqlite.py +78 -0
- adam/commands/export/show_column_counts.py +45 -0
- adam/commands/export/show_export_databases.py +39 -0
- adam/commands/export/show_export_session.py +39 -0
- adam/commands/export/show_export_sessions.py +37 -0
- adam/commands/export/utils_export.py +366 -0
- adam/commands/fs/__init__.py +0 -0
- adam/commands/fs/cat.py +36 -0
- adam/commands/fs/cat_local.py +42 -0
- adam/commands/fs/cd.py +41 -0
- adam/commands/fs/download_file.py +47 -0
- adam/commands/fs/find_files.py +51 -0
- adam/commands/fs/find_processes.py +76 -0
- adam/commands/fs/head.py +36 -0
- adam/commands/fs/ls.py +41 -0
- adam/commands/fs/ls_local.py +40 -0
- adam/commands/fs/pwd.py +45 -0
- adam/commands/fs/rm.py +18 -0
- adam/commands/fs/rm_downloads.py +39 -0
- adam/commands/fs/rm_logs.py +38 -0
- adam/commands/{shell.py → fs/shell.py} +12 -4
- adam/commands/{show → fs}/show_adam.py +3 -3
- adam/commands/{show → fs}/show_host.py +1 -1
- adam/commands/help.py +5 -3
- adam/commands/intermediate_command.py +52 -0
- adam/commands/kubectl.py +38 -0
- adam/commands/medusa/medusa.py +4 -22
- adam/commands/medusa/medusa_backup.py +20 -27
- adam/commands/medusa/medusa_restore.py +35 -48
- adam/commands/medusa/medusa_show_backupjobs.py +16 -18
- adam/commands/medusa/medusa_show_restorejobs.py +13 -18
- adam/commands/medusa/utils_medusa.py +15 -0
- adam/commands/nodetool/__init__.py +0 -0
- adam/commands/{nodetool.py → nodetool/nodetool.py} +9 -20
- adam/commands/postgres/completions_p.py +22 -0
- adam/commands/postgres/postgres.py +47 -55
- adam/commands/postgres/postgres_databases.py +269 -0
- adam/commands/postgres/postgres_ls.py +5 -9
- adam/commands/postgres/postgres_preview.py +5 -9
- adam/commands/postgres/utils_postgres.py +80 -0
- adam/commands/preview_table.py +8 -44
- adam/commands/reaper/reaper.py +4 -27
- adam/commands/reaper/reaper_forward.py +49 -56
- adam/commands/reaper/reaper_forward_session.py +6 -0
- adam/commands/reaper/reaper_forward_stop.py +10 -16
- adam/commands/reaper/reaper_restart.py +7 -14
- adam/commands/reaper/reaper_run_abort.py +8 -33
- adam/commands/reaper/reaper_runs.py +43 -58
- adam/commands/reaper/reaper_runs_abort.py +29 -49
- adam/commands/reaper/reaper_schedule_activate.py +14 -33
- adam/commands/reaper/reaper_schedule_start.py +9 -33
- adam/commands/reaper/reaper_schedule_stop.py +9 -33
- adam/commands/reaper/reaper_schedules.py +4 -14
- adam/commands/reaper/reaper_status.py +8 -16
- adam/commands/reaper/utils_reaper.py +203 -0
- adam/commands/repair/repair.py +4 -22
- adam/commands/repair/repair_log.py +5 -11
- adam/commands/repair/repair_run.py +27 -34
- adam/commands/repair/repair_scan.py +32 -40
- adam/commands/repair/repair_stop.py +5 -12
- adam/commands/show.py +40 -0
- adam/config.py +5 -15
- adam/embedded_params.py +1 -1
- adam/log.py +4 -4
- adam/repl.py +83 -116
- adam/repl_commands.py +86 -45
- adam/repl_session.py +9 -1
- adam/repl_state.py +176 -40
- adam/sql/async_executor.py +62 -0
- adam/sql/lark_completer.py +286 -0
- adam/sql/lark_parser.py +604 -0
- adam/sql/qingl.lark +1076 -0
- adam/sql/sql_completer.py +52 -27
- adam/sql/sql_state_machine.py +131 -19
- adam/sso/authn_ad.py +6 -8
- adam/sso/authn_okta.py +4 -6
- adam/sso/cred_cache.py +4 -9
- adam/sso/idp.py +9 -12
- adam/utils.py +670 -31
- adam/utils_athena.py +145 -0
- adam/utils_audits.py +12 -103
- adam/utils_issues.py +32 -0
- adam/utils_k8s/app_clusters.py +35 -0
- adam/utils_k8s/app_pods.py +41 -0
- adam/utils_k8s/cassandra_clusters.py +35 -20
- adam/utils_k8s/cassandra_nodes.py +15 -6
- adam/utils_k8s/custom_resources.py +16 -17
- adam/utils_k8s/ingresses.py +2 -2
- adam/utils_k8s/jobs.py +7 -11
- adam/utils_k8s/k8s.py +96 -0
- adam/utils_k8s/kube_context.py +3 -6
- adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +13 -4
- adam/utils_k8s/pods.py +159 -89
- adam/utils_k8s/secrets.py +4 -4
- adam/utils_k8s/service_accounts.py +5 -4
- adam/utils_k8s/services.py +2 -2
- adam/utils_k8s/statefulsets.py +6 -14
- adam/utils_local.py +80 -0
- adam/utils_net.py +4 -4
- adam/utils_repl/__init__.py +0 -0
- adam/utils_repl/appendable_completer.py +6 -0
- adam/utils_repl/automata_completer.py +48 -0
- adam/utils_repl/repl_completer.py +93 -0
- adam/utils_repl/state_machine.py +173 -0
- adam/utils_sqlite.py +132 -0
- adam/version.py +1 -1
- {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/METADATA +1 -1
- kaqing-2.0.214.dist-info/RECORD +272 -0
- kaqing-2.0.214.dist-info/top_level.txt +2 -0
- teddy/__init__.py +0 -0
- teddy/lark_parser.py +436 -0
- teddy/lark_parser2.py +618 -0
- adam/commands/alter_tables.py +0 -81
- adam/commands/app.py +0 -67
- adam/commands/bash.py +0 -150
- adam/commands/cd.py +0 -125
- adam/commands/cp.py +0 -95
- adam/commands/cql/cql_completions.py +0 -15
- adam/commands/cql/cql_utils.py +0 -112
- adam/commands/devices.py +0 -118
- adam/commands/issues.py +0 -75
- adam/commands/logs.py +0 -40
- adam/commands/ls.py +0 -146
- adam/commands/postgres/postgres_context.py +0 -239
- adam/commands/postgres/postgres_utils.py +0 -31
- adam/commands/postgres/psql_completions.py +0 -10
- adam/commands/pwd.py +0 -77
- adam/commands/reaper/reaper_session.py +0 -159
- adam/commands/report.py +0 -63
- adam/commands/show/show.py +0 -54
- adam/commands/show/show_app_actions.py +0 -56
- adam/commands/show/show_cassandra_status.py +0 -128
- adam/commands/show/show_commands.py +0 -61
- adam/commands/show/show_login.py +0 -63
- adam/commands/show/show_processes.py +0 -53
- adam/commands/show/show_repairs.py +0 -47
- adam/commands/show/show_storage.py +0 -52
- kaqing-2.0.110.dist-info/RECORD +0 -187
- kaqing-2.0.110.dist-info/top_level.txt +0 -1
- /adam/commands/{show → app}/__init__.py +0 -0
- /adam/commands/{nodetool_commands.py → nodetool/nodetool_commands.py} +0 -0
- {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/WHEEL +0 -0
- {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/entry_points.txt +0 -0
adam/commands/fs/head.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from adam.commands import validate_args
|
|
2
|
+
from adam.commands.command import Command
|
|
3
|
+
from adam.commands.devices.devices import Devices
|
|
4
|
+
from adam.repl_state import ReplState, RequiredState
|
|
5
|
+
|
|
6
|
+
class Head(Command):
|
|
7
|
+
COMMAND = 'head'
|
|
8
|
+
|
|
9
|
+
# the singleton pattern
|
|
10
|
+
def __new__(cls, *args, **kwargs):
|
|
11
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Head, 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 Head.COMMAND
|
|
20
|
+
|
|
21
|
+
def required(self):
|
|
22
|
+
return [RequiredState.CLUSTER_OR_POD, RequiredState.APP_APP, ReplState.P]
|
|
23
|
+
|
|
24
|
+
def run(self, cmd: str, state: ReplState):
|
|
25
|
+
if not(args := self.args(cmd)):
|
|
26
|
+
return super().run(cmd, state)
|
|
27
|
+
|
|
28
|
+
with self.validate(args, state) as (args, state):
|
|
29
|
+
with validate_args(args, state, name='file'):
|
|
30
|
+
return Devices.of(state).bash(state, state, cmd.split(' '))
|
|
31
|
+
|
|
32
|
+
def completion(self, state: ReplState):
|
|
33
|
+
return super().completion(state, lambda: {f: None for f in Devices.of(state).files(state)}, pods=Devices.of(state).pods(state, '-'), auto='jit')
|
|
34
|
+
|
|
35
|
+
def help(self, _: ReplState):
|
|
36
|
+
return f'{Head.COMMAND} file [&]\t run head command on the pod'
|
adam/commands/fs/ls.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.commands.devices.devices import Devices
|
|
5
|
+
from adam.repl_state import ReplState
|
|
6
|
+
|
|
7
|
+
class Ls(Command):
|
|
8
|
+
COMMAND = 'ls'
|
|
9
|
+
|
|
10
|
+
# the singleton pattern
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Ls, 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 Ls.COMMAND
|
|
21
|
+
|
|
22
|
+
def run(self, cmd: str, state: ReplState):
|
|
23
|
+
if not(args := self.args(cmd)):
|
|
24
|
+
return super().run(cmd, state)
|
|
25
|
+
|
|
26
|
+
with self.validate(args, state) as (args, state):
|
|
27
|
+
if len(args) > 0:
|
|
28
|
+
arg = args[0]
|
|
29
|
+
if arg in ['p:', 'c:'] and arg != f'{state.device}:':
|
|
30
|
+
state = copy.copy(state)
|
|
31
|
+
state.device = arg.replace(':', '')
|
|
32
|
+
|
|
33
|
+
Devices.of(state).ls(cmd, state)
|
|
34
|
+
|
|
35
|
+
return state
|
|
36
|
+
|
|
37
|
+
def completion(self, state: ReplState):
|
|
38
|
+
return super().completion(state, {'&': None}, pods=Devices.of(state).pods(state, '-'))
|
|
39
|
+
|
|
40
|
+
def help(self, _: ReplState):
|
|
41
|
+
return f'{Ls.COMMAND} [device:]\t list apps, envs, clusters, nodes, pg hosts/databases or export databases'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.repl_state import ReplState
|
|
5
|
+
from adam.utils import log2
|
|
6
|
+
from adam.utils_local import local_qing_dir
|
|
7
|
+
|
|
8
|
+
class LsLocal(Command):
|
|
9
|
+
COMMAND = ':ls'
|
|
10
|
+
|
|
11
|
+
# the singleton pattern
|
|
12
|
+
def __new__(cls, *args, **kwargs):
|
|
13
|
+
if not hasattr(cls, 'instance'): cls.instance = super(LsLocal, cls).__new__(cls)
|
|
14
|
+
|
|
15
|
+
return cls.instance
|
|
16
|
+
|
|
17
|
+
def __init__(self, successor: Command=None):
|
|
18
|
+
super().__init__(successor)
|
|
19
|
+
|
|
20
|
+
def command(self):
|
|
21
|
+
return LsLocal.COMMAND
|
|
22
|
+
|
|
23
|
+
def run(self, cmd: str, state: ReplState):
|
|
24
|
+
if not(args := self.args(cmd)):
|
|
25
|
+
return super().run(cmd, state)
|
|
26
|
+
|
|
27
|
+
with self.validate(args, state) as (args, state):
|
|
28
|
+
if args:
|
|
29
|
+
os.system(f'ls {args}')
|
|
30
|
+
else:
|
|
31
|
+
os.system(f'ls {local_qing_dir()}')
|
|
32
|
+
log2()
|
|
33
|
+
|
|
34
|
+
return state
|
|
35
|
+
|
|
36
|
+
def completion(self, state: ReplState):
|
|
37
|
+
return super().completion(state)
|
|
38
|
+
|
|
39
|
+
def help(self, _: ReplState):
|
|
40
|
+
return f'{LsLocal.COMMAND} [dir]\t list files on local system'
|
adam/commands/fs/pwd.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from adam.app_session import AppSession
|
|
2
|
+
from adam.commands.command import Command
|
|
3
|
+
from adam.commands.devices.devices import Devices
|
|
4
|
+
from adam.repl_state import ReplState
|
|
5
|
+
from adam.utils import tabulize, log, log_exc
|
|
6
|
+
|
|
7
|
+
class Pwd(Command):
|
|
8
|
+
COMMAND = 'pwd'
|
|
9
|
+
|
|
10
|
+
# the singleton pattern
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Pwd, 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 Pwd.COMMAND
|
|
21
|
+
|
|
22
|
+
def run(self, cmd: str, state: ReplState):
|
|
23
|
+
if not(args := self.args(cmd)):
|
|
24
|
+
return super().run(cmd, state)
|
|
25
|
+
|
|
26
|
+
with self.validate(args, state) as (_, state):
|
|
27
|
+
host = "unknown"
|
|
28
|
+
with log_exc():
|
|
29
|
+
app_session: AppSession = AppSession.create('c3', 'c3')
|
|
30
|
+
host = app_session.host
|
|
31
|
+
|
|
32
|
+
tabulize([device.pwd(state) for device in Devices.all()] + [
|
|
33
|
+
f'',
|
|
34
|
+
f'HOST\t{host}',
|
|
35
|
+
f'NAMESPACE\t{state.namespace if state.namespace else "/"}',
|
|
36
|
+
], header='DEVICE\tLOCATION', separator='\t')
|
|
37
|
+
log()
|
|
38
|
+
|
|
39
|
+
return state
|
|
40
|
+
|
|
41
|
+
def completion(self, state: ReplState):
|
|
42
|
+
return super().completion(state)
|
|
43
|
+
|
|
44
|
+
def help(self, _: ReplState):
|
|
45
|
+
return f'{Pwd.COMMAND}\t print current working directories'
|
adam/commands/fs/rm.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from adam.commands.fs.rm_downloads import RmDownloads
|
|
2
|
+
from adam.commands.fs.rm_logs import RmLogs
|
|
3
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
4
|
+
|
|
5
|
+
class RmLocal(IntermediateCommand):
|
|
6
|
+
COMMAND = ':rm'
|
|
7
|
+
|
|
8
|
+
# the singleton pattern
|
|
9
|
+
def __new__(cls, *args, **kwargs):
|
|
10
|
+
if not hasattr(cls, 'instance'): cls.instance = super(RmLocal, cls).__new__(cls)
|
|
11
|
+
|
|
12
|
+
return cls.instance
|
|
13
|
+
|
|
14
|
+
def command(self):
|
|
15
|
+
return RmLocal.COMMAND
|
|
16
|
+
|
|
17
|
+
def cmd_list(self):
|
|
18
|
+
return [RmDownloads(), RmLogs()]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.repl_state import ReplState
|
|
5
|
+
from adam.utils import log2
|
|
6
|
+
from adam.utils_local import local_downloads_dir
|
|
7
|
+
|
|
8
|
+
class RmDownloads(Command):
|
|
9
|
+
COMMAND = ':rm downloads'
|
|
10
|
+
|
|
11
|
+
# the singleton pattern
|
|
12
|
+
def __new__(cls, *args, **kwargs):
|
|
13
|
+
if not hasattr(cls, 'instance'): cls.instance = super(RmDownloads, cls).__new__(cls)
|
|
14
|
+
|
|
15
|
+
return cls.instance
|
|
16
|
+
|
|
17
|
+
def __init__(self, successor: Command=None):
|
|
18
|
+
super().__init__(successor)
|
|
19
|
+
|
|
20
|
+
def command(self):
|
|
21
|
+
return RmDownloads.COMMAND
|
|
22
|
+
|
|
23
|
+
def run(self, cmd: str, state: ReplState):
|
|
24
|
+
if not(args := self.args(cmd)):
|
|
25
|
+
return super().run(cmd, state)
|
|
26
|
+
|
|
27
|
+
with self.validate(args, state) as (args, state):
|
|
28
|
+
cmd = f'rm -rf {local_downloads_dir()}/*'
|
|
29
|
+
log2(cmd)
|
|
30
|
+
os.system(cmd)
|
|
31
|
+
log2()
|
|
32
|
+
|
|
33
|
+
return state
|
|
34
|
+
|
|
35
|
+
def completion(self, state: ReplState):
|
|
36
|
+
return super().completion(state)
|
|
37
|
+
|
|
38
|
+
def help(self, _: ReplState):
|
|
39
|
+
return f'{RmDownloads.COMMAND}\t remove all downloads files under {local_downloads_dir()}'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.repl_state import ReplState
|
|
5
|
+
from adam.utils import log2, log_dir
|
|
6
|
+
|
|
7
|
+
class RmLogs(Command):
|
|
8
|
+
COMMAND = ':rm logs'
|
|
9
|
+
|
|
10
|
+
# the singleton pattern
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
if not hasattr(cls, 'instance'): cls.instance = super(RmLogs, 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 RmLogs.COMMAND
|
|
21
|
+
|
|
22
|
+
def run(self, cmd: str, state: ReplState):
|
|
23
|
+
if not(args := self.args(cmd)):
|
|
24
|
+
return super().run(cmd, state)
|
|
25
|
+
|
|
26
|
+
with self.validate(args, state) as (args, state):
|
|
27
|
+
cmd = f'rm -rf {log_dir()}/*'
|
|
28
|
+
log2(cmd)
|
|
29
|
+
os.system(cmd)
|
|
30
|
+
log2()
|
|
31
|
+
|
|
32
|
+
return state
|
|
33
|
+
|
|
34
|
+
def completion(self, state: ReplState):
|
|
35
|
+
return super().completion(state)
|
|
36
|
+
|
|
37
|
+
def help(self, _: ReplState):
|
|
38
|
+
return f'{RmLogs.COMMAND}\t remove all qing log files under {log_dir()}'
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
|
+
from adam.commands import validate_args
|
|
3
4
|
from adam.commands.command import Command
|
|
4
5
|
from adam.repl_state import ReplState
|
|
6
|
+
from adam.utils import log2
|
|
5
7
|
|
|
6
8
|
class Shell(Command):
|
|
7
9
|
COMMAND = ':sh'
|
|
@@ -18,13 +20,19 @@ class Shell(Command):
|
|
|
18
20
|
def command(self):
|
|
19
21
|
return Shell.COMMAND
|
|
20
22
|
|
|
21
|
-
def run(self, cmd: str,
|
|
23
|
+
def run(self, cmd: str, state: ReplState):
|
|
22
24
|
if not(args := self.args(cmd)):
|
|
23
|
-
return super().run(cmd,
|
|
25
|
+
return super().run(cmd, state)
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
with self.validate(args, state) as (args, _):
|
|
28
|
+
with validate_args(args, state, at_least=0) as args_str:
|
|
29
|
+
if args_str:
|
|
30
|
+
os.system(args_str)
|
|
31
|
+
log2()
|
|
32
|
+
else:
|
|
33
|
+
os.system('QING_DROPPED=true bash')
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
return state
|
|
28
36
|
|
|
29
37
|
def completion(self, state: ReplState):
|
|
30
38
|
return super().completion(state)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
|
-
from adam.utils import
|
|
4
|
+
from adam.utils import tabulize
|
|
5
5
|
|
|
6
6
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
7
7
|
|
|
@@ -34,10 +34,10 @@ class ShowAdam(Command):
|
|
|
34
34
|
|
|
35
35
|
package = os.path.dirname(os.path.abspath(__file__))
|
|
36
36
|
package = package.split('/adam/')[0] + '/adam'
|
|
37
|
-
|
|
37
|
+
tabulize([
|
|
38
38
|
f'version\t{__version__}',
|
|
39
39
|
f'source\t{package}'
|
|
40
|
-
], separator='\t')
|
|
40
|
+
], separator='\t', to=2)
|
|
41
41
|
|
|
42
42
|
return state
|
|
43
43
|
|
adam/commands/help.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.repl_commands import ReplCommands
|
|
3
3
|
from adam.repl_state import ReplState
|
|
4
|
-
from adam.utils import
|
|
4
|
+
from adam.utils import tabulize, log
|
|
5
5
|
|
|
6
6
|
class Help(Command):
|
|
7
7
|
COMMAND = 'help'
|
|
@@ -28,7 +28,7 @@ class Help(Command):
|
|
|
28
28
|
|
|
29
29
|
lines = []
|
|
30
30
|
lines.append('NAVIGATION')
|
|
31
|
-
lines.append(' a: | c: | l: | p:\t switch to another operational device: App, Cassandra, Audit or
|
|
31
|
+
lines.append(' a: | c: | l: | p: | x:\t switch to another operational device: App, Cassandra, Audit, Postgres or Export')
|
|
32
32
|
lines.extend(section(ReplCommands.navigation()))
|
|
33
33
|
lines.append('CASSANDRA')
|
|
34
34
|
lines.extend(section(ReplCommands.cassandra_ops()))
|
|
@@ -36,6 +36,8 @@ class Help(Command):
|
|
|
36
36
|
lines.extend(section(ReplCommands.postgres_ops()))
|
|
37
37
|
lines.append('APP')
|
|
38
38
|
lines.extend(section(ReplCommands.app_ops()))
|
|
39
|
+
lines.append('EXPORT DB')
|
|
40
|
+
lines.extend(section(ReplCommands.export_ops()))
|
|
39
41
|
lines.append('AUDIT')
|
|
40
42
|
lines.extend(section(ReplCommands.audit_ops()))
|
|
41
43
|
lines.append('TOOLS')
|
|
@@ -43,7 +45,7 @@ class Help(Command):
|
|
|
43
45
|
lines.append('')
|
|
44
46
|
lines.extend(section(ReplCommands.exit()))
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
tabulize(lines, separator='\t')
|
|
47
49
|
|
|
48
50
|
return lines
|
|
49
51
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.commands.command_helpers import ClusterCommandHelper
|
|
5
|
+
from adam.repl_state import ReplState
|
|
6
|
+
from adam.utils import tabulize, log, log2
|
|
7
|
+
|
|
8
|
+
class IntermediateCommand(Command):
|
|
9
|
+
def run(self, cmd: str, state: ReplState):
|
|
10
|
+
if not(args := self.args(cmd)):
|
|
11
|
+
return super().run(cmd, state)
|
|
12
|
+
|
|
13
|
+
return self.intermediate_run(cmd, state, args, self.cmd_list())
|
|
14
|
+
|
|
15
|
+
def completion(self, state: ReplState):
|
|
16
|
+
return {}
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
def cmd_list(self):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
def intermediate_run(self, cmd: str, state: ReplState, args: list[str], cmds: list['Command'], separator='\t', display_help=True):
|
|
23
|
+
state, _ = self.apply_state(args, state)
|
|
24
|
+
|
|
25
|
+
if state.in_repl:
|
|
26
|
+
if display_help:
|
|
27
|
+
tabulize(cmds, lambda c: c.help(state), separator=separator)
|
|
28
|
+
|
|
29
|
+
return 'command-missing'
|
|
30
|
+
else:
|
|
31
|
+
# head with the Chain of Responsibility pattern
|
|
32
|
+
if not self.run_subcommand(cmd, state):
|
|
33
|
+
if display_help:
|
|
34
|
+
log2('* Command is missing.')
|
|
35
|
+
Command.display_help()
|
|
36
|
+
return 'command-missing'
|
|
37
|
+
|
|
38
|
+
return state
|
|
39
|
+
|
|
40
|
+
def run_subcommand(self, cmd: str, state: ReplState):
|
|
41
|
+
cmds = Command.chain(self.cmd_list())
|
|
42
|
+
return cmds.run(cmd, state)
|
|
43
|
+
|
|
44
|
+
def intermediate_help(super_help: str, cmd: str, cmd_list: list['Command'], separator='\t', show_cluster_help=False):
|
|
45
|
+
log(super_help)
|
|
46
|
+
log()
|
|
47
|
+
log('Sub-Commands:')
|
|
48
|
+
|
|
49
|
+
tabulize(cmd_list, lambda c: c.help(ReplState()).replace(f'{cmd} ', ' ', 1), separator=separator)
|
|
50
|
+
if show_cluster_help:
|
|
51
|
+
log()
|
|
52
|
+
ClusterCommandHelper.cluster_help()
|
adam/commands/kubectl.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
with self.validate(args, state) as (args, state):
|
|
29
|
+
subprocess.run(["kubectl"] + args)
|
|
30
|
+
|
|
31
|
+
return state
|
|
32
|
+
|
|
33
|
+
def completion(self, state: ReplState):
|
|
34
|
+
return super().completion(state)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def help(self, _: ReplState):
|
|
38
|
+
return f'{Kubectl.COMMAND} \t run a kubectl command'
|
adam/commands/medusa/medusa.py
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
3
|
from adam.commands.command import Command
|
|
4
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
4
5
|
from .medusa_backup import MedusaBackup
|
|
5
6
|
from .medusa_restore import MedusaRestore
|
|
6
7
|
from .medusa_show_backupjobs import MedusaShowBackupJobs
|
|
7
8
|
from .medusa_show_restorejobs import MedusaShowRestoreJobs
|
|
8
|
-
from adam.repl_state import ReplState, RequiredState
|
|
9
9
|
|
|
10
|
-
class Medusa(
|
|
10
|
+
class Medusa(IntermediateCommand):
|
|
11
11
|
COMMAND = 'medusa'
|
|
12
12
|
|
|
13
13
|
# the singleton pattern
|
|
@@ -16,30 +16,12 @@ class Medusa(Command):
|
|
|
16
16
|
|
|
17
17
|
return cls.instance
|
|
18
18
|
|
|
19
|
-
def __init__(self, successor: Command=None):
|
|
20
|
-
super().__init__(successor)
|
|
21
|
-
|
|
22
19
|
def command(self):
|
|
23
20
|
return Medusa.COMMAND
|
|
24
21
|
|
|
25
|
-
def
|
|
26
|
-
return RequiredState.CLUSTER
|
|
27
|
-
|
|
28
|
-
def run(self, cmd: str, state: ReplState):
|
|
29
|
-
if not(args := self.args(cmd)):
|
|
30
|
-
return super().run(cmd, state)
|
|
31
|
-
|
|
32
|
-
return super().intermediate_run(cmd, state, args, Medusa.cmd_list())
|
|
33
|
-
|
|
34
|
-
def cmd_list():
|
|
22
|
+
def cmd_list(self):
|
|
35
23
|
return [MedusaBackup(), MedusaRestore(), MedusaShowBackupJobs(), MedusaShowRestoreJobs()]
|
|
36
24
|
|
|
37
|
-
def completion(self, state: ReplState):
|
|
38
|
-
if state.sts:
|
|
39
|
-
return super().completion(state)
|
|
40
|
-
|
|
41
|
-
return {}
|
|
42
|
-
|
|
43
25
|
class MedusaCommandHelper(click.Command):
|
|
44
26
|
def get_help(self, ctx: click.Context):
|
|
45
|
-
|
|
27
|
+
IntermediateCommand.intermediate_help(super().get_help(ctx), Medusa.COMMAND, Medusa().cmd_list(), show_cluster_help=True)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
-
import re
|
|
3
2
|
|
|
3
|
+
from adam.commands import validate_args
|
|
4
4
|
from adam.commands.command import Command
|
|
5
5
|
from adam.utils_k8s.statefulsets import StatefulSets
|
|
6
6
|
from adam.repl_state import ReplState, RequiredState
|
|
7
7
|
from adam.utils_k8s.custom_resources import CustomResources
|
|
8
8
|
from adam.utils import log2
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
class MedusaBackup(Command):
|
|
12
11
|
COMMAND = 'backup'
|
|
13
12
|
|
|
@@ -29,33 +28,27 @@ class MedusaBackup(Command):
|
|
|
29
28
|
def run(self, cmd: str, state: ReplState):
|
|
30
29
|
if not(args := self.args(cmd)):
|
|
31
30
|
return super().run(cmd, state)
|
|
32
|
-
state, args = self.apply_state(args, state)
|
|
33
|
-
if not self.validate_state(state):
|
|
34
|
-
return state
|
|
35
|
-
|
|
36
|
-
ns = state.namespace
|
|
37
|
-
sts = state.sts
|
|
38
|
-
now_dtformat = datetime.now().strftime("%Y-%m-%d.%H.%M.%S")
|
|
39
|
-
bkname = 'medusa-' + now_dtformat + 'full-backup-' + sts
|
|
40
|
-
if len(args) == 1:
|
|
41
|
-
bkname = str(args[0])
|
|
42
|
-
groups = re.match(r'^(.*?-.*?-).*', sts)
|
|
43
|
-
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
44
|
-
if not dc:
|
|
45
|
-
return state
|
|
46
|
-
|
|
47
|
-
try:
|
|
48
|
-
CustomResources.create_medusa_backupjob(bkname, dc, ns)
|
|
49
|
-
except Exception as e:
|
|
50
|
-
log2("Exception: MedusaBackup failed: %s\n" % e)
|
|
51
|
-
|
|
52
|
-
return state
|
|
53
31
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
32
|
+
with self.validate(args, state) as (args, state):
|
|
33
|
+
ns = state.namespace
|
|
34
|
+
sts = state.sts
|
|
35
|
+
now_dtformat = datetime.now().strftime("%Y-%m-%d.%H.%M.%S")
|
|
36
|
+
with validate_args(args, state, default='medusa-' + now_dtformat + 'full-backup-' + sts) as bkname:
|
|
37
|
+
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
38
|
+
if not dc:
|
|
39
|
+
return state
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
CustomResources.create_medusa_backupjob(bkname, dc, ns)
|
|
43
|
+
except Exception as e:
|
|
44
|
+
log2("Exception: MedusaBackup failed: %s\n" % e)
|
|
45
|
+
finally:
|
|
46
|
+
CustomResources.clear_caches()
|
|
57
47
|
|
|
58
|
-
|
|
48
|
+
return state
|
|
49
|
+
|
|
50
|
+
def completion(self, state: ReplState):
|
|
51
|
+
return super().completion(state)
|
|
59
52
|
|
|
60
53
|
def help(self, _: ReplState):
|
|
61
54
|
return f'{MedusaBackup.COMMAND}\t start a backup job'
|