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
adam/commands/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.device(state).ls(cmd, state)
|
|
34
|
+
|
|
35
|
+
return state
|
|
36
|
+
|
|
37
|
+
def completion(self, state: ReplState):
|
|
38
|
+
return Devices.device(state).ls_completion(Ls.COMMAND, state, default = super().completion(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,27 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
5
|
+
from .medusa_backup import MedusaBackup
|
|
6
|
+
from .medusa_restore import MedusaRestore
|
|
7
|
+
from .medusa_show_backupjobs import MedusaShowBackupJobs
|
|
8
|
+
from .medusa_show_restorejobs import MedusaShowRestoreJobs
|
|
9
|
+
|
|
10
|
+
class Medusa(IntermediateCommand):
|
|
11
|
+
COMMAND = 'medusa'
|
|
12
|
+
|
|
13
|
+
# the singleton pattern
|
|
14
|
+
def __new__(cls, *args, **kwargs):
|
|
15
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Medusa, cls).__new__(cls)
|
|
16
|
+
|
|
17
|
+
return cls.instance
|
|
18
|
+
|
|
19
|
+
def command(self):
|
|
20
|
+
return Medusa.COMMAND
|
|
21
|
+
|
|
22
|
+
def cmd_list(self):
|
|
23
|
+
return [MedusaBackup(), MedusaRestore(), MedusaShowBackupJobs(), MedusaShowRestoreJobs()]
|
|
24
|
+
|
|
25
|
+
class MedusaCommandHelper(click.Command):
|
|
26
|
+
def get_help(self, ctx: click.Context):
|
|
27
|
+
IntermediateCommand.intermediate_help(super().get_help(ctx), Medusa.COMMAND, Medusa().cmd_list(), show_cluster_help=True)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
from adam.commands.command import Command
|
|
5
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
6
|
+
from adam.repl_state import ReplState, RequiredState
|
|
7
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
8
|
+
from adam.utils import log2
|
|
9
|
+
|
|
10
|
+
class MedusaBackup(Command):
|
|
11
|
+
COMMAND = 'backup'
|
|
12
|
+
|
|
13
|
+
# the singleton pattern
|
|
14
|
+
def __new__(cls, *args, **kwargs):
|
|
15
|
+
if not hasattr(cls, 'instance'): cls.instance = super(MedusaBackup, cls).__new__(cls)
|
|
16
|
+
|
|
17
|
+
return cls.instance
|
|
18
|
+
|
|
19
|
+
def __init__(self, successor: Command=None):
|
|
20
|
+
super().__init__(successor)
|
|
21
|
+
|
|
22
|
+
def command(self):
|
|
23
|
+
return MedusaBackup.COMMAND
|
|
24
|
+
|
|
25
|
+
def required(self):
|
|
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
|
+
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
|
+
bkname = 'medusa-' + now_dtformat + 'full-backup-' + sts
|
|
37
|
+
if len(args) == 1:
|
|
38
|
+
bkname = str(args[0])
|
|
39
|
+
groups = re.match(r'^(.*?-.*?-).*', sts)
|
|
40
|
+
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
41
|
+
if not dc:
|
|
42
|
+
return state
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
CustomResources.create_medusa_backupjob(bkname, dc, ns)
|
|
46
|
+
except Exception as e:
|
|
47
|
+
log2("Exception: MedusaBackup failed: %s\n" % e)
|
|
48
|
+
finally:
|
|
49
|
+
CustomResources.clear_caches()
|
|
50
|
+
|
|
51
|
+
return state
|
|
52
|
+
|
|
53
|
+
def completion(self, state: ReplState):
|
|
54
|
+
return super().completion(state)
|
|
55
|
+
|
|
56
|
+
def help(self, _: ReplState):
|
|
57
|
+
return f'{MedusaBackup.COMMAND}\t start a backup job'
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
5
|
+
from adam.repl_state import ReplState, RequiredState
|
|
6
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
7
|
+
from adam.config import Config
|
|
8
|
+
from adam.utils import lines_to_tabular, log2
|
|
9
|
+
|
|
10
|
+
class MedusaRestore(Command):
|
|
11
|
+
COMMAND = 'restore'
|
|
12
|
+
|
|
13
|
+
# the singleton pattern
|
|
14
|
+
def __new__(cls, *args, **kwargs):
|
|
15
|
+
if not hasattr(cls, 'instance'): cls.instance = super(MedusaRestore, cls).__new__(cls)
|
|
16
|
+
|
|
17
|
+
return cls.instance
|
|
18
|
+
|
|
19
|
+
def __init__(self, successor: Command=None):
|
|
20
|
+
super().__init__(successor)
|
|
21
|
+
|
|
22
|
+
def command(self):
|
|
23
|
+
return MedusaRestore.COMMAND
|
|
24
|
+
|
|
25
|
+
def required(self):
|
|
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
|
+
with self.validate(args, state) as (args, state):
|
|
33
|
+
ns = state.namespace
|
|
34
|
+
dc: str = StatefulSets.get_datacenter(state.sts, ns)
|
|
35
|
+
if not dc:
|
|
36
|
+
return state
|
|
37
|
+
|
|
38
|
+
if len(args) == 1:
|
|
39
|
+
bkname = args[0]
|
|
40
|
+
job = CustomResources.medusa_get_backupjob(dc, ns, bkname)
|
|
41
|
+
if not job:
|
|
42
|
+
log2('\n* Backup job name is not valid.')
|
|
43
|
+
bklist = [f"{x['metadata']['name']}\t{x['metadata']['creationTimestamp']}\t{x['status'].get('finishTime', '')}" for x in CustomResources.medusa_show_backupjobs(dc, ns)]
|
|
44
|
+
log2(lines_to_tabular(bklist, 'NAME\tCREATED\tFINISHED', separator='\t'))
|
|
45
|
+
|
|
46
|
+
return state
|
|
47
|
+
|
|
48
|
+
if not input(f"Restoring from {bkname} created at {job['metadata']['creationTimestamp']}. Please enter Yes to continue: ").lower() in ['y', 'yes']:
|
|
49
|
+
return state
|
|
50
|
+
else:
|
|
51
|
+
bklist = [f"{x['metadata']['name']}\t{x['metadata']['creationTimestamp']}\t{x['status'].get('finishTime', '')}" for x in CustomResources.medusa_show_backupjobs(dc, ns)]
|
|
52
|
+
log2('\n* Missing Backup Name')
|
|
53
|
+
log2('Usage: qing medusa restore <backup> <sts@name_space>\n')
|
|
54
|
+
log2(lines_to_tabular(bklist, 'NAME\tCREATED\tFINISHED', separator='\t'))
|
|
55
|
+
return state
|
|
56
|
+
|
|
57
|
+
now_dtformat = datetime.now().strftime("%Y-%m-%d.%H.%M.%S")
|
|
58
|
+
rtname = 'medusa-' + now_dtformat + '-restore-from-' + bkname
|
|
59
|
+
try:
|
|
60
|
+
CustomResources.create_medusa_restorejob(rtname, bkname, dc, ns)
|
|
61
|
+
except Exception as e:
|
|
62
|
+
log2("Exception: MedusaRestore failed: %s\n" % e)
|
|
63
|
+
|
|
64
|
+
return state
|
|
65
|
+
|
|
66
|
+
def completion(self, state: ReplState):
|
|
67
|
+
if sc := super().completion(state):
|
|
68
|
+
ns = state.namespace
|
|
69
|
+
dc: str = StatefulSets.get_datacenter(state.sts, ns)
|
|
70
|
+
if not dc:
|
|
71
|
+
return {}
|
|
72
|
+
|
|
73
|
+
if Config().get('medusa.restore-auto-complete', False):
|
|
74
|
+
leaf = {id: None for id in [f"{x['metadata']['name']}" for x in CustomResources.medusa_show_backupjobs(dc, ns)]}
|
|
75
|
+
|
|
76
|
+
return super().completion(state, leaf)
|
|
77
|
+
else:
|
|
78
|
+
return sc
|
|
79
|
+
|
|
80
|
+
return {}
|
|
81
|
+
|
|
82
|
+
def help(self, _: ReplState):
|
|
83
|
+
return f'{MedusaRestore.COMMAND}\t start a restore job'
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from adam.commands.command import Command
|
|
2
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
3
|
+
from adam.repl_state import ReplState, RequiredState
|
|
4
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
5
|
+
from adam.utils import lines_to_tabular, log2
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MedusaShowBackupJobs(Command):
|
|
9
|
+
COMMAND = 'show backups'
|
|
10
|
+
|
|
11
|
+
# the singleton pattern
|
|
12
|
+
def __new__(cls, *args, **kwargs):
|
|
13
|
+
if not hasattr(cls, 'instance'): cls.instance = super(MedusaShowBackupJobs, 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 MedusaShowBackupJobs.COMMAND
|
|
22
|
+
|
|
23
|
+
def required(self):
|
|
24
|
+
return RequiredState.CLUSTER
|
|
25
|
+
|
|
26
|
+
def run(self, cmd: str, state: ReplState):
|
|
27
|
+
if not(args := self.args(cmd)):
|
|
28
|
+
return super().run(cmd, state)
|
|
29
|
+
|
|
30
|
+
with self.validate(args, state) as (args, state):
|
|
31
|
+
ns = state.namespace
|
|
32
|
+
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
33
|
+
if not dc:
|
|
34
|
+
return state
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
# always show latest
|
|
38
|
+
CustomResources.clear_caches()
|
|
39
|
+
|
|
40
|
+
bklist = [f"{x['metadata']['name']}\t{x['metadata']['creationTimestamp']}\t{x['status'].get('finishTime', '') if 'status' in x else 'unknown'}" for x in CustomResources.medusa_show_backupjobs(dc, ns)]
|
|
41
|
+
log2(lines_to_tabular(bklist, 'NAME\tCREATED\tFINISHED', separator='\t'))
|
|
42
|
+
except Exception as e:
|
|
43
|
+
log2("Exception: MedusaShowBackupJobs failed: %s\n" % e)
|
|
44
|
+
|
|
45
|
+
return state
|
|
46
|
+
|
|
47
|
+
def completion(self, state: ReplState):
|
|
48
|
+
return super().completion(state)
|
|
49
|
+
|
|
50
|
+
def help(self, _: ReplState):
|
|
51
|
+
return f'{MedusaShowBackupJobs.COMMAND}\t show Medusa backups'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from adam.commands.command import Command
|
|
2
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
3
|
+
from adam.repl_state import ReplState, RequiredState
|
|
4
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
5
|
+
from adam.utils import lines_to_tabular, log2
|
|
6
|
+
|
|
7
|
+
class MedusaShowRestoreJobs(Command):
|
|
8
|
+
COMMAND = 'show restores'
|
|
9
|
+
|
|
10
|
+
# the singleton pattern
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
if not hasattr(cls, 'instance'): cls.instance = super(MedusaShowRestoreJobs, 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 MedusaShowRestoreJobs.COMMAND
|
|
21
|
+
|
|
22
|
+
def required(self):
|
|
23
|
+
return RequiredState.CLUSTER
|
|
24
|
+
|
|
25
|
+
def run(self, cmd: str, state: ReplState):
|
|
26
|
+
if not(args := self.args(cmd)):
|
|
27
|
+
return super().run(cmd, state)
|
|
28
|
+
|
|
29
|
+
with self.validate(args, state) as (args, state):
|
|
30
|
+
ns = state.namespace
|
|
31
|
+
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
32
|
+
if not dc:
|
|
33
|
+
return state
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
rtlist = CustomResources.medusa_show_restorejobs(dc, ns)
|
|
37
|
+
log2(lines_to_tabular(rtlist, 'NAME\tCREATED\tFINISHED', separator='\t'))
|
|
38
|
+
except Exception as e:
|
|
39
|
+
log2("Exception: MedusaShowRestoreJobs failed: %s\n" % e)
|
|
40
|
+
|
|
41
|
+
return state
|
|
42
|
+
|
|
43
|
+
def completion(self, state: ReplState):
|
|
44
|
+
return super().completion(state)
|
|
45
|
+
|
|
46
|
+
def help(self, _: ReplState):
|
|
47
|
+
return f'{MedusaShowRestoreJobs.COMMAND}\t show Medusa restores'
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
3
|
+
from adam.commands.command import Command
|
|
4
|
+
from adam.commands.command_helpers import ClusterOrPodCommandHelper
|
|
5
|
+
from adam.commands.cql.utils_cql import cassandra
|
|
6
|
+
from adam.commands.nodetool_commands import NODETOOL_COMMANDS
|
|
7
|
+
from adam.config import Config
|
|
8
|
+
from adam.repl_state import ReplState, RequiredState
|
|
9
|
+
from adam.utils import log
|
|
10
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
11
11
|
|
|
12
12
|
class NodeTool(Command):
|
|
13
13
|
COMMAND = 'nodetool'
|
|
@@ -31,26 +31,22 @@ class NodeTool(Command):
|
|
|
31
31
|
if not(args := self.args(cmd)):
|
|
32
32
|
return super().run(cmd, state)
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
user, pw = state.user_pass()
|
|
39
|
-
command = f"nodetool -u {user} -pw {pw} {' '.join(args)}"
|
|
34
|
+
with self.validate(args, state) as (args, state):
|
|
35
|
+
with cassandra(state) as pods:
|
|
36
|
+
pods.nodetool(' '.join(args))
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
return CassandraNodes.exec(state.pod, state.namespace, command, show_out=True)
|
|
43
|
-
elif state.sts:
|
|
44
|
-
return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool', show_out=True)
|
|
38
|
+
return state
|
|
45
39
|
|
|
46
40
|
def completion(self, state: ReplState):
|
|
47
|
-
if
|
|
48
|
-
|
|
41
|
+
if super().completion(state):
|
|
42
|
+
d = {c: {'&': None} for c in NODETOOL_COMMANDS}
|
|
43
|
+
return {NodeTool.COMMAND: {'help': None} | d} | \
|
|
44
|
+
{f'@{p}': {NodeTool.COMMAND: d} for p in StatefulSets.pod_names(state.sts, state.namespace)}
|
|
49
45
|
|
|
50
46
|
return {}
|
|
51
47
|
|
|
52
48
|
def help(self, _: ReplState):
|
|
53
|
-
return f'{NodeTool.COMMAND} <sub-command
|
|
49
|
+
return f'{NodeTool.COMMAND} <sub-command> [&]\t run nodetool with arguments'
|
|
54
50
|
|
|
55
51
|
class NodeToolCommandHelper(click.Command):
|
|
56
52
|
def get_help(self, ctx: click.Context):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
from
|
|
1
|
+
from adam.commands.command import Command
|
|
2
|
+
from adam.config import Config
|
|
3
|
+
from adam.repl_state import ReplState
|
|
4
|
+
from adam.utils import lines_to_tabular, log, log2
|
|
5
5
|
|
|
6
6
|
class GetParam(Command):
|
|
7
7
|
COMMAND = 'get'
|
|
@@ -22,21 +22,20 @@ class GetParam(Command):
|
|
|
22
22
|
if not(args := self.args(cmd)):
|
|
23
23
|
return super().run(cmd, state)
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
with self.validate(args, state) as (args, state):
|
|
26
|
+
if len(args) < 1:
|
|
27
|
+
lines = [f'{key}\t{Config().get(key, None)}' for key in Config().keys()]
|
|
28
|
+
log(lines_to_tabular(lines, separator='\t'))
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
lines = [f'{key}\t{Config().get(key, None)}' for key in Config().keys()]
|
|
29
|
-
log(lines_to_tabular(lines, separator='\t'))
|
|
30
|
+
return state
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
key = args[0]
|
|
33
|
+
if v := Config().get(key, None):
|
|
34
|
+
log(v)
|
|
35
|
+
else:
|
|
36
|
+
log2(f'{key} is not set.')
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
if v := Config().get(key, None):
|
|
35
|
-
log(v)
|
|
36
|
-
else:
|
|
37
|
-
log2(f'{key} is not set.')
|
|
38
|
-
|
|
39
|
-
return v if v else state
|
|
38
|
+
return v if v else state
|
|
40
39
|
|
|
41
40
|
def completion(self, _: ReplState):
|
|
42
41
|
return {GetParam.COMMAND: {key: None for key in Config().keys()}}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from adam.commands.command import Command
|
|
2
|
+
from adam.config import Config
|
|
3
|
+
from adam.repl_state import ReplState
|
|
4
|
+
from adam.utils import log, log2
|
|
5
|
+
|
|
6
|
+
class SetParam(Command):
|
|
7
|
+
COMMAND = 'set'
|
|
8
|
+
|
|
9
|
+
# the singleton pattern
|
|
10
|
+
def __new__(cls, *args, **kwargs):
|
|
11
|
+
if not hasattr(cls, 'instance'): cls.instance = super(SetParam, 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 SetParam.COMMAND
|
|
20
|
+
|
|
21
|
+
def run(self, cmd: str, state: ReplState):
|
|
22
|
+
if not(args := self.args(cmd)):
|
|
23
|
+
return super().run(cmd, state)
|
|
24
|
+
|
|
25
|
+
with self.validate(args, state) as (args, state):
|
|
26
|
+
if len(args) < 2:
|
|
27
|
+
log2('set <key> <value>')
|
|
28
|
+
|
|
29
|
+
return 'invalid args'
|
|
30
|
+
|
|
31
|
+
key = args[0]
|
|
32
|
+
value = args[1]
|
|
33
|
+
Config().set(key, value)
|
|
34
|
+
|
|
35
|
+
log(Config().get(key, None))
|
|
36
|
+
|
|
37
|
+
return value
|
|
38
|
+
|
|
39
|
+
def completion(self, _: ReplState):
|
|
40
|
+
return {SetParam.COMMAND: {key: ({'true': None, 'false': None} if Config().get(key, None) in [True, False] else None) for key in Config().keys()}}
|
|
41
|
+
|
|
42
|
+
def help(self, _: ReplState):
|
|
43
|
+
return f"{SetParam.COMMAND} <key> <value>\t sets a Kaqing parameter to a different value"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from adam.commands import extract_trailing_options
|
|
4
|
+
from adam.commands.command import Command
|
|
5
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
6
|
+
from adam.commands.postgres.psql_completions import psql_completions
|
|
7
|
+
from adam.commands.postgres.utils_postgres import pg_table_names, postgres
|
|
8
|
+
from .postgres_ls import PostgresLs
|
|
9
|
+
from .postgres_preview import PostgresPreview
|
|
10
|
+
from .postgres_context import PostgresContext
|
|
11
|
+
from adam.repl_state import ReplState
|
|
12
|
+
from adam.utils import log, log2
|
|
13
|
+
|
|
14
|
+
class Postgres(IntermediateCommand):
|
|
15
|
+
COMMAND = 'pg'
|
|
16
|
+
|
|
17
|
+
# the singleton pattern
|
|
18
|
+
def __new__(cls, *args, **kwargs):
|
|
19
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Postgres, cls).__new__(cls)
|
|
20
|
+
|
|
21
|
+
return cls.instance
|
|
22
|
+
|
|
23
|
+
def __init__(self, successor: Command=None):
|
|
24
|
+
super().__init__(successor)
|
|
25
|
+
|
|
26
|
+
def command(self):
|
|
27
|
+
return Postgres.COMMAND
|
|
28
|
+
|
|
29
|
+
def run(self, cmd: str, state: ReplState):
|
|
30
|
+
if not(args := self.args(cmd)):
|
|
31
|
+
return super().run(cmd, state)
|
|
32
|
+
|
|
33
|
+
with self.validate(args, state) as (args, state):
|
|
34
|
+
with extract_trailing_options(args, '&') as (args, backgrounded):
|
|
35
|
+
if not args:
|
|
36
|
+
if state.in_repl:
|
|
37
|
+
log2('Please use SQL statement. e.g. pg \l')
|
|
38
|
+
else:
|
|
39
|
+
log2('* Command or SQL statements is missing.')
|
|
40
|
+
Command.display_help()
|
|
41
|
+
|
|
42
|
+
return 'command-missing'
|
|
43
|
+
|
|
44
|
+
if not state.pg_path:
|
|
45
|
+
if state.in_repl:
|
|
46
|
+
log2('Enter "use <pg-name>" first.')
|
|
47
|
+
else:
|
|
48
|
+
log2('* pg-name is missing.')
|
|
49
|
+
|
|
50
|
+
return state
|
|
51
|
+
|
|
52
|
+
if state.in_repl:
|
|
53
|
+
with postgres(state) as pod:
|
|
54
|
+
pod.sql(args, background=backgrounded)
|
|
55
|
+
elif not self.run_subcommand(cmd, state):
|
|
56
|
+
with postgres(state) as pod:
|
|
57
|
+
pod.sql(args, background=backgrounded)
|
|
58
|
+
|
|
59
|
+
return state
|
|
60
|
+
|
|
61
|
+
def cmd_list(self):
|
|
62
|
+
return [PostgresLs(), PostgresPreview(), PostgresPg()]
|
|
63
|
+
|
|
64
|
+
def completion(self, state: ReplState):
|
|
65
|
+
if state.device != state.P:
|
|
66
|
+
# conflicts with cql completions
|
|
67
|
+
return {}
|
|
68
|
+
|
|
69
|
+
leaf = {}
|
|
70
|
+
session = PostgresContext.apply(state.namespace, state.pg_path)
|
|
71
|
+
if session.db:
|
|
72
|
+
if pg_table_names(state.namespace, state.pg_path):
|
|
73
|
+
leaf = psql_completions(state.namespace, state.pg_path)
|
|
74
|
+
elif state.pg_path:
|
|
75
|
+
leaf = {
|
|
76
|
+
'\h': None,
|
|
77
|
+
'\l': None,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if state.pg_path:
|
|
81
|
+
return super().completion(state, leaf) | leaf
|
|
82
|
+
else:
|
|
83
|
+
return {}
|
|
84
|
+
|
|
85
|
+
def help(self, _: ReplState):
|
|
86
|
+
return f'<sql-statements> [&]\t run queries on Postgres databases'
|
|
87
|
+
|
|
88
|
+
class PostgresCommandHelper(click.Command):
|
|
89
|
+
def get_help(self, ctx: click.Context):
|
|
90
|
+
IntermediateCommand.intermediate_help(super().get_help(ctx), Postgres.COMMAND, Postgres().cmd_list(), show_cluster_help=True)
|
|
91
|
+
log('PG-Name: Kubernetes secret for Postgres credentials')
|
|
92
|
+
log(' e.g. stgawsscpsr-c3-c3-k8spg-cs-001')
|
|
93
|
+
log('Database: Postgres database name within a host')
|
|
94
|
+
log(' e.g. stgawsscpsr_c3_c3')
|
|
95
|
+
|
|
96
|
+
# No action body, only for a help entry and auto-completion
|
|
97
|
+
class PostgresPg(Command):
|
|
98
|
+
COMMAND = 'pg'
|
|
99
|
+
|
|
100
|
+
def command(self):
|
|
101
|
+
return PostgresPg.COMMAND
|
|
102
|
+
|
|
103
|
+
def help(self, _: ReplState):
|
|
104
|
+
return f'pg <sql-statements>\t run queries on Postgres databases'
|