kaqing 2.0.102__tar.gz → 2.0.104__tar.gz
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.
- {kaqing-2.0.102 → kaqing-2.0.104}/PKG-INFO +1 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/batch.py +0 -14
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/audit/audit.py +4 -8
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/audit/audit_repair_tables.py +13 -35
- kaqing-2.0.104/adam/commands/audit/audit_run.py +49 -0
- kaqing-2.0.104/adam/commands/bash.py +150 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cd.py +8 -8
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/commands_utils.py +1 -2
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cql/cql_completions.py +4 -4
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cql/cql_utils.py +1 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cql/cqlsh.py +1 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/deploy_pg_agent.py +2 -2
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/undeploy_pg_agent.py +2 -2
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/ls.py +12 -12
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/nodetool.py +1 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/postgres/postgres.py +3 -3
- kaqing-2.0.102/adam/commands/postgres/postgres_session.py → kaqing-2.0.104/adam/commands/postgres/postgres_context.py +26 -27
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/postgres/postgres_utils.py +5 -5
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/postgres/psql_completions.py +1 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/preview_table.py +8 -27
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/pwd.py +2 -2
- kaqing-2.0.104/adam/embedded_params.py +2 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/repl.py +3 -3
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/repl_commands.py +3 -6
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/repl_state.py +2 -2
- kaqing-2.0.104/adam/sql/sql_completer.py +93 -0
- kaqing-2.0.104/adam/sql/sql_state_machine.py +518 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sql/term_completer.py +3 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_athena.py +68 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/pods.py +2 -2
- kaqing-2.0.104/adam/version.py +5 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/kaqing.egg-info/PKG-INFO +1 -1
- {kaqing-2.0.102 → kaqing-2.0.104}/kaqing.egg-info/SOURCES.txt +3 -12
- {kaqing-2.0.102 → kaqing-2.0.104}/setup.py +1 -1
- kaqing-2.0.102/adam/commands/audit/audit_table_completer.py +0 -9
- kaqing-2.0.102/adam/commands/bash.py +0 -92
- kaqing-2.0.102/adam/commands/cql/cql_table_completer.py +0 -8
- kaqing-2.0.102/adam/commands/describe/describe.py +0 -61
- kaqing-2.0.102/adam/commands/describe/describe_keyspace.py +0 -58
- kaqing-2.0.102/adam/commands/describe/describe_keyspaces.py +0 -46
- kaqing-2.0.102/adam/commands/describe/describe_schema.py +0 -46
- kaqing-2.0.102/adam/commands/describe/describe_table.py +0 -57
- kaqing-2.0.102/adam/commands/describe/describe_tables.py +0 -46
- kaqing-2.0.102/adam/commands/postgres/psql_table_completer.py +0 -11
- kaqing-2.0.102/adam/embedded_params.py +0 -2
- kaqing-2.0.102/adam/sql/sql_completer.py +0 -102
- kaqing-2.0.102/adam/sql/state_machine.py +0 -576
- kaqing-2.0.102/adam/utils_k8s/__init__.py +0 -0
- kaqing-2.0.102/adam/version.py +0 -5
- {kaqing-2.0.102 → kaqing-2.0.104}/README +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/app_session.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/apps.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/check.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/check_context.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/check_result.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/check_utils.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/compactionstats.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/cpu.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/disk.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/gossip.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/issue.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/memory.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/checks/status.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/cli.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/cli_group.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/column.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/columns.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/compactions.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/cpu.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/dir_data.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/dir_snapshots.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/gossip.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/host_id.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/memory.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/node_address.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/node_load.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/node_owns.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/node_status.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/node_tokens.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/node_utils.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/pod_name.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/volume_cassandra.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/columns/volume_root.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/alter_tables.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/app.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/app_ping.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/audit/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/check.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cli_commands.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/command.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/command_helpers.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cp.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/cql/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/code_start.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/code_stop.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/code_utils.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/deploy.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/deploy_frontend.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/deploy_pod.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/deploy_utils.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/undeploy.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/undeploy_frontend.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/deploy/undeploy_pod.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/devices.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/exit.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/help.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/issues.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/login.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/logs.py +0 -0
- {kaqing-2.0.102/adam/commands/describe → kaqing-2.0.104/adam/commands/medusa}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/medusa/medusa.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/medusa/medusa_backup.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/medusa/medusa_restore.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/medusa/medusa_show_backupjobs.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/medusa/medusa_show_restorejobs.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/nodetool_commands.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/param_get.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/param_set.py +0 -0
- {kaqing-2.0.102/adam/commands/medusa → kaqing-2.0.104/adam/commands/postgres}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/postgres/postgres_ls.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/postgres/postgres_preview.py +0 -0
- {kaqing-2.0.102/adam/commands/postgres → kaqing-2.0.104/adam/commands/reaper}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_forward.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_forward_stop.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_restart.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_run_abort.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_runs.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_runs_abort.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_schedule_activate.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_schedule_start.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_schedule_stop.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_schedules.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_session.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/reaper/reaper_status.py +0 -0
- {kaqing-2.0.102/adam/commands/reaper → kaqing-2.0.104/adam/commands/repair}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/repair/repair.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/repair/repair_log.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/repair/repair_run.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/repair/repair_scan.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/repair/repair_stop.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/report.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/restart.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/rollout.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/shell.py +0 -0
- {kaqing-2.0.102/adam/commands/repair → kaqing-2.0.104/adam/commands/show}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_adam.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_app_actions.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_app_id.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_app_queues.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_cassandra_status.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_cassandra_version.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_commands.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_host.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_login.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_params.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_processes.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_repairs.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/show/show_storage.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/commands/watch.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/config.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/embedded_apps.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/log.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/pod_exec_result.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/repl_session.py +0 -0
- {kaqing-2.0.102/adam/commands/show → kaqing-2.0.104/adam/sql}/__init__.py +0 -0
- {kaqing-2.0.102/adam/sql → kaqing-2.0.104/adam/sso}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/authenticator.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/authn_ad.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/authn_okta.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/cred_cache.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/id_token.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/idp.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/idp_login.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/idp_session.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/sso/sso_config.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils.py +0 -0
- {kaqing-2.0.102/adam/sso → kaqing-2.0.104/adam/utils_k8s}/__init__.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/cassandra_clusters.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/cassandra_nodes.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/config_maps.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/custom_resources.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/deployment.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/ingresses.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/jobs.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/kube_context.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/secrets.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/service_accounts.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/services.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/statefulsets.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_k8s/volumes.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/adam/utils_net.py +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/kaqing.egg-info/dependency_links.txt +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/kaqing.egg-info/entry_points.txt +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/kaqing.egg-info/top_level.txt +0 -0
- {kaqing-2.0.102 → kaqing-2.0.104}/setup.cfg +0 -0
|
@@ -9,7 +9,6 @@ from adam.commands.command_helpers import ClusterCommandHelper, ClusterOrPodComm
|
|
|
9
9
|
from adam.commands.cql.cqlsh import CqlCommandHelper, Cqlsh
|
|
10
10
|
from adam.commands.deploy.deploy import Deploy, DeployCommandHelper
|
|
11
11
|
from adam.commands.deploy.undeploy import Undeploy, UndeployCommandHelper
|
|
12
|
-
from adam.commands.describe.describe import Describe, DescribeCommandHelper
|
|
13
12
|
from adam.commands.issues import Issues
|
|
14
13
|
from adam.commands.login import Login
|
|
15
14
|
from adam.commands.logs import Logs
|
|
@@ -97,19 +96,6 @@ def deploy(kubeconfig: str, config: str, param: list[str], namespace: str, extra
|
|
|
97
96
|
run_command(Deploy(), kubeconfig, config, param, None, namespace, None, extra_args)
|
|
98
97
|
|
|
99
98
|
|
|
100
|
-
@cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=DescribeCommandHelper, help='Describe keyspace(s) or table(s).')
|
|
101
|
-
@click.option('--kubeconfig', '-k', required=False, metavar='path', help='path to kubeconfig file')
|
|
102
|
-
@click.option('--config', default='params.yaml', metavar='path', help='path to kaqing parameters file')
|
|
103
|
-
@click.option('--param', '-v', multiple=True, metavar='<key>=<value>', help='parameter override')
|
|
104
|
-
@click.option('--cluster', '-c', required=False, metavar='statefulset', help='Kubernetes statefulset name')
|
|
105
|
-
@click.option('--namespace', '-n', required=False, metavar='namespace', help='Kubernetes namespace')
|
|
106
|
-
@click.option('--pod', '-p', required=False, metavar='pod', help='Kubernetes pod name')
|
|
107
|
-
@click.option('--all-nodes', '-a', is_flag=True, help='execute on all Cassandra nodes')
|
|
108
|
-
@click.argument('extra_args', nargs=-1, metavar='<cluster|pod>', type=click.UNPROCESSED)
|
|
109
|
-
def describe(kubeconfig: str, config: str, param: list[str], cluster: str, namespace: str, pod: str, all_nodes: bool, extra_args):
|
|
110
|
-
run_command(Describe(), kubeconfig, config, param, cluster, namespace, pod, extra_args + ('&',) if all_nodes else extra_args)
|
|
111
|
-
|
|
112
|
-
|
|
113
99
|
@cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=ClusterOrPodCommandHelper, help="Print Qing's issues.")
|
|
114
100
|
@click.option('--kubeconfig', '-k', required=False, metavar='path', help='path to kubeconfig file')
|
|
115
101
|
@click.option('--config', default='params.yaml', metavar='path', help='path to kaqing parameters file')
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
3
|
from adam.commands.audit.audit_repair_tables import AuditRepairTables
|
|
4
|
+
from adam.commands.audit.audit_run import AuditRun
|
|
4
5
|
from adam.commands.command import Command
|
|
5
6
|
from adam.config import Config
|
|
6
7
|
from adam.repl_state import ReplState
|
|
@@ -54,22 +55,17 @@ class Audit(Command):
|
|
|
54
55
|
audit_column_names()
|
|
55
56
|
audit_column_names(partition_cols_only=True)
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
# return audit_column_names()
|
|
59
|
-
|
|
60
|
-
return super().completion(state) | SqlCompleter.completions(
|
|
58
|
+
return super().completion(state) | SqlCompleter(
|
|
61
59
|
lambda: audit_table_names(),
|
|
62
60
|
columns=lambda table: audit_column_names(),
|
|
63
61
|
partition_columns=lambda table: audit_column_names(partition_cols_only=True),
|
|
64
62
|
variant='athena'
|
|
65
|
-
)
|
|
66
|
-
# | {
|
|
67
|
-
# 'desc': {table: None for table in audit_table_names()}}
|
|
63
|
+
).completions_for_nesting()
|
|
68
64
|
|
|
69
65
|
return {}
|
|
70
66
|
|
|
71
67
|
def cmd_list():
|
|
72
|
-
return [AuditRepairTables()]
|
|
68
|
+
return [AuditRepairTables(), AuditRun()]
|
|
73
69
|
|
|
74
70
|
def help(self, _: ReplState):
|
|
75
71
|
return f'[{Audit.COMMAND}] <sql-statements>\t run SQL queries on Authena audit database'
|
|
@@ -6,7 +6,7 @@ from adam.commands.command import Command
|
|
|
6
6
|
from adam.config import Config
|
|
7
7
|
from adam.repl_state import ReplState
|
|
8
8
|
from adam.utils import log, log2
|
|
9
|
-
from adam.utils_athena import audit_query, run_audit_query
|
|
9
|
+
from adam.utils_athena import AuditMeta, audit_query, get_meta, put_meta, run_audit_query
|
|
10
10
|
|
|
11
11
|
class AuditRepairTables(Command):
|
|
12
12
|
COMMAND = 'audit repair'
|
|
@@ -30,11 +30,12 @@ class AuditRepairTables(Command):
|
|
|
30
30
|
|
|
31
31
|
state, args = self.apply_state(args, state)
|
|
32
32
|
|
|
33
|
-
tables = Config().get('audit.tables', 'audit').split(',')
|
|
33
|
+
tables = Config().get('audit.athena.repair-partition-tables', 'audit').split(',')
|
|
34
34
|
if args:
|
|
35
35
|
tables = args
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
meta = get_meta()
|
|
38
|
+
self.repair(tables, meta)
|
|
38
39
|
|
|
39
40
|
return state
|
|
40
41
|
|
|
@@ -52,43 +53,20 @@ class AuditRepairTables(Command):
|
|
|
52
53
|
def auto_repair(self, hours: int):
|
|
53
54
|
self.auto_repaired = True
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
if
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
except:
|
|
63
|
-
pass
|
|
64
|
-
|
|
65
|
-
if do_repair:
|
|
66
|
-
tables = Config().get('audit.athena.tables', 'audit').split(',')
|
|
67
|
-
self.repair(tables, show_sql=True)
|
|
68
|
-
log2(f'Audit tables have been auto-repaired.')
|
|
69
|
-
|
|
70
|
-
def repair(self, tables: list[str], show_sql = False):
|
|
56
|
+
meta = get_meta()
|
|
57
|
+
if meta.checked_in + hours * 60 * 60 < time.time():
|
|
58
|
+
tables = Config().get('audit.athena.repair-partition-tables', 'audit').split(',')
|
|
59
|
+
self.repair(tables, meta, show_sql=True)
|
|
60
|
+
log2(f'Audit tables have been auto-repaired.')
|
|
61
|
+
|
|
62
|
+
def repair(self, tables: list[str], meta: AuditMeta, show_sql = False):
|
|
71
63
|
with concurrent.futures.ThreadPoolExecutor(max_workers=Config().get('audit.workers', 3)) as executor:
|
|
72
64
|
for table in tables:
|
|
73
65
|
if show_sql:
|
|
74
66
|
log(f'MSCK REPAIR TABLE {table}')
|
|
75
67
|
|
|
76
68
|
executor.submit(run_audit_query, f'MSCK REPAIR TABLE {table}', None,)
|
|
77
|
-
executor.submit(
|
|
69
|
+
executor.submit(put_meta, 'check-in', meta,)
|
|
78
70
|
|
|
79
71
|
def help(self, _: ReplState):
|
|
80
|
-
return f"{AuditRepairTables.COMMAND} \t run MSCK REPAIR command for new partition discovery"
|
|
81
|
-
|
|
82
|
-
def check_in(self):
|
|
83
|
-
payload = {
|
|
84
|
-
'action': 'check-in'
|
|
85
|
-
}
|
|
86
|
-
audit_endpoint = Config().get("audit.endpoint", "https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/")
|
|
87
|
-
try:
|
|
88
|
-
response = requests.post(audit_endpoint, json=payload, timeout=Config().get("audit.timeout", 10))
|
|
89
|
-
if response.status_code in [200, 201]:
|
|
90
|
-
Config().debug(response.text)
|
|
91
|
-
else:
|
|
92
|
-
log2(f"Error: {response.status_code} {response.text}")
|
|
93
|
-
except requests.exceptions.Timeout as e:
|
|
94
|
-
log2(f"Timeout occurred: {e}")
|
|
72
|
+
return f"{AuditRepairTables.COMMAND} \t run MSCK REPAIR command for new partition discovery"
|
|
@@ -0,0 +1,49 @@
|
|
|
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 log2
|
|
5
|
+
from adam.utils_athena import AuditMeta, find_new_clusters, get_meta, put_meta, run_audit_query
|
|
6
|
+
|
|
7
|
+
class AuditRun(Command):
|
|
8
|
+
COMMAND = 'audit run'
|
|
9
|
+
|
|
10
|
+
# the singleton pattern
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
if not hasattr(cls, 'instance'): cls.instance = super(AuditRun, cls).__new__(cls)
|
|
13
|
+
|
|
14
|
+
return cls.instance
|
|
15
|
+
|
|
16
|
+
def __init__(self, successor: Command=None):
|
|
17
|
+
super().__init__(successor)
|
|
18
|
+
self.auto_repaired = False
|
|
19
|
+
|
|
20
|
+
def command(self):
|
|
21
|
+
return AuditRun.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
|
+
state, args = self.apply_state(args, state)
|
|
28
|
+
|
|
29
|
+
meta: AuditMeta = get_meta()
|
|
30
|
+
clusters = find_new_clusters(meta.cluster_last_checked)
|
|
31
|
+
if clusters:
|
|
32
|
+
put_meta('add-clusters', meta, clusters=clusters)
|
|
33
|
+
log2(f'Added {len(clusters)} new clusters.')
|
|
34
|
+
tables = Config().get('audit.athena.repair-cluster-tables', 'cluster').split(',')
|
|
35
|
+
for table in tables:
|
|
36
|
+
run_audit_query(f'MSCK REPAIR TABLE {table}')
|
|
37
|
+
else:
|
|
38
|
+
log2(f'No new clusters were found.')
|
|
39
|
+
|
|
40
|
+
return state
|
|
41
|
+
|
|
42
|
+
def completion(self, state: ReplState):
|
|
43
|
+
if state.device == ReplState.L:
|
|
44
|
+
return super().completion(state)
|
|
45
|
+
|
|
46
|
+
return {}
|
|
47
|
+
|
|
48
|
+
def help(self, _: ReplState):
|
|
49
|
+
return f"{AuditRun.COMMAND} \t run"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
from adam.commands.command import Command
|
|
2
|
+
from adam.utils_k8s.cassandra_clusters import CassandraClusters
|
|
3
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
4
|
+
from adam.pod_exec_result import PodExecResult
|
|
5
|
+
from adam.repl_state import BashSession, ReplState, RequiredState
|
|
6
|
+
from adam.utils_repl.automata_completer import AutomataCompleter
|
|
7
|
+
from adam.utils_repl.state_machine import StateMachine
|
|
8
|
+
|
|
9
|
+
class Bash(Command):
|
|
10
|
+
COMMAND = 'bash'
|
|
11
|
+
|
|
12
|
+
# the singleton pattern
|
|
13
|
+
def __new__(cls, *args, **kwargs):
|
|
14
|
+
if not hasattr(cls, 'instance'): cls.instance = super(Bash, cls).__new__(cls)
|
|
15
|
+
|
|
16
|
+
return cls.instance
|
|
17
|
+
|
|
18
|
+
def __init__(self, successor: Command=None):
|
|
19
|
+
super().__init__(successor)
|
|
20
|
+
|
|
21
|
+
def command(self):
|
|
22
|
+
return Bash.COMMAND
|
|
23
|
+
|
|
24
|
+
def required(self):
|
|
25
|
+
return RequiredState.CLUSTER_OR_POD
|
|
26
|
+
|
|
27
|
+
def run(self, cmd: str, s0: ReplState):
|
|
28
|
+
if not(args := self.args(cmd)):
|
|
29
|
+
return super().run(cmd, s0)
|
|
30
|
+
|
|
31
|
+
state, args = self.apply_state(args, s0, args_to_check=2)
|
|
32
|
+
if not self.validate_state(state):
|
|
33
|
+
return state
|
|
34
|
+
|
|
35
|
+
if state.in_repl:
|
|
36
|
+
if s0.sts != state.sts or s0.pod != state.pod:
|
|
37
|
+
r = self.exec_with_dir(state, args)
|
|
38
|
+
else:
|
|
39
|
+
r = self.exec_with_dir(s0, args)
|
|
40
|
+
|
|
41
|
+
if not r:
|
|
42
|
+
state.exit_bash()
|
|
43
|
+
|
|
44
|
+
return 'inconsistent pwd'
|
|
45
|
+
|
|
46
|
+
return r
|
|
47
|
+
else:
|
|
48
|
+
command = ' '.join(args)
|
|
49
|
+
|
|
50
|
+
if state.pod:
|
|
51
|
+
CassandraNodes.exec(state.pod, state.namespace, command, show_out=True)
|
|
52
|
+
elif state.sts:
|
|
53
|
+
CassandraClusters.exec(state.sts, state.namespace, command, action='bash', show_out=True)
|
|
54
|
+
|
|
55
|
+
return state
|
|
56
|
+
|
|
57
|
+
def exec_with_dir(self, state: ReplState, args: list[str]) -> list[PodExecResult]:
|
|
58
|
+
session_just_created = False
|
|
59
|
+
if not args:
|
|
60
|
+
session_just_created = True
|
|
61
|
+
session = BashSession(state.device)
|
|
62
|
+
state.enter_bash(session)
|
|
63
|
+
|
|
64
|
+
if state.bash_session:
|
|
65
|
+
if args != ['pwd']:
|
|
66
|
+
if args:
|
|
67
|
+
args.append('&&')
|
|
68
|
+
args.extend(['pwd', '>', f'/tmp/.qing-{state.bash_session.session_id}'])
|
|
69
|
+
|
|
70
|
+
if not session_just_created:
|
|
71
|
+
if pwd := state.bash_session.pwd(state):
|
|
72
|
+
args = ['cd', pwd, '&&'] + args
|
|
73
|
+
|
|
74
|
+
command = ' '.join(args)
|
|
75
|
+
|
|
76
|
+
rs = []
|
|
77
|
+
|
|
78
|
+
if state.pod:
|
|
79
|
+
rs = [CassandraNodes.exec(state.pod, state.namespace, command,
|
|
80
|
+
show_out=not session_just_created, shell='bash')]
|
|
81
|
+
elif state.sts:
|
|
82
|
+
rs = CassandraClusters.exec(state.sts, state.namespace, command, action='bash',
|
|
83
|
+
show_out=not session_just_created, shell='bash')
|
|
84
|
+
|
|
85
|
+
return rs
|
|
86
|
+
|
|
87
|
+
def completion(self, state: ReplState):
|
|
88
|
+
if state.pod or state.sts:
|
|
89
|
+
return {Bash.COMMAND: AutomataCompleter(BashStateMachine())}
|
|
90
|
+
|
|
91
|
+
return {}
|
|
92
|
+
|
|
93
|
+
def help(self, _: ReplState):
|
|
94
|
+
return f'{Bash.COMMAND} [bash-commands]\t run bash on the Cassandra nodes'
|
|
95
|
+
|
|
96
|
+
BASH_SPEC = [
|
|
97
|
+
# <command> ::= <simple_command> | <pipeline> | <conditional_command>
|
|
98
|
+
# <simple_command> ::= <word> <argument>* <redirection>*
|
|
99
|
+
# <pipeline> ::= <command> '|' <command>
|
|
100
|
+
# <conditional_command> ::= <command> '&&' <command> | <command> '||' <command>
|
|
101
|
+
# <word> ::= <letter> <letter_or_digit>*
|
|
102
|
+
# <argument> ::= <word>
|
|
103
|
+
# <redirection> ::= '>' <filename> | '<' <filename>
|
|
104
|
+
# <filename> ::= <word>
|
|
105
|
+
# <letter> ::= 'a' | 'b' | ... | 'z' | 'A' | 'B' | ... | 'Z'
|
|
106
|
+
# <digit> ::= '0' | '1' | ... | '9'
|
|
107
|
+
# <letter_or_digit> ::= <letter> | <digit>
|
|
108
|
+
|
|
109
|
+
' > word > word',
|
|
110
|
+
'word > word > word ^ |,>,2>,<,&,&&,||',
|
|
111
|
+
'- > pipe > word_pipe',
|
|
112
|
+
'- > _rdr0_ > word_rdr0',
|
|
113
|
+
'- > _rdr1_ > word_rdr1',
|
|
114
|
+
'- > _rdr2_ > word_rdr2',
|
|
115
|
+
'- > & > word_bg ^ |,>,2>,<,&,&&,||',
|
|
116
|
+
'- > &&|_or_ > word',
|
|
117
|
+
'word_a > word > word',
|
|
118
|
+
'word_pipe > word > word',
|
|
119
|
+
'word_rdr0 > word > word_rdr0_f',
|
|
120
|
+
'word_rdr1 > word > word_rdr1_f',
|
|
121
|
+
'word_rdr2 > word > word_rdr2_f',
|
|
122
|
+
'word_rdr1_f > pipe > word_pipe ^ |,2>,<,&,&&,||',
|
|
123
|
+
'- > _rdr2_ > word_rdr2',
|
|
124
|
+
'- > _rdr0_ > word_rdr0',
|
|
125
|
+
'word_rdr2_f > pipe > word_pipe ^ |,<,&,&&,||',
|
|
126
|
+
'- > _rdr0_ > word_rdr0',
|
|
127
|
+
'- > & > word_bg ^ |,>,2>,<,&,&&,||',
|
|
128
|
+
'- > &&|_or_ > word',
|
|
129
|
+
'word_rdr0_f > pipe > word_pipe ^ |,&,&&,||',
|
|
130
|
+
'- > & > word_bg ^ |,>,2>,<,&,&&,||',
|
|
131
|
+
'- > &&|_or_ > word',
|
|
132
|
+
'word_bg > &&|_or_ > ^ &&,||',
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
BASH_KEYWORDS = [
|
|
136
|
+
'&',
|
|
137
|
+
'&&',
|
|
138
|
+
'|',
|
|
139
|
+
'||',
|
|
140
|
+
'>',
|
|
141
|
+
'2>',
|
|
142
|
+
'>>',
|
|
143
|
+
'<'
|
|
144
|
+
]
|
|
145
|
+
class BashStateMachine(StateMachine[str]):
|
|
146
|
+
def spec(self) -> str:
|
|
147
|
+
return BASH_SPEC
|
|
148
|
+
|
|
149
|
+
def keywords(self) -> list[str]:
|
|
150
|
+
return BASH_KEYWORDS
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.commands.postgres.postgres_utils import pg_database_names
|
|
3
|
-
from adam.commands.postgres.
|
|
3
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
4
4
|
from adam.utils_k8s.cassandra_clusters import CassandraClusters
|
|
5
5
|
from adam.utils_k8s.kube_context import KubeContext
|
|
6
6
|
from adam.utils_k8s.statefulsets import StatefulSets
|
|
@@ -36,11 +36,11 @@ class Cd(Command):
|
|
|
36
36
|
if dir == '':
|
|
37
37
|
state.pg_path = None
|
|
38
38
|
else:
|
|
39
|
-
|
|
39
|
+
context: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path, arg=dir)
|
|
40
40
|
# patch up state.namespace from pg cd
|
|
41
|
-
if not state.namespace and
|
|
42
|
-
state.namespace =
|
|
43
|
-
state.pg_path =
|
|
41
|
+
if not state.namespace and context.namespace:
|
|
42
|
+
state.namespace = context.namespace
|
|
43
|
+
state.pg_path = context.path()
|
|
44
44
|
elif state.device == ReplState.A:
|
|
45
45
|
if dir == '':
|
|
46
46
|
state.app_env = None
|
|
@@ -91,13 +91,13 @@ class Cd(Command):
|
|
|
91
91
|
|
|
92
92
|
def completion(self, state: ReplState):
|
|
93
93
|
if state.device == ReplState.P:
|
|
94
|
-
pg =
|
|
94
|
+
pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path) if state.pg_path else None
|
|
95
95
|
if pg and pg.db:
|
|
96
96
|
return {Cd.COMMAND: {'..': None}}
|
|
97
97
|
elif pg and pg.host:
|
|
98
|
-
return {Cd.COMMAND: {'..': None} | {p: None for p in pg_database_names(state.namespace, pg.
|
|
98
|
+
return {Cd.COMMAND: {'..': None} | {p: None for p in pg_database_names(state.namespace, pg.path())}}
|
|
99
99
|
else:
|
|
100
|
-
return {Cd.COMMAND: {p: None for p in
|
|
100
|
+
return {Cd.COMMAND: {p: None for p in PostgresContext.hosts(state.namespace)}}
|
|
101
101
|
elif state.device == ReplState.A:
|
|
102
102
|
if state.app_app:
|
|
103
103
|
return {Cd.COMMAND: {'..': None}}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from concurrent.futures import ThreadPoolExecutor
|
|
2
|
-
import time
|
|
3
2
|
from kubernetes import client
|
|
4
3
|
from typing import List
|
|
5
4
|
|
|
@@ -10,7 +9,7 @@ from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
|
10
9
|
from adam.utils_k8s.pods import Pods
|
|
11
10
|
from adam.utils_k8s.statefulsets import StatefulSets
|
|
12
11
|
from adam.repl_state import ReplState
|
|
13
|
-
from adam.utils import
|
|
12
|
+
from adam.utils import duration, lines_to_tabular, log, log2
|
|
14
13
|
|
|
15
14
|
def show_pods(pods: List[client.V1Pod], ns: str, show_namespace = True, show_host_id = True):
|
|
16
15
|
if len(pods) == 0:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from adam.commands.cql.cql_utils import
|
|
1
|
+
from adam.commands.cql.cql_utils import cassandra_table_names
|
|
2
2
|
from adam.config import Config
|
|
3
3
|
from adam.repl_state import ReplState
|
|
4
4
|
from adam.sql.sql_completer import SqlCompleter
|
|
@@ -8,8 +8,8 @@ def cql_completions(state: ReplState) -> dict[str, any]:
|
|
|
8
8
|
return {
|
|
9
9
|
'describe': {
|
|
10
10
|
'keyspaces': None,
|
|
11
|
-
'table': {t: None for t in
|
|
11
|
+
'table': {t: None for t in cassandra_table_names(state)},
|
|
12
12
|
'tables': None},
|
|
13
|
-
} | SqlCompleter
|
|
13
|
+
} | SqlCompleter(lambda: cassandra_table_names(state), table_props=lambda: {
|
|
14
14
|
'GC_GRACE_SECONDS': ps
|
|
15
|
-
}, variant='cql')
|
|
15
|
+
}, variant='cql').completions_for_nesting()
|
|
@@ -23,7 +23,7 @@ def keyspaces(state: ReplState, on_any=False):
|
|
|
23
23
|
|
|
24
24
|
return parse_cql_desc_keyspaces(r.stdout if state.pod else r[0].stdout)
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def cassandra_table_names(state: ReplState):
|
|
27
27
|
return [f'{k}.{t}' for k, ts in tables(state, on_any=True).items() for t in ts]
|
|
28
28
|
|
|
29
29
|
@functools.lru_cache()
|
|
@@ -3,7 +3,7 @@ import click
|
|
|
3
3
|
from adam.commands.command import Command
|
|
4
4
|
from adam.commands.command_helpers import ClusterOrPodCommandHelper
|
|
5
5
|
from adam.commands.cql.cql_completions import cql_completions
|
|
6
|
-
from .cql_utils import run_cql,
|
|
6
|
+
from .cql_utils import run_cql, cassandra_table_names
|
|
7
7
|
from adam.repl_state import ReplState, RequiredState
|
|
8
8
|
from adam.utils import log, log2
|
|
9
9
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.commands.postgres.
|
|
2
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
3
3
|
from adam.config import Config
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
|
|
@@ -29,7 +29,7 @@ class DeployPgAgent(Command):
|
|
|
29
29
|
if not self.validate_state(state):
|
|
30
30
|
return state
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
PostgresContext.deploy_pg_agent(Config().get('pg.agent.name', 'ops-pg-agent'), state.namespace)
|
|
33
33
|
|
|
34
34
|
def completion(self, state: ReplState):
|
|
35
35
|
return super().completion(state)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.commands.deploy.deploy_utils import deleting
|
|
3
|
-
from adam.commands.postgres.
|
|
3
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
4
4
|
from adam.config import Config
|
|
5
5
|
from adam.repl_state import ReplState, RequiredState
|
|
6
6
|
|
|
@@ -30,7 +30,7 @@ class UndeployPgAgent(Command):
|
|
|
30
30
|
if not self.validate_state(state):
|
|
31
31
|
return state
|
|
32
32
|
|
|
33
|
-
deleting('pod', lambda:
|
|
33
|
+
deleting('pod', lambda: PostgresContext.undeploy_pg_agent(Config().get('pg.agent.name', 'ops-pg-agent'), state.namespace))
|
|
34
34
|
|
|
35
35
|
return state
|
|
36
36
|
|
|
@@ -4,7 +4,7 @@ from adam.commands.command import Command
|
|
|
4
4
|
from adam.commands.commands_utils import show_pods, show_rollout
|
|
5
5
|
from adam.commands.cql.cqlsh import Cqlsh
|
|
6
6
|
from adam.commands.postgres.postgres_utils import pg_database_names, pg_table_names
|
|
7
|
-
from adam.commands.postgres.
|
|
7
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
8
8
|
from adam.config import Config
|
|
9
9
|
from adam.utils_k8s.custom_resources import CustomResources
|
|
10
10
|
from adam.utils_k8s.ingresses import Ingresses
|
|
@@ -45,7 +45,7 @@ class Ls(Command):
|
|
|
45
45
|
|
|
46
46
|
if state.device == ReplState.P:
|
|
47
47
|
if state.pg_path:
|
|
48
|
-
pg =
|
|
48
|
+
pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path)
|
|
49
49
|
if pg.db:
|
|
50
50
|
self.show_pg_tables(pg)
|
|
51
51
|
else:
|
|
@@ -110,25 +110,25 @@ class Ls(Command):
|
|
|
110
110
|
|
|
111
111
|
def show_pg_hosts(self, state: ReplState):
|
|
112
112
|
if state.namespace:
|
|
113
|
-
def line(pg:
|
|
114
|
-
return f'{pg.
|
|
113
|
+
def line(pg: PostgresContext):
|
|
114
|
+
return f'{pg.path()},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
|
|
115
115
|
|
|
116
|
-
lines = [line(
|
|
116
|
+
lines = [line(PostgresContext.apply(state.namespace, pg)) for pg in PostgresContext.hosts(state.namespace)]
|
|
117
117
|
|
|
118
118
|
log(lines_to_tabular(lines, 'NAME,ENDPOINT,USERNAME,PASSWORD', separator=','))
|
|
119
119
|
else:
|
|
120
|
-
def line(pg:
|
|
121
|
-
return f'{pg.
|
|
120
|
+
def line(pg: PostgresContext):
|
|
121
|
+
return f'{pg.path()},{pg.namespace},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
|
|
122
122
|
|
|
123
|
-
lines = [line(
|
|
123
|
+
lines = [line(PostgresContext.apply(state.namespace, pg)) for pg in PostgresContext.hosts(state.namespace)]
|
|
124
124
|
|
|
125
125
|
log(lines_to_tabular(lines, 'NAME,NAMESPACE,ENDPOINT,USERNAME,PASSWORD', separator=','))
|
|
126
126
|
|
|
127
|
-
def show_pg_databases(self, pg:
|
|
128
|
-
log(lines_to_tabular(pg_database_names(pg.namespace, pg.
|
|
127
|
+
def show_pg_databases(self, pg: PostgresContext):
|
|
128
|
+
log(lines_to_tabular(pg_database_names(pg.namespace, pg.path()), 'DATABASE', separator=','))
|
|
129
129
|
|
|
130
|
-
def show_pg_tables(self, pg:
|
|
131
|
-
log(lines_to_tabular(pg_table_names(pg.namespace, pg.
|
|
130
|
+
def show_pg_tables(self, pg: PostgresContext):
|
|
131
|
+
log(lines_to_tabular(pg_table_names(pg.namespace, pg.path()), 'NAME', separator=','))
|
|
132
132
|
|
|
133
133
|
def show_audit_log_tables(self):
|
|
134
134
|
log(lines_to_tabular(audit_table_names(), 'NAME', separator=','))
|
|
@@ -47,7 +47,7 @@ class NodeTool(Command):
|
|
|
47
47
|
|
|
48
48
|
def completion(self, state: ReplState):
|
|
49
49
|
if state.pod or state.sts:
|
|
50
|
-
return {NodeTool.COMMAND: {'help': None} | {c: None for c in NODETOOL_COMMANDS}}
|
|
50
|
+
return {NodeTool.COMMAND: {'help': None} | {c: {'&': None} for c in NODETOOL_COMMANDS}}
|
|
51
51
|
|
|
52
52
|
return {}
|
|
53
53
|
|
|
@@ -5,7 +5,7 @@ from adam.commands.postgres.psql_completions import psql_completions
|
|
|
5
5
|
from adam.commands.postgres.postgres_utils import pg_table_names
|
|
6
6
|
from .postgres_ls import PostgresLs
|
|
7
7
|
from .postgres_preview import PostgresPreview
|
|
8
|
-
from .
|
|
8
|
+
from .postgres_context import PostgresContext
|
|
9
9
|
from adam.repl_state import ReplState
|
|
10
10
|
from adam.utils import log, log2
|
|
11
11
|
|
|
@@ -62,7 +62,7 @@ class Postgres(Command):
|
|
|
62
62
|
|
|
63
63
|
return state
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
PostgresContext.apply(state.namespace, state.pg_path).run_sql(' '.join(args))
|
|
66
66
|
|
|
67
67
|
def completion(self, state: ReplState):
|
|
68
68
|
if state.device != state.P:
|
|
@@ -70,7 +70,7 @@ class Postgres(Command):
|
|
|
70
70
|
return {}
|
|
71
71
|
|
|
72
72
|
leaf = {}
|
|
73
|
-
session =
|
|
73
|
+
session = PostgresContext.apply(state.namespace, state.pg_path)
|
|
74
74
|
if session.db:
|
|
75
75
|
if pg_table_names(state.namespace, state.pg_path):
|
|
76
76
|
leaf = psql_completions(state.namespace, state.pg_path)
|
|
@@ -8,7 +8,28 @@ from adam.utils_k8s.pods import Pods
|
|
|
8
8
|
from adam.utils_k8s.secrets import Secrets
|
|
9
9
|
from adam.utils import log2
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class PostgresContext:
|
|
12
|
+
def apply(namespace: str, path: str, arg: str = None) -> 'PostgresContext':
|
|
13
|
+
context = PostgresContext(namespace, path)
|
|
14
|
+
|
|
15
|
+
if arg:
|
|
16
|
+
if arg == '..':
|
|
17
|
+
if context.db:
|
|
18
|
+
context.db = None
|
|
19
|
+
else:
|
|
20
|
+
context.host = None
|
|
21
|
+
else:
|
|
22
|
+
tks = arg.split('@')
|
|
23
|
+
if not context.host:
|
|
24
|
+
context.host = tks[0]
|
|
25
|
+
else:
|
|
26
|
+
context.db = tks[0]
|
|
27
|
+
|
|
28
|
+
if not namespace and tks[1]:
|
|
29
|
+
context.namespace = tks[1]
|
|
30
|
+
|
|
31
|
+
return context
|
|
32
|
+
|
|
12
33
|
def __init__(self, ns: str, path: str):
|
|
13
34
|
self.namespace = ns
|
|
14
35
|
self.conn_details = None
|
|
@@ -25,29 +46,7 @@ class PostgresSession:
|
|
|
25
46
|
if len(tks) > 1:
|
|
26
47
|
self.db = tks[1]
|
|
27
48
|
|
|
28
|
-
def
|
|
29
|
-
if arg:
|
|
30
|
-
tks = arg.split('@')
|
|
31
|
-
if len(tks) > 1:
|
|
32
|
-
return tks[1]
|
|
33
|
-
|
|
34
|
-
return None
|
|
35
|
-
|
|
36
|
-
def directory(self, arg: str = None):
|
|
37
|
-
if arg:
|
|
38
|
-
if arg == '..':
|
|
39
|
-
if self.db:
|
|
40
|
-
self.db = None
|
|
41
|
-
else:
|
|
42
|
-
self.host = None
|
|
43
|
-
else:
|
|
44
|
-
tks = arg.split('@')
|
|
45
|
-
arg = tks[0]
|
|
46
|
-
if not self.host:
|
|
47
|
-
self.host = arg
|
|
48
|
-
else:
|
|
49
|
-
self.db = arg
|
|
50
|
-
|
|
49
|
+
def path(self):
|
|
51
50
|
if not self.host:
|
|
52
51
|
return None
|
|
53
52
|
|
|
@@ -58,7 +57,7 @@ class PostgresSession:
|
|
|
58
57
|
return f'{self.host}/{self.db}'
|
|
59
58
|
|
|
60
59
|
def hosts(ns: str):
|
|
61
|
-
return
|
|
60
|
+
return PostgresContext.hosts_for_namespace(ns)
|
|
62
61
|
|
|
63
62
|
@functools.lru_cache()
|
|
64
63
|
def hosts_for_namespace(ns: str):
|
|
@@ -133,7 +132,7 @@ class PostgresSession:
|
|
|
133
132
|
return dbs
|
|
134
133
|
|
|
135
134
|
def run_sql(self, sql: str, show_out = True):
|
|
136
|
-
db = self.db if self.db else
|
|
135
|
+
db = self.db if self.db else PostgresContext.default_db()
|
|
137
136
|
|
|
138
137
|
if KubeContext.in_cluster():
|
|
139
138
|
cmd1 = f'env PGPASSWORD={self.password()} psql -h {self.endpoint()} -p {self.port()} -U {self.username()} {db} --pset pager=off -c'
|
|
@@ -151,7 +150,7 @@ class PostgresSession:
|
|
|
151
150
|
pod_name = Config().get('pg.agent.name', 'ops-pg-agent')
|
|
152
151
|
|
|
153
152
|
if Config().get('pg.agent.just-in-time', False):
|
|
154
|
-
if not
|
|
153
|
+
if not PostgresContext.deploy_pg_agent(pod_name, ns):
|
|
155
154
|
return
|
|
156
155
|
|
|
157
156
|
real_pod_name = pod_name
|