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/show.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from adam.commands.app.show_app_actions import ShowAppActions
|
|
4
|
+
from adam.commands.app.show_app_id import ShowAppId
|
|
5
|
+
from adam.commands.app.show_app_queues import ShowAppQueues
|
|
6
|
+
from adam.commands.cassandra.show_cassandra_repairs import ShowCassandraRepairs
|
|
7
|
+
from adam.commands.cassandra.show_cassandra_status import ShowCassandraStatus
|
|
8
|
+
from adam.commands.cassandra.show_cassandra_version import ShowCassandraVersion
|
|
9
|
+
from adam.commands.cassandra.show_processes import ShowProcesses
|
|
10
|
+
from adam.commands.cassandra.show_storage import ShowStorage
|
|
11
|
+
from adam.commands.cli.show_cli_commands import ShowKubectlCommands
|
|
12
|
+
from adam.commands.config.show_params import ShowParams
|
|
13
|
+
from adam.commands.debug.show_offloaded_completes import ShowOffloadedCompletes
|
|
14
|
+
from adam.commands.fs.show_adam import ShowAdam
|
|
15
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
16
|
+
from adam.commands.medusa.medusa_show_backupjobs import MedusaShowBackupJobs
|
|
17
|
+
from adam.commands.medusa.medusa_show_restorejobs import MedusaShowRestoreJobs
|
|
18
|
+
from adam.commands.fs.show_host import ShowHost
|
|
19
|
+
from adam.commands.app.show_login import ShowLogin
|
|
20
|
+
|
|
21
|
+
class Show(IntermediateCommand):
|
|
22
|
+
COMMAND = 'show'
|
|
23
|
+
|
|
24
|
+
# the singleton pattern
|
|
25
|
+
def __new__(cls, *args, **kwargs):
|
|
26
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Show, cls).__new__(cls)
|
|
27
|
+
|
|
28
|
+
return cls.instance
|
|
29
|
+
|
|
30
|
+
def command(self):
|
|
31
|
+
return Show.COMMAND
|
|
32
|
+
|
|
33
|
+
def cmd_list(self):
|
|
34
|
+
return [ShowAppActions(), ShowAppId(), ShowAppQueues(), ShowOffloadedCompletes(), ShowHost(), ShowLogin(), ShowKubectlCommands(),
|
|
35
|
+
ShowParams(), ShowProcesses(), ShowCassandraRepairs(), ShowStorage(), ShowAdam(),
|
|
36
|
+
ShowCassandraStatus(), ShowCassandraVersion(), MedusaShowRestoreJobs(), MedusaShowBackupJobs()]
|
|
37
|
+
|
|
38
|
+
class ShowCommandHelper(click.Command):
|
|
39
|
+
def get_help(self, ctx: click.Context):
|
|
40
|
+
IntermediateCommand.intermediate_help(super().get_help(ctx), Show.COMMAND, Show().cmd_list(), show_cluster_help=True)
|
adam/config.py
CHANGED
|
@@ -3,11 +3,11 @@ from typing import TypeVar, cast
|
|
|
3
3
|
import yaml
|
|
4
4
|
|
|
5
5
|
from . import __version__
|
|
6
|
-
from adam.utils import copy_config_file, get_deep_keys, log2
|
|
6
|
+
from adam.utils import ConfigHolder, ConfigReadable, copy_config_file, get_deep_keys, log2
|
|
7
7
|
|
|
8
8
|
T = TypeVar('T')
|
|
9
9
|
|
|
10
|
-
class Config:
|
|
10
|
+
class Config(ConfigReadable):
|
|
11
11
|
EMBEDDED_PARAMS = {}
|
|
12
12
|
|
|
13
13
|
# the singleton pattern
|
|
@@ -25,6 +25,8 @@ class Config:
|
|
|
25
25
|
except:
|
|
26
26
|
with open(copy_config_file(f'params.yaml.{__version__}', 'adam.embedded_params', show_out=not is_user_entry)) as f:
|
|
27
27
|
self.params = cast(dict[str, any], yaml.safe_load(f))
|
|
28
|
+
|
|
29
|
+
ConfigHolder().config = self
|
|
28
30
|
elif not hasattr(self, 'params'):
|
|
29
31
|
with open(copy_config_file(f'params.yaml.{__version__}', 'adam.embedded_params', show_out=not is_user_entry)) as f:
|
|
30
32
|
self.params = cast(dict[str, any], yaml.safe_load(f))
|
|
@@ -41,10 +43,6 @@ class Config:
|
|
|
41
43
|
def is_debug(self):
|
|
42
44
|
return os.getenv('QING_DEV', 'false').lower() == 'true' or Config().get('debug', False)
|
|
43
45
|
|
|
44
|
-
def debug(self, s: None):
|
|
45
|
-
if self.is_debug():
|
|
46
|
-
log2(f'DEBUG {s}')
|
|
47
|
-
|
|
48
46
|
def get(self, key: str, default: T) -> T:
|
|
49
47
|
# params['nodetool']['status']['max-nodes']
|
|
50
48
|
d = self.params
|
|
@@ -85,12 +83,4 @@ class Config:
|
|
|
85
83
|
log2(f'incorrect path: {key}')
|
|
86
84
|
return None
|
|
87
85
|
|
|
88
|
-
return v if v else 'false'
|
|
89
|
-
|
|
90
|
-
def wait_log(self, msg: str):
|
|
91
|
-
if hasattr(self, 'wait_log_flag') and not self.wait_log_flag:
|
|
92
|
-
log2(msg)
|
|
93
|
-
self.wait_log_flag = True
|
|
94
|
-
|
|
95
|
-
def clear_wait_log_flag(self):
|
|
96
|
-
self.wait_log_flag = False
|
|
86
|
+
return v if v else 'false'
|
adam/embedded_params.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
def config():
|
|
2
|
-
return {'app': {'console-endpoint': 'https://{host}/{env}/{app}/static/console/index.html', 'cr': {'cluster-regex': '(.*?-.*?)-.*', 'group': 'ops.c3.ai', 'v': 'v2', 'plural': 'c3cassandras'}, 'label': 'c3__app_id-0', 'login': {'admin-group': '{host}/C3.ClusterAdmin', 'ingress': '{app_id}-k8singr-appleader-001', 'timeout': 5, 'session-check-url': 'https://{host}/{env}/{app}/api/8/C3/userSessionToken', 'cache-creds': True, 'cache-username': True, 'url': 'https://{host}/{env}/{app}', 'another': "You're logged in to {has}. However, for this app, you need to log in to {need}.", 'token-server-url': 'http://localhost:{port}', 'password-max-length': 128}, 'strip': '0'}, 'audit': {'endpoint': 'https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/', 'workers': 3, 'timeout': 10, 'log-audit-queries': False, 'athena': {'auto-repair': {'elapsed_hours': 12}, 'region': 'us-west-2', 'catalog': 'AwsDataCatalog', 'database': 'audit', 'repair-partition-tables': 'audit', 'output': 's3://s3.ops--audit/ddl/results', 'repair-cluster-tables': 'cluster'}}, 'bash': {'workers': 32}, 'cassandra': {'service-name': 'all-pods-service'}, 'cql': {'workers': 32, 'samples': 3, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-superuser', 'password-item': 'password'}, 'alter-tables': {'excludes': 'system_auth,system_traces,reaper_db,system_distributed,system_views,system,system_schema,system_virtual_schema', 'gc-grace-periods': '3600,86400,864000,7776000', 'batching': True}}, 'checks': {'compactions-threshold': 250, 'cpu-busy-threshold': 98.0, 'cpu-threshold': 0.0, 'cassandra-data-path': '/c3/cassandra', 'root-disk-threshold': 50, 'cassandra-disk-threshold': 50, 'snapshot-size-cmd': "ls /c3/cassandra/data/data/*/*/snapshots | grep snapshots | sed 's/:$//g' | xargs -I {} du -sk {} | awk '{print $1}' | awk '{s+=$1} END {print s}'", 'snapshot-size-threshold': '40G', 'table-sizes-cmd': "ls -Al /c3/cassandra/data/data/ | awk '{print $9}' | sed 's/\\^r//g' | xargs -I {} du -sk /c3/cassandra/data/data/{}"}, 'get-host-id': {'workers': 32}, 'idps': {'ad': {'email-pattern': '.*@c3.ai', 'uri': 'https://login.microsoftonline.com/53ad779a-93e7-485c-ba20-ac8290d7252b/oauth2/v2.0/authorize?response_type=id_token&response_mode=form_post&client_id=00ff94a8-6b0a-4715-98e0-95490012d818&scope=openid+email+profile&redirect_uri=https%3A%2F%2Fplat.c3ci.cloud%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://login.microsoftonline.com/common/discovery/keys', 'contact': 'Please contact ted.tran@c3.ai.', 'whitelist-file': '/kaqing/members'}, 'okta': {'default': True, 'email-pattern': '.*@c3iot.com', 'uri': 'https://c3energy.okta.com/oauth2/v1/authorize?response_type=id_token&response_mode=form_post&client_id={client_id}&scope=openid+email+profile+groups&redirect_uri=https%3A%2F%2F{host}%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://c3energy.okta.com/oauth2/v1/keys'}}, 'issues': {'workers': 32}, 'logs': {'path': '/c3/cassandra/logs/system.log'}, '
|
|
2
|
+
return {'app': {'console-endpoint': 'https://{host}/{env}/{app}/static/console/index.html', 'container-name': 'c3-server', 'cr': {'cluster-regex': '(.*?-.*?)-.*', 'group': 'ops.c3.ai', 'v': 'v2', 'plural': 'c3cassandras'}, 'label': 'c3__app_id-0', 'login': {'admin-group': '{host}/C3.ClusterAdmin', 'ingress': '{app_id}-k8singr-appleader-001', 'timeout': 5, 'session-check-url': 'https://{host}/{env}/{app}/api/8/C3/userSessionToken', 'cache-creds': True, 'cache-username': True, 'url': 'https://{host}/{env}/{app}', 'another': "You're logged in to {has}. However, for this app, you need to log in to {need}.", 'token-server-url': 'http://localhost:{port}', 'password-max-length': 128}, 'strip': '0'}, 'audit': {'endpoint': 'https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/', 'workers': 3, 'timeout': 10, 'log-audit-queries': False, 'athena': {'auto-repair': {'elapsed_hours': 12}, 'region': 'us-west-2', 'catalog': 'AwsDataCatalog', 'database': 'audit', 'repair-partition-tables': 'audit', 'output': 's3://s3.ops--audit/ddl/results', 'repair-cluster-tables': 'cluster'}, 'queries': {'last10': "SELECT * FROM audit\nWHERE drive <> 'z' and ({date_condition})\nORDER BY ts DESC LIMIT {limit}", 'slow10': "SELECT * FROM audit\nWHERE drive <> 'z' and ({date_condition})\nORDER BY CAST(duration AS REAL) DESC LIMIT {limit}", 'top10': "SELECT min(c) AS cluster, line, COUNT(*) AS cnt, avg(CAST(duration AS REAL)) AS duration\nFROM audit WHERE drive <> 'z' and ({date_condition})\nGROUP BY line ORDER BY cnt DESC LIMIT {limit}"}}, 'bash': {'workers': 32}, 'cassandra': {'service-name': 'all-pods-service'}, 'cql': {'workers': 32, 'samples': 3, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-superuser', 'password-item': 'password'}, 'alter-tables': {'excludes': 'system_auth,system_traces,reaper_db,system_distributed,system_views,system,system_schema,system_virtual_schema', 'gc-grace-periods': '3600,86400,864000,7776000', 'batching': True}}, 'checks': {'compactions-threshold': 250, 'cpu-busy-threshold': 98.0, 'cpu-threshold': 0.0, 'cassandra-data-path': '/c3/cassandra', 'root-disk-threshold': 50, 'cassandra-disk-threshold': 50, 'snapshot-size-cmd': "ls /c3/cassandra/data/data/*/*/snapshots | grep snapshots | sed 's/:$//g' | xargs -I {} du -sk {} | awk '{print $1}' | awk '{s+=$1} END {print s}'", 'snapshot-size-threshold': '40G', 'table-sizes-cmd': "ls -Al /c3/cassandra/data/data/ | awk '{print $9}' | sed 's/\\^r//g' | xargs -I {} du -sk /c3/cassandra/data/data/{}"}, 'download': {'workers': 8}, 'export': {'workers': 8, 'csv_dir': '/c3/cassandra/tmp', 'column_counts_query': 'select id, count(id) as columns from {table} group by id order by columns desc limit 10', 'default-importer': 'sqlite', 'sqlite': {'workers': 8, 'columns': '<row-key>', 'local-db-dir': '/tmp/qing-db/q/export/db'}, 'athena': {'workers': 8, 'columns': '<keys>', 'bucket': 'c3.ops--qing'}, 'csv': {'workers': 8, 'columns': '<row-key>'}, 'log-dir': '/tmp/qing-db/q/export/logs'}, 'get-host-id': {'workers': 32}, 'idps': {'ad': {'email-pattern': '.*@c3.ai', 'uri': 'https://login.microsoftonline.com/53ad779a-93e7-485c-ba20-ac8290d7252b/oauth2/v2.0/authorize?response_type=id_token&response_mode=form_post&client_id=00ff94a8-6b0a-4715-98e0-95490012d818&scope=openid+email+profile&redirect_uri=https%3A%2F%2Fplat.c3ci.cloud%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://login.microsoftonline.com/common/discovery/keys', 'contact': 'Please contact ted.tran@c3.ai.', 'whitelist-file': '/kaqing/members'}, 'okta': {'default': True, 'email-pattern': '.*@c3iot.com', 'uri': 'https://c3energy.okta.com/oauth2/v1/authorize?response_type=id_token&response_mode=form_post&client_id={client_id}&scope=openid+email+profile+groups&redirect_uri=https%3A%2F%2F{host}%2Fc3%2Fc3%2Foidc%2Flogin&nonce={nonce}&state=EMPTY', 'jwks-uri': 'https://c3energy.okta.com/oauth2/v1/keys'}}, 'issues': {'workers': 32}, 'local-qing-dir': '/tmp/qing-db/q', 'local-downloads-dir': '/tmp/qing-db/q/downloads', 'logs': {'path': '/c3/cassandra/logs/system.log'}, 'log-dir': '/tmp/qing-db/q/logs', 'nodetool': {'workers': 96, 'commands_in_line': 40, 'status': {'workers': 32, 'samples': 3, 'commands_in_line': 40}}, 'pg': {'name-pattern': '^{namespace}.*-k8spg-.*', 'excludes': '.helm., -admin-secret', 'agent': {'name': 'ops-pg-agent', 'just-in-time': False, 'timeout': 86400, 'image': 'seanahnsf/kaqing'}, 'default-db': 'postgres', 'default-schema': 'postgres', 'secret': {'endpoint-key': 'postgres-db-endpoint', 'port-key': 'postgres-db-port', 'username-key': 'postgres-admin-username', 'password-key': 'postgres-admin-password'}}, 'pod': {'name': 'ops', 'image': 'seanahnsf/kaqing-cloud', 'sa': {'name': 'ops', 'proto': 'c3', 'additional-cluster-roles': 'c3aiops-k8ssandra-operator'}, 'label-selector': 'run=ops'}, 'preview': {'rows': 10}, 'processes': {'columns': 'pod,cpu-metrics,mem', 'header': 'POD_NAME,M_CPU(USAGE/LIMIT),MEM/LIMIT'}, 'processes-qing': {'columns': 'pod,cpu,mem', 'header': 'POD_NAME,Q_CPU/TOTAL,MEM/LIMIT'}, 'reaper': {'service-name': 'reaper-service', 'port-forward': {'timeout': 86400, 'local-port': 9001}, 'abort-runs-batch': 10, 'show-runs-batch': 100, 'pod': {'cluster-regex': '(.*?-.*?-.*?-.*?)-.*', 'label-selector': 'k8ssandra.io/reaper={cluster}-reaper'}, 'secret': {'cluster-regex': '(.*?-.*?)-.*', 'name': '{cluster}-reaper-ui', 'password-item': 'password'}}, 'repair': {'log-path': '/home/cassrepair/logs/', 'image': 'ci-registry.c3iot.io/cloudops/cassrepair:2.0.14', 'secret': 'ciregistryc3iotio', 'env': {'interval': 24, 'timeout': 60, 'pr': False, 'runs': 1}}, 'repl': {'start-drive': 'c', 'a': {'auto-enter': 'c3/c3'}, 'c': {'auto-enter': 'cluster'}, 'x': {'auto-enter': 'latest'}, 'history': {'push-cat-log-file': True, 'push-cat-remote-log-file': True}, 'background-process': {'auto-nohup': True}}, 'status': {'columns': 'status,address,load,tokens,owns,host_id,gossip,compactions', 'header': '--,Address,Load,Tokens,Owns,Host ID,GOSSIP,COMPACTIONS'}, 'storage': {'columns': 'pod,volume_root,volume_cassandra,snapshots,data,compactions', 'header': 'POD_NAME,VOLUME /,VOLUME CASS,SNAPSHOTS,DATA,COMPACTIONS'}, 'watch': {'auto': 'rollout', 'timeout': 3600, 'interval': 10}, 'auto-complete': {'c': {'tables': 'lazy', 'table-props-value': 'jit'}, 'x': {'tables': 'lazy'}, 'cli': {'cp': 'jit'}, 'export': {'databases': 'jit'}, 'medusa': {'backups': 'jit'}, 'reaper': {'schedules': 'jit'}}, 'debug': False, 'debugs': {'complete': False, 'timings': False, 'exit-on-error': False}}
|
adam/log.py
CHANGED
|
@@ -4,6 +4,8 @@ import os
|
|
|
4
4
|
import sys
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
|
+
from adam.utils import log_exc
|
|
8
|
+
|
|
7
9
|
class Log:
|
|
8
10
|
DEBUG = False
|
|
9
11
|
|
|
@@ -28,7 +30,7 @@ class Log:
|
|
|
28
30
|
print(file=sys.stderr)
|
|
29
31
|
|
|
30
32
|
def log_to_file(config: dict[any, any]):
|
|
31
|
-
|
|
33
|
+
with log_exc():
|
|
32
34
|
base = f"/tmp/logs"
|
|
33
35
|
os.makedirs(base, exist_ok=True)
|
|
34
36
|
|
|
@@ -42,6 +44,4 @@ class Log:
|
|
|
42
44
|
except:
|
|
43
45
|
f.write(config)
|
|
44
46
|
else:
|
|
45
|
-
f.write(config)
|
|
46
|
-
except:
|
|
47
|
-
pass
|
|
47
|
+
f.write(config)
|
adam/repl.py
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import re
|
|
3
2
|
import time
|
|
4
|
-
import
|
|
3
|
+
from typing import cast
|
|
5
4
|
import click
|
|
6
|
-
import concurrent
|
|
7
|
-
from prompt_toolkit.completion import NestedCompleter
|
|
8
5
|
from prompt_toolkit.key_binding import KeyBindings
|
|
9
6
|
|
|
10
7
|
from adam.cli_group import cli
|
|
11
|
-
from adam.commands.command import Command
|
|
8
|
+
from adam.commands.command import Command, InvalidArgumentsException, InvalidStateException
|
|
12
9
|
from adam.commands.command_helpers import ClusterCommandHelper
|
|
10
|
+
from adam.commands.devices.devices import Devices
|
|
13
11
|
from adam.commands.help import Help
|
|
14
|
-
from adam.commands.postgres.postgres_context import PostgresContext
|
|
15
12
|
from adam.config import Config
|
|
13
|
+
from adam.sql.async_executor import AsyncExecutor
|
|
16
14
|
from adam.utils_audits import Audits
|
|
17
15
|
from adam.utils_k8s.kube_context import KubeContext
|
|
18
|
-
from adam.utils_k8s.statefulsets import StatefulSets
|
|
19
16
|
from adam.log import Log
|
|
20
17
|
from adam.repl_commands import ReplCommands
|
|
21
18
|
from adam.repl_session import ReplSession
|
|
22
19
|
from adam.repl_state import ReplState
|
|
23
|
-
from adam.utils import
|
|
20
|
+
from adam.utils import CommandLog, clear_wait_log_flag, debug_trace, deep_sort_dict, tabulize, log2, log_exc, log_timing
|
|
24
21
|
from adam.apps import Apps
|
|
22
|
+
from adam.utils_repl.repl_completer import ReplCompleter, merge_completions
|
|
25
23
|
from . import __version__
|
|
26
24
|
|
|
25
|
+
import nest_asyncio
|
|
26
|
+
nest_asyncio.apply()
|
|
27
|
+
|
|
28
|
+
import asyncio
|
|
29
|
+
|
|
27
30
|
def enter_repl(state: ReplState):
|
|
28
31
|
if os.getenv('QING_DROPPED', 'false') == 'true':
|
|
29
32
|
log2('You have dropped to bash from another qing instance. Please enter "exit" to go back to qing.')
|
|
@@ -35,66 +38,13 @@ def enter_repl(state: ReplState):
|
|
|
35
38
|
session = ReplSession().prompt_session
|
|
36
39
|
|
|
37
40
|
def prompt_msg():
|
|
38
|
-
msg =
|
|
39
|
-
if state.device == ReplState.P:
|
|
40
|
-
msg = f'{ReplState.P}:'
|
|
41
|
-
pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path) if state.pg_path else None
|
|
42
|
-
if pg and pg.db:
|
|
43
|
-
msg += pg.db
|
|
44
|
-
elif pg and pg.host:
|
|
45
|
-
msg += pg.host
|
|
46
|
-
elif state.device == ReplState.A:
|
|
47
|
-
msg = f'{ReplState.A}:'
|
|
48
|
-
if state.app_env:
|
|
49
|
-
msg += state.app_env
|
|
50
|
-
if state.app_app:
|
|
51
|
-
msg += f'/{state.app_app}'
|
|
52
|
-
elif state.device == ReplState.L:
|
|
53
|
-
msg = f'{ReplState.L}:'
|
|
54
|
-
else:
|
|
55
|
-
msg = f'{ReplState.C}:'
|
|
56
|
-
if state.pod:
|
|
57
|
-
# cs-d0767a536f-cs-d0767a536f-default-sts-0
|
|
58
|
-
group = re.match(r".*?-.*?-(.*)", state.pod)
|
|
59
|
-
msg += group[1]
|
|
60
|
-
elif state.sts:
|
|
61
|
-
# cs-d0767a536f-cs-d0767a536f-default-sts
|
|
62
|
-
group = re.match(r".*?-.*?-(.*)", state.sts)
|
|
63
|
-
msg += group[1]
|
|
41
|
+
msg = state.__str__()
|
|
64
42
|
|
|
65
43
|
return f"{msg}$ " if state.bash_session else f"{msg}> "
|
|
66
44
|
|
|
67
45
|
Log.log2(f'kaqing {__version__}')
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
auto_enter = Config().get('repl.c.auto-enter', 'cluster')
|
|
71
|
-
if auto_enter and auto_enter in ['cluster', 'first-pod']:
|
|
72
|
-
ss = StatefulSets.list_sts_name_and_ns()
|
|
73
|
-
if not ss:
|
|
74
|
-
log2("No Cassandra clusters found.")
|
|
75
|
-
elif not state.sts and len(ss) == 1:
|
|
76
|
-
cluster = ss[0]
|
|
77
|
-
state.sts = cluster[0]
|
|
78
|
-
state.namespace = cluster[1]
|
|
79
|
-
if auto_enter == 'first-pod':
|
|
80
|
-
state.pod = f'{state.sts}-0'
|
|
81
|
-
if KubeContext().in_cluster_namespace:
|
|
82
|
-
Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}...')
|
|
83
|
-
else:
|
|
84
|
-
Config().wait_log(f'Moving to the only Cassandra cluster: {state.sts}@{state.namespace}...')
|
|
85
|
-
elif state.device == ReplState.A:
|
|
86
|
-
if not state.app_env:
|
|
87
|
-
if app := Config().get('repl.a.auto-enter-app', 'c3/c3'):
|
|
88
|
-
if app != 'no':
|
|
89
|
-
ea = app.split('/')
|
|
90
|
-
state.app_env = ea[0]
|
|
91
|
-
if len(ea) > 1:
|
|
92
|
-
state.app_app = ea[1]
|
|
93
|
-
Config().wait_log(f'Moving to {state.app_env}/{state.app_app}...')
|
|
94
|
-
else:
|
|
95
|
-
Config().wait_log(f'Moving to {state.app_env}...')
|
|
96
|
-
elif state.device == ReplState.P:
|
|
97
|
-
Config().wait_log('Inspecting postgres database instances...')
|
|
47
|
+
Devices.of(state).enter(state)
|
|
98
48
|
|
|
99
49
|
kb = KeyBindings()
|
|
100
50
|
|
|
@@ -102,34 +52,34 @@ def enter_repl(state: ReplState):
|
|
|
102
52
|
def _(event):
|
|
103
53
|
event.app.current_buffer.text = ''
|
|
104
54
|
|
|
105
|
-
with
|
|
55
|
+
with Audits.offload() as exec:
|
|
106
56
|
# warm up AWS lambda - this log line may timeout and get lost, which is fine
|
|
107
|
-
|
|
57
|
+
exec.submit(Audits.log, 'entering kaqing repl', state.namespace, 'z', 0.0)
|
|
108
58
|
|
|
109
59
|
s0 = time.time()
|
|
110
60
|
|
|
111
61
|
# use sorted command list only for auto-completion
|
|
112
62
|
sorted_cmds = sorted(cmd_list, key=lambda cmd: cmd.command())
|
|
113
63
|
while True:
|
|
64
|
+
AsyncExecutor.reset()
|
|
65
|
+
|
|
66
|
+
cmd: str = None
|
|
114
67
|
result = None
|
|
115
68
|
try:
|
|
116
|
-
completer =
|
|
69
|
+
completer = ReplCompleter.from_nested_dict({})
|
|
117
70
|
if not state.bash_session:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
# print(json.dumps(completions, indent=4))
|
|
132
|
-
completer = NestedCompleter.from_nested_dict(completions)
|
|
71
|
+
with log_timing('completion-calcs'):
|
|
72
|
+
completions = {}
|
|
73
|
+
# app commands are available only on a: drive
|
|
74
|
+
if state.device == ReplState.A and state.app_app:
|
|
75
|
+
completions = log_timing('actions', lambda: Apps(path='apps.yaml').commands())
|
|
76
|
+
|
|
77
|
+
for c in sorted_cmds:
|
|
78
|
+
with log_exc(f'* {c.command()} command returned None completions.'):
|
|
79
|
+
completions = log_timing(c.command(), lambda: deep_sort_dict(merge_completions(completions, c.completion(state))))
|
|
80
|
+
|
|
81
|
+
# print(json.dumps(completions, indent=4))
|
|
82
|
+
completer = ReplCompleter.from_nested_dict(completions)
|
|
133
83
|
|
|
134
84
|
cmd = session.prompt(prompt_msg(), completer=completer, key_bindings=kb)
|
|
135
85
|
s0 = time.time()
|
|
@@ -141,9 +91,40 @@ def enter_repl(state: ReplState):
|
|
|
141
91
|
|
|
142
92
|
cmd = f'bash {cmd}'
|
|
143
93
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
94
|
+
def targetted(state: ReplState, cmd: str):
|
|
95
|
+
if not (cmd.startswith('@') and len(arry := cmd.split(' ')) > 1):
|
|
96
|
+
return state, cmd
|
|
97
|
+
|
|
98
|
+
if state.device == ReplState.A and state.app_app or state.device == ReplState.P:
|
|
99
|
+
state.push(pod_targetted=True)
|
|
100
|
+
|
|
101
|
+
state.app_pod = arry[0].strip('@')
|
|
102
|
+
cmd = ' '.join(arry[1:])
|
|
103
|
+
elif state.device == ReplState.P:
|
|
104
|
+
state.push(pod_targetted=True)
|
|
105
|
+
|
|
106
|
+
state.app_pod = arry[0].strip('@')
|
|
107
|
+
cmd = ' '.join(arry[1:])
|
|
108
|
+
elif state.sts:
|
|
109
|
+
state.push(pod_targetted=True)
|
|
110
|
+
|
|
111
|
+
state.pod = arry[0].strip('@')
|
|
112
|
+
cmd = ' '.join(arry[1:])
|
|
113
|
+
|
|
114
|
+
return (state, cmd)
|
|
115
|
+
|
|
116
|
+
target, cmd = targetted(state, cmd)
|
|
117
|
+
try:
|
|
118
|
+
if cmd and cmd.strip(' ') and not (result := cmds.run(cmd, target)):
|
|
119
|
+
result = try_device_default_action(target, cmds, cmd_list, cmd)
|
|
120
|
+
except InvalidStateException:
|
|
121
|
+
pass
|
|
122
|
+
except InvalidArgumentsException:
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
if result and type(result) is ReplState and (s := cast(ReplState, result).export_session) != state.export_session:
|
|
126
|
+
state.export_session = s
|
|
127
|
+
|
|
147
128
|
except EOFError: # Handle Ctrl+D (EOF) for graceful exit
|
|
148
129
|
break
|
|
149
130
|
except Exception as e:
|
|
@@ -151,45 +132,28 @@ def enter_repl(state: ReplState):
|
|
|
151
132
|
raise e
|
|
152
133
|
else:
|
|
153
134
|
log2(e)
|
|
154
|
-
|
|
135
|
+
debug_trace()
|
|
155
136
|
finally:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
137
|
+
if not state.bash_session:
|
|
138
|
+
state.pop()
|
|
139
|
+
|
|
140
|
+
clear_wait_log_flag()
|
|
141
|
+
if cmd:
|
|
142
|
+
log_timing(f'command {cmd}', s0=s0)
|
|
159
143
|
|
|
160
144
|
# offload audit logging
|
|
161
145
|
if cmd and (state.device != ReplState.L or Config().get('audit.log-audit-queries', False)):
|
|
162
|
-
|
|
146
|
+
exec.submit(Audits.log, cmd, state.namespace, state.device, time.time() - s0, get_audit_extra(result))
|
|
147
|
+
|
|
148
|
+
CommandLog.close_log_file()
|
|
163
149
|
|
|
164
150
|
def try_device_default_action(state: ReplState, cmds: Command, cmd_list: list[Command], cmd: str):
|
|
165
|
-
result =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if state.device == ReplState.P:
|
|
169
|
-
pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path)
|
|
170
|
-
if pg.db:
|
|
171
|
-
c_sql_tried = True
|
|
172
|
-
cmd = f'pg {cmd}'
|
|
173
|
-
result = cmds.run(cmd, state)
|
|
174
|
-
elif state.device == ReplState.A:
|
|
175
|
-
if state.app_app:
|
|
176
|
-
c_sql_tried = True
|
|
177
|
-
cmd = f'app {cmd}'
|
|
178
|
-
result = cmds.run(cmd, state)
|
|
179
|
-
elif state.device == ReplState.L:
|
|
180
|
-
c_sql_tried = True
|
|
181
|
-
cmd = f'audit {cmd}'
|
|
182
|
-
result = cmds.run(cmd, state)
|
|
183
|
-
elif state.sts:
|
|
184
|
-
c_sql_tried = True
|
|
185
|
-
cmd = f'cql {cmd}'
|
|
186
|
-
result = cmds.run(cmd, state)
|
|
187
|
-
|
|
188
|
-
if not c_sql_tried:
|
|
151
|
+
action_taken, result = Devices.of(state).try_fallback_action(cmds, state, cmd)
|
|
152
|
+
|
|
153
|
+
if not action_taken:
|
|
189
154
|
log2(f'* Invalid command: {cmd}')
|
|
190
155
|
log2()
|
|
191
|
-
|
|
192
|
-
log2(lines_to_tabular(lines, separator='\t'))
|
|
156
|
+
tabulize([c.help(state) for c in cmd_list if c.help(state)], separator='\t', to=2)
|
|
193
157
|
|
|
194
158
|
return result
|
|
195
159
|
|
|
@@ -221,6 +185,9 @@ def repl(kubeconfig: str, config: str, param: list[str], cluster:str, namespace:
|
|
|
221
185
|
if not KubeContext.init_params(config, param):
|
|
222
186
|
return
|
|
223
187
|
|
|
224
|
-
state = ReplState(
|
|
188
|
+
state = ReplState(ns_sts=cluster, namespace=namespace, in_repl=True)
|
|
225
189
|
state, _ = state.apply_device_arg(extra_args)
|
|
190
|
+
if not state.device:
|
|
191
|
+
state.device=Config().get('repl.start-drive', 'a')
|
|
192
|
+
|
|
226
193
|
enter_repl(state)
|
adam/repl_commands.py
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
-
from adam.commands.
|
|
2
|
-
from adam.commands.app import
|
|
3
|
-
from adam.commands.
|
|
1
|
+
from adam.commands.app.app import App
|
|
2
|
+
from adam.commands.app.app_ping import AppPing
|
|
3
|
+
from adam.commands.app.show_app_actions import ShowAppActions
|
|
4
|
+
from adam.commands.app.show_app_id import ShowAppId
|
|
5
|
+
from adam.commands.app.show_app_queues import ShowAppQueues
|
|
4
6
|
from adam.commands.audit.audit import Audit
|
|
5
|
-
from adam.commands.
|
|
6
|
-
from adam.commands.
|
|
7
|
+
from adam.commands.cassandra.restart_cluster import RestartCluster
|
|
8
|
+
from adam.commands.cassandra.restart_node import RestartNode
|
|
9
|
+
from adam.commands.cassandra.restart_nodes import RestartNodes
|
|
10
|
+
from adam.commands.cassandra.rollout import RollOut
|
|
11
|
+
from adam.commands.cassandra.show_cassandra_repairs import ShowCassandraRepairs
|
|
12
|
+
from adam.commands.cassandra.show_cassandra_status import ShowCassandraStatus
|
|
13
|
+
from adam.commands.cassandra.show_cassandra_version import ShowCassandraVersion
|
|
14
|
+
from adam.commands.cassandra.show_processes import ShowProcesses
|
|
15
|
+
from adam.commands.cassandra.show_storage import ShowStorage
|
|
16
|
+
from adam.commands.cassandra.watch import Watch
|
|
17
|
+
from adam.commands.cli.clipboard_copy import ClipboardCopy
|
|
18
|
+
from adam.commands.config.param_get import GetParam
|
|
19
|
+
from adam.commands.config.param_set import SetParam
|
|
20
|
+
from adam.commands.debug.show_offloaded_completes import ShowOffloadedCompletes
|
|
21
|
+
from adam.commands.diag.check import Check
|
|
22
|
+
from adam.commands.diag.generate_report import GenerateReport
|
|
23
|
+
from adam.commands.diag.issues import Issues
|
|
24
|
+
from adam.commands.fs.cat import Cat
|
|
25
|
+
from adam.commands.code import Code
|
|
26
|
+
from adam.commands.cql.alter_tables import AlterTables
|
|
27
|
+
from adam.commands.debug.debug import Debug
|
|
28
|
+
from adam.commands.cassandra.download_cassandra_log import DownloadCassandraLog
|
|
29
|
+
from adam.commands.fs.cat_local import CatLocal
|
|
30
|
+
from adam.commands.fs.download_file import DownloadFile
|
|
7
31
|
from adam.commands.deploy.code_start import CodeStart
|
|
8
32
|
from adam.commands.deploy.code_stop import CodeStop
|
|
9
33
|
from adam.commands.deploy.deploy import Deploy
|
|
@@ -14,51 +38,59 @@ from adam.commands.deploy.undeploy import Undeploy
|
|
|
14
38
|
from adam.commands.deploy.undeploy_frontend import UndeployFrontend
|
|
15
39
|
from adam.commands.deploy.undeploy_pg_agent import UndeployPgAgent
|
|
16
40
|
from adam.commands.deploy.undeploy_pod import UndeployPod
|
|
17
|
-
from adam.commands.
|
|
18
|
-
from adam.commands.
|
|
19
|
-
from adam.commands.
|
|
20
|
-
from adam.commands.
|
|
21
|
-
from adam.commands.
|
|
22
|
-
from adam.commands.
|
|
41
|
+
from adam.commands.devices.device_app import DeviceApp
|
|
42
|
+
from adam.commands.devices.device_auit_log import DeviceAuditLog
|
|
43
|
+
from adam.commands.devices.device_cass import DeviceCass
|
|
44
|
+
from adam.commands.devices.device_export import DeviceExport
|
|
45
|
+
from adam.commands.devices.device_postgres import DevicePostgres
|
|
46
|
+
from adam.commands.export.download_export_session import DownloadExportSession
|
|
47
|
+
from adam.commands.export.drop_export_database import DropExportDatabase
|
|
48
|
+
from adam.commands.export.export import ExportTables
|
|
49
|
+
from adam.commands.export.import_files import ImportCSVFiles
|
|
50
|
+
from adam.commands.export.import_session import ImportSession
|
|
51
|
+
from adam.commands.export.clean_up_export_sessions import CleanUpExportSessions
|
|
52
|
+
from adam.commands.export.clean_up_all_export_sessions import CleanUpAllExportSessions
|
|
53
|
+
from adam.commands.export.drop_export_databases import DropExportDatabases
|
|
54
|
+
from adam.commands.export.export_x_select import ExportXSelect
|
|
55
|
+
from adam.commands.export.export_use import ExportUse
|
|
56
|
+
from adam.commands.export.export_select import ExportSelect
|
|
57
|
+
from adam.commands.export.show_column_counts import ShowColumnCounts
|
|
58
|
+
from adam.commands.export.show_export_databases import ShowExportDatabases
|
|
59
|
+
from adam.commands.export.show_export_session import ShowExportSession
|
|
60
|
+
from adam.commands.export.show_export_sessions import ShowExportSessions
|
|
61
|
+
from adam.commands.fs.find_files import FindLocalFiles
|
|
62
|
+
from adam.commands.fs.find_processes import FindProcesses
|
|
63
|
+
from adam.commands.fs.head import Head
|
|
64
|
+
from adam.commands.fs.ls_local import LsLocal
|
|
65
|
+
from adam.commands.fs.rm import RmLocal
|
|
66
|
+
from adam.commands.kubectl import Kubectl
|
|
67
|
+
from adam.commands.fs.shell import Shell
|
|
68
|
+
from adam.commands.bash.bash import Bash
|
|
69
|
+
from adam.commands.fs.cd import Cd
|
|
23
70
|
from adam.commands.command import Command
|
|
24
71
|
from adam.commands.cql.cqlsh import Cqlsh
|
|
25
|
-
from adam.commands.devices import DeviceApp, DeviceAuditLog, DeviceCass, DevicePostgres
|
|
26
72
|
from adam.commands.exit import Exit
|
|
27
73
|
from adam.commands.medusa.medusa import Medusa
|
|
28
|
-
from adam.commands.
|
|
29
|
-
from adam.commands.
|
|
30
|
-
from adam.commands.
|
|
31
|
-
from adam.commands.nodetool import NodeTool
|
|
32
|
-
from adam.commands.postgres.postgres import Postgres
|
|
74
|
+
from adam.commands.fs.ls import Ls
|
|
75
|
+
from adam.commands.nodetool.nodetool import NodeTool
|
|
76
|
+
from adam.commands.postgres.postgres import Postgres, PostgresPg
|
|
33
77
|
from adam.commands.preview_table import PreviewTable
|
|
34
|
-
from adam.commands.pwd import Pwd
|
|
78
|
+
from adam.commands.fs.pwd import Pwd
|
|
35
79
|
from adam.commands.reaper.reaper import Reaper
|
|
36
80
|
from adam.commands.repair.repair import Repair
|
|
37
|
-
from adam.commands.
|
|
38
|
-
from adam.commands.
|
|
39
|
-
from adam.commands.
|
|
40
|
-
from adam.commands.
|
|
41
|
-
from adam.commands.
|
|
42
|
-
from adam.commands.show
|
|
43
|
-
from adam.commands.show.show_app_id import ShowAppId
|
|
44
|
-
from adam.commands.show.show_cassandra_status import ShowCassandraStatus
|
|
45
|
-
from adam.commands.show.show_cassandra_version import ShowCassandraVersion
|
|
46
|
-
from adam.commands.show.show_commands import ShowKubectlCommands
|
|
47
|
-
from adam.commands.show.show_host import ShowHost
|
|
48
|
-
from adam.commands.show.show_login import ShowLogin
|
|
49
|
-
from adam.commands.show.show_params import ShowParams
|
|
50
|
-
from adam.commands.show.show_processes import ShowProcesses
|
|
51
|
-
from adam.commands.show.show_repairs import ShowRepairs
|
|
52
|
-
from adam.commands.show.show_storage import ShowStorage
|
|
53
|
-
from adam.commands.show.show_adam import ShowAdam
|
|
54
|
-
from adam.commands.watch import Watch
|
|
81
|
+
from adam.commands.cli.show_cli_commands import ShowKubectlCommands
|
|
82
|
+
from adam.commands.fs.show_host import ShowHost
|
|
83
|
+
from adam.commands.app.show_login import ShowLogin
|
|
84
|
+
from adam.commands.config.show_params import ShowParams
|
|
85
|
+
from adam.commands.fs.show_adam import ShowAdam
|
|
86
|
+
from adam.commands.show import Show
|
|
55
87
|
|
|
56
88
|
class ReplCommands:
|
|
57
89
|
def repl_cmd_list() -> list[Command]:
|
|
58
90
|
cmds: list[Command] = ReplCommands.navigation() + ReplCommands.cassandra_ops() + ReplCommands.postgres_ops() + \
|
|
59
|
-
ReplCommands.app_ops() + ReplCommands.audit_ops() + ReplCommands.tools() + ReplCommands.exit()
|
|
91
|
+
ReplCommands.app_ops() + ReplCommands.audit_ops() + ReplCommands.export_ops() + ReplCommands.tools() + ReplCommands.exit()
|
|
60
92
|
|
|
61
|
-
intermediate_cmds: list[Command] = [App(), Audit(), Reaper(), Repair(), Deploy(), Show(), Undeploy()]
|
|
93
|
+
intermediate_cmds: list[Command] = [App(), Audit(), Reaper(), Repair(), Debug(), Deploy(), Show(), Undeploy()]
|
|
62
94
|
ic = [c.command() for c in intermediate_cmds]
|
|
63
95
|
# 1. dedup commands
|
|
64
96
|
deduped = []
|
|
@@ -75,24 +107,33 @@ class ReplCommands:
|
|
|
75
107
|
return deduped
|
|
76
108
|
|
|
77
109
|
def navigation() -> list[Command]:
|
|
78
|
-
return [Ls(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), DeviceAuditLog(),
|
|
79
|
-
|
|
110
|
+
return [Ls(), LsLocal(), PreviewTable(), DeviceApp(), DevicePostgres(), DeviceCass(), DeviceAuditLog(), DeviceExport(),
|
|
111
|
+
Cd(), Cat(), CatLocal(), Head(), DownloadFile(), FindLocalFiles(), FindProcesses(), Pwd(), ClipboardCopy(),
|
|
112
|
+
GetParam(), SetParam(), ShowOffloadedCompletes(), ShowParams(), ShowKubectlCommands(), ShowLogin(), ShowAdam(), ShowHost()] + RmLocal().cmd_list()
|
|
80
113
|
|
|
81
114
|
def cassandra_ops() -> list[Command]:
|
|
82
|
-
return [Cqlsh(), ShowCassandraStatus(), ShowCassandraVersion(),
|
|
83
|
-
|
|
115
|
+
return [Cqlsh(), DownloadCassandraLog(), ShowCassandraStatus(), ShowCassandraVersion(), ShowCassandraRepairs(), ShowStorage(), ShowProcesses(),
|
|
116
|
+
Check(), Issues(), NodeTool(), GenerateReport(), AlterTables(), Bash(),
|
|
117
|
+
ExportTables(), ExportXSelect(), ExportUse(), ShowExportDatabases(), ShowColumnCounts(),
|
|
118
|
+
DropExportDatabase(), DropExportDatabases(),
|
|
119
|
+
ShowExportSessions(), ShowExportSession(), DownloadExportSession(),
|
|
120
|
+
CleanUpExportSessions(), CleanUpAllExportSessions(), ImportSession(), ImportCSVFiles()] + \
|
|
121
|
+
Medusa().cmd_list() + [RestartNodes(), RestartNode(), RestartCluster(), RollOut(), Watch()] + Reaper().cmd_list() + Repair().cmd_list() + Debug().cmd_list()
|
|
84
122
|
|
|
85
123
|
def postgres_ops() -> list[Command]:
|
|
86
|
-
return [Postgres(), DeployPgAgent(), UndeployPgAgent()]
|
|
124
|
+
return [Postgres(), DeployPgAgent(), UndeployPgAgent(), PostgresPg()]
|
|
87
125
|
|
|
88
126
|
def app_ops() -> list[Command]:
|
|
89
127
|
return [ShowAppActions(), ShowAppId(), ShowAppQueues(), AppPing(), App()]
|
|
90
128
|
|
|
91
129
|
def audit_ops() -> list[Command]:
|
|
92
|
-
return [Audit()] + Audit.cmd_list()
|
|
130
|
+
return [Audit()] + Audit().cmd_list()
|
|
131
|
+
|
|
132
|
+
def export_ops() -> list[Command]:
|
|
133
|
+
return [ExportSelect(), DropExportDatabase(), DropExportDatabases(), ShowColumnCounts()]
|
|
93
134
|
|
|
94
135
|
def tools() -> list[Command]:
|
|
95
|
-
return [
|
|
136
|
+
return [Shell(), CodeStart(), CodeStop(), DeployFrontend(), UndeployFrontend(), DeployPod(), UndeployPod(), Kubectl(), Code()]
|
|
96
137
|
|
|
97
138
|
def exit() -> list[Command]:
|
|
98
139
|
return [Exit()]
|
adam/repl_session.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from prompt_toolkit import PromptSession
|
|
2
2
|
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
3
3
|
|
|
4
|
+
from adam.config import Config
|
|
5
|
+
from adam.utils import ConfigHolder
|
|
6
|
+
|
|
4
7
|
class ReplSession:
|
|
5
8
|
# the singleton pattern
|
|
6
9
|
def __new__(cls, *args, **kwargs):
|
|
@@ -10,4 +13,9 @@ class ReplSession:
|
|
|
10
13
|
|
|
11
14
|
def __init__(self):
|
|
12
15
|
if not hasattr(self, 'prompt_session'):
|
|
13
|
-
self.prompt_session = PromptSession(auto_suggest=AutoSuggestFromHistory())
|
|
16
|
+
self.prompt_session = PromptSession(auto_suggest=AutoSuggestFromHistory())
|
|
17
|
+
ConfigHolder().append_command_history = self.append_history
|
|
18
|
+
|
|
19
|
+
def append_history(self, entry: str):
|
|
20
|
+
if entry and self.prompt_session and Config().get('repl.history.push-cat-remote-log-file', True):
|
|
21
|
+
self.prompt_session.history.append_string(entry)
|