kaqing 2.0.114__tar.gz → 2.0.177__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.114 → kaqing-2.0.177}/PKG-INFO +1 -1
- kaqing-2.0.177/adam/__init__.py +1 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/app_session.py +9 -12
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/apps.py +18 -4
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/batch.py +4 -4
- kaqing-2.0.177/adam/checks/check_utils.py +65 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/cpu.py +7 -1
- kaqing-2.0.177/adam/checks/cpu_metrics.py +52 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/disk.py +2 -3
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/columns.py +3 -1
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/cpu.py +3 -1
- kaqing-2.0.177/adam/columns/cpu_metrics.py +22 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/memory.py +3 -4
- kaqing-2.0.177/adam/commands/__init__.py +22 -0
- kaqing-2.0.177/adam/commands/alter_tables.py +66 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/audit/audit.py +22 -27
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/audit/audit_repair_tables.py +13 -18
- kaqing-2.0.177/adam/commands/audit/audit_run.py +50 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/audit/show_last10.py +4 -18
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/audit/show_slow10.py +4 -18
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/audit/show_top10.py +4 -17
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/audit/utils_show_top10.py +15 -3
- kaqing-2.0.177/adam/commands/bash/__init__.py +5 -0
- kaqing-2.0.177/adam/commands/bash/bash.py +36 -0
- kaqing-2.0.177/adam/commands/bash/utils_bash.py +16 -0
- kaqing-2.0.177/adam/commands/cat.py +40 -0
- kaqing-2.0.177/adam/commands/cd.py +41 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/check.py +15 -24
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/cli_commands.py +2 -3
- kaqing-2.0.177/adam/commands/clipboard_copy.py +86 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/code.py +21 -24
- kaqing-2.0.177/adam/commands/command.py +265 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/commands_utils.py +12 -27
- kaqing-2.0.177/adam/commands/cql/cql_completions.py +32 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/cql/cqlsh.py +10 -30
- kaqing-2.0.177/adam/commands/cql/utils_cql.py +341 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/code_start.py +7 -10
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/code_stop.py +4 -21
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/code_utils.py +3 -3
- kaqing-2.0.177/adam/commands/deploy/deploy.py +25 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/deploy_frontend.py +14 -17
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/deploy_pg_agent.py +2 -5
- kaqing-2.0.177/adam/commands/deploy/deploy_pod.py +106 -0
- kaqing-2.0.177/adam/commands/deploy/deploy_utils.py +29 -0
- kaqing-2.0.177/adam/commands/deploy/undeploy.py +25 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/undeploy_frontend.py +4 -7
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/undeploy_pg_agent.py +5 -7
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/deploy/undeploy_pod.py +11 -12
- kaqing-2.0.177/adam/commands/devices/device.py +118 -0
- kaqing-2.0.177/adam/commands/devices/device_app.py +171 -0
- kaqing-2.0.177/adam/commands/devices/device_auit_log.py +49 -0
- kaqing-2.0.177/adam/commands/devices/device_cass.py +185 -0
- kaqing-2.0.177/adam/commands/devices/device_export.py +84 -0
- kaqing-2.0.177/adam/commands/devices/device_postgres.py +142 -0
- kaqing-2.0.177/adam/commands/devices/devices.py +25 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/exit.py +1 -4
- kaqing-2.0.177/adam/commands/export/clean_up_all_export_sessions.py +37 -0
- kaqing-2.0.177/adam/commands/export/clean_up_export_sessions.py +44 -0
- kaqing-2.0.177/adam/commands/export/drop_export_database.py +39 -0
- kaqing-2.0.177/adam/commands/export/drop_export_databases.py +37 -0
- kaqing-2.0.177/adam/commands/export/export.py +53 -0
- kaqing-2.0.177/adam/commands/export/export_databases.py +239 -0
- kaqing-2.0.177/adam/commands/export/export_select.py +76 -0
- kaqing-2.0.177/adam/commands/export/export_select_x.py +54 -0
- kaqing-2.0.177/adam/commands/export/export_sessions.py +124 -0
- kaqing-2.0.177/adam/commands/export/export_use.py +48 -0
- kaqing-2.0.177/adam/commands/export/exporter.py +294 -0
- kaqing-2.0.177/adam/commands/export/import_session.py +40 -0
- kaqing-2.0.177/adam/commands/export/importer.py +74 -0
- kaqing-2.0.177/adam/commands/export/importer_athena.py +81 -0
- kaqing-2.0.177/adam/commands/export/importer_sqlite.py +42 -0
- kaqing-2.0.177/adam/commands/export/show_column_counts.py +46 -0
- kaqing-2.0.177/adam/commands/export/show_export_databases.py +37 -0
- kaqing-2.0.177/adam/commands/export/show_export_session.py +40 -0
- kaqing-2.0.177/adam/commands/export/show_export_sessions.py +43 -0
- kaqing-2.0.177/adam/commands/export/utils_export.py +316 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/help.py +3 -3
- kaqing-2.0.177/adam/commands/intermediate_command.py +49 -0
- kaqing-2.0.177/adam/commands/issues.py +43 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/kubectl.py +3 -6
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/login.py +22 -24
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/logs.py +3 -6
- kaqing-2.0.177/adam/commands/ls.py +41 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/medusa/medusa.py +4 -22
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/medusa/medusa_backup.py +20 -27
- kaqing-2.0.177/adam/commands/medusa/medusa_restore.py +86 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/medusa/medusa_show_backupjobs.py +16 -18
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/medusa/medusa_show_restorejobs.py +13 -18
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/nodetool.py +6 -15
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/param_get.py +11 -14
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/param_set.py +8 -12
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/postgres/postgres.py +35 -36
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/postgres/postgres_context.py +57 -24
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/postgres/postgres_ls.py +4 -8
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/postgres/postgres_preview.py +5 -9
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/postgres/psql_completions.py +1 -1
- kaqing-2.0.177/adam/commands/postgres/utils_postgres.py +70 -0
- kaqing-2.0.177/adam/commands/preview_table.py +39 -0
- kaqing-2.0.177/adam/commands/pwd.py +45 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/reaper/reaper.py +4 -27
- kaqing-2.0.177/adam/commands/reaper/reaper_forward.py +93 -0
- kaqing-2.0.177/adam/commands/reaper/reaper_forward_session.py +6 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/reaper/reaper_forward_stop.py +10 -16
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/reaper/reaper_restart.py +7 -14
- kaqing-2.0.177/adam/commands/reaper/reaper_run_abort.py +40 -0
- kaqing-2.0.177/adam/commands/reaper/reaper_runs.py +82 -0
- kaqing-2.0.177/adam/commands/reaper/reaper_runs_abort.py +63 -0
- kaqing-2.0.177/adam/commands/reaper/reaper_schedule_activate.py +41 -0
- kaqing-2.0.177/adam/commands/reaper/reaper_schedule_start.py +41 -0
- kaqing-2.0.177/adam/commands/reaper/reaper_schedule_stop.py +41 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/reaper/reaper_schedules.py +4 -14
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/reaper/reaper_status.py +8 -16
- kaqing-2.0.177/adam/commands/reaper/utils_reaper.py +194 -0
- kaqing-2.0.177/adam/commands/repair/repair.py +26 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/repair/repair_log.py +5 -11
- kaqing-2.0.177/adam/commands/repair/repair_run.py +65 -0
- kaqing-2.0.177/adam/commands/repair/repair_scan.py +68 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/repair/repair_stop.py +5 -11
- kaqing-2.0.177/adam/commands/report.py +61 -0
- kaqing-2.0.177/adam/commands/restart.py +60 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/rollout.py +19 -24
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/shell.py +12 -4
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show.py +10 -25
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show_adam.py +3 -3
- kaqing-2.0.177/adam/commands/show/show_cassandra_repairs.py +35 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show_cassandra_status.py +33 -51
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show_cassandra_version.py +5 -18
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show_commands.py +20 -25
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show_host.py +1 -1
- kaqing-2.0.177/adam/commands/show/show_login.py +56 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/show/show_params.py +2 -5
- kaqing-2.0.177/adam/commands/show/show_processes.py +49 -0
- kaqing-2.0.177/adam/commands/show/show_storage.py +42 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/watch.py +26 -29
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/config.py +5 -14
- kaqing-2.0.177/adam/embedded_params.py +2 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/log.py +4 -4
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/pod_exec_result.py +3 -3
- kaqing-2.0.177/adam/repl.py +180 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/repl_commands.py +34 -18
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/repl_state.py +57 -28
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sql/sql_completer.py +44 -28
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sql/sql_state_machine.py +100 -28
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/authn_ad.py +6 -8
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/authn_okta.py +4 -6
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/cred_cache.py +3 -5
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/idp.py +9 -12
- kaqing-2.0.177/adam/utils.py +688 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_athena.py +61 -42
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_audits.py +12 -14
- kaqing-2.0.177/adam/utils_issues.py +32 -0
- kaqing-2.0.177/adam/utils_k8s/app_clusters.py +28 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/app_pods.py +2 -0
- kaqing-2.0.177/adam/utils_k8s/cassandra_clusters.py +36 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/cassandra_nodes.py +2 -2
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/custom_resources.py +16 -17
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/ingresses.py +2 -2
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/jobs.py +7 -11
- kaqing-2.0.177/adam/utils_k8s/k8s.py +87 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/kube_context.py +2 -2
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/pods.py +40 -77
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/secrets.py +4 -4
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/service_accounts.py +5 -4
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/services.py +2 -2
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/statefulsets.py +1 -12
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_net.py +4 -4
- kaqing-2.0.177/adam/utils_repl/automata_completer.py +48 -0
- kaqing-2.0.177/adam/utils_repl/repl_completer.py +46 -0
- kaqing-2.0.177/adam/utils_repl/state_machine.py +173 -0
- kaqing-2.0.177/adam/utils_sqlite.py +137 -0
- kaqing-2.0.177/adam/version.py +5 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/kaqing.egg-info/PKG-INFO +1 -1
- {kaqing-2.0.114 → kaqing-2.0.177}/kaqing.egg-info/SOURCES.txt +41 -14
- {kaqing-2.0.114 → kaqing-2.0.177}/setup.py +1 -1
- kaqing-2.0.114/adam/__init__.py +0 -3
- kaqing-2.0.114/adam/checks/check_utils.py +0 -97
- kaqing-2.0.114/adam/commands/alter_tables.py +0 -81
- kaqing-2.0.114/adam/commands/app.py +0 -67
- kaqing-2.0.114/adam/commands/app_ping.py +0 -44
- kaqing-2.0.114/adam/commands/audit/audit_run.py +0 -58
- kaqing-2.0.114/adam/commands/bash/bash.py +0 -124
- kaqing-2.0.114/adam/commands/cat.py +0 -55
- kaqing-2.0.114/adam/commands/cd.py +0 -131
- kaqing-2.0.114/adam/commands/command.py +0 -139
- kaqing-2.0.114/adam/commands/cp.py +0 -95
- kaqing-2.0.114/adam/commands/cql/cql_completions.py +0 -15
- kaqing-2.0.114/adam/commands/cql/cql_utils.py +0 -204
- kaqing-2.0.114/adam/commands/deploy/deploy.py +0 -48
- kaqing-2.0.114/adam/commands/deploy/deploy_pod.py +0 -114
- kaqing-2.0.114/adam/commands/deploy/deploy_utils.py +0 -39
- kaqing-2.0.114/adam/commands/deploy/undeploy.py +0 -48
- kaqing-2.0.114/adam/commands/devices.py +0 -147
- kaqing-2.0.114/adam/commands/export/export.py +0 -63
- kaqing-2.0.114/adam/commands/export/export_on_x.py +0 -76
- kaqing-2.0.114/adam/commands/export/export_rmdbs.py +0 -65
- kaqing-2.0.114/adam/commands/export/export_select.py +0 -68
- kaqing-2.0.114/adam/commands/export/export_use.py +0 -56
- kaqing-2.0.114/adam/commands/export/utils_export.py +0 -201
- kaqing-2.0.114/adam/commands/issues.py +0 -75
- kaqing-2.0.114/adam/commands/ls.py +0 -158
- kaqing-2.0.114/adam/commands/medusa/medusa_restore.py +0 -85
- kaqing-2.0.114/adam/commands/postgres/postgres_utils.py +0 -31
- kaqing-2.0.114/adam/commands/preview_table.py +0 -76
- kaqing-2.0.114/adam/commands/pwd.py +0 -78
- kaqing-2.0.114/adam/commands/reaper/reaper_forward.py +0 -100
- kaqing-2.0.114/adam/commands/reaper/reaper_run_abort.py +0 -65
- kaqing-2.0.114/adam/commands/reaper/reaper_runs.py +0 -97
- kaqing-2.0.114/adam/commands/reaper/reaper_runs_abort.py +0 -83
- kaqing-2.0.114/adam/commands/reaper/reaper_schedule_activate.py +0 -64
- kaqing-2.0.114/adam/commands/reaper/reaper_schedule_start.py +0 -64
- kaqing-2.0.114/adam/commands/reaper/reaper_schedule_stop.py +0 -64
- kaqing-2.0.114/adam/commands/reaper/reaper_session.py +0 -159
- kaqing-2.0.114/adam/commands/repair/repair.py +0 -44
- kaqing-2.0.114/adam/commands/repair/repair_run.py +0 -72
- kaqing-2.0.114/adam/commands/repair/repair_scan.py +0 -74
- kaqing-2.0.114/adam/commands/report.py +0 -63
- kaqing-2.0.114/adam/commands/restart.py +0 -61
- kaqing-2.0.114/adam/commands/show/show_app_actions.py +0 -56
- kaqing-2.0.114/adam/commands/show/show_app_id.py +0 -47
- kaqing-2.0.114/adam/commands/show/show_app_queues.py +0 -45
- kaqing-2.0.114/adam/commands/show/show_login.py +0 -63
- kaqing-2.0.114/adam/commands/show/show_processes.py +0 -53
- kaqing-2.0.114/adam/commands/show/show_repairs.py +0 -47
- kaqing-2.0.114/adam/commands/show/show_storage.py +0 -52
- kaqing-2.0.114/adam/embedded_params.py +0 -2
- kaqing-2.0.114/adam/repl.py +0 -242
- kaqing-2.0.114/adam/utils.py +0 -243
- kaqing-2.0.114/adam/utils_export.py +0 -42
- kaqing-2.0.114/adam/utils_k8s/app_clusters.py +0 -33
- kaqing-2.0.114/adam/utils_k8s/cassandra_clusters.py +0 -33
- kaqing-2.0.114/adam/version.py +0 -5
- {kaqing-2.0.114 → kaqing-2.0.177}/README +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/check.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/check_context.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/check_result.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/compactionstats.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/gossip.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/issue.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/memory.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/checks/status.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/cli.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/cli_group.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/column.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/compactions.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/dir_data.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/dir_snapshots.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/gossip.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/host_id.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/node_address.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/node_load.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/node_owns.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/node_status.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/node_tokens.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/node_utils.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/pod_name.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/volume_cassandra.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/columns/volume_root.py +0 -0
- {kaqing-2.0.114/adam/commands → kaqing-2.0.177/adam/commands/audit}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/bash/bash_completer.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/command_helpers.py +0 -0
- {kaqing-2.0.114/adam/commands/audit → kaqing-2.0.177/adam/commands/cql}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/bash → kaqing-2.0.177/adam/commands/deploy}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/cql → kaqing-2.0.177/adam/commands/devices}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/deploy → kaqing-2.0.177/adam/commands/export}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/export → kaqing-2.0.177/adam/commands/medusa}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/commands/nodetool_commands.py +0 -0
- {kaqing-2.0.114/adam/commands/medusa → kaqing-2.0.177/adam/commands/postgres}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/postgres → kaqing-2.0.177/adam/commands/reaper}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/reaper → kaqing-2.0.177/adam/commands/repair}/__init__.py +0 -0
- {kaqing-2.0.114/adam/commands/repair → kaqing-2.0.177/adam/commands/show}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/embedded_apps.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/repl_session.py +0 -0
- {kaqing-2.0.114/adam/commands/show → kaqing-2.0.177/adam/sql}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sql/term_completer.py +0 -0
- {kaqing-2.0.114/adam/sql → kaqing-2.0.177/adam/sso}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/authenticator.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/id_token.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/idp_login.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/idp_session.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/sso/sso_config.py +0 -0
- {kaqing-2.0.114/adam/sso → kaqing-2.0.177/adam/utils_k8s}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/config_maps.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/deployment.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/adam/utils_k8s/volumes.py +0 -0
- {kaqing-2.0.114/adam/utils_k8s → kaqing-2.0.177/adam/utils_repl}/__init__.py +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/kaqing.egg-info/dependency_links.txt +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/kaqing.egg-info/entry_points.txt +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/kaqing.egg-info/top_level.txt +0 -0
- {kaqing-2.0.114 → kaqing-2.0.177}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .version import __version__, __release__
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import threading
|
|
3
3
|
import time
|
|
4
|
-
import traceback
|
|
5
4
|
import requests
|
|
6
5
|
from urllib.parse import urlparse
|
|
7
6
|
|
|
@@ -9,7 +8,7 @@ from adam.log import Log
|
|
|
9
8
|
from adam.sso.idp import Idp
|
|
10
9
|
from adam.sso.idp_login import IdpLogin
|
|
11
10
|
from adam.config import Config
|
|
12
|
-
from adam.utils import json_to_csv,
|
|
11
|
+
from adam.utils import debug, debug_trace, json_to_csv, tabulize, log, log2, log_exc
|
|
13
12
|
from adam.apps import Apps
|
|
14
13
|
|
|
15
14
|
class AppLogin:
|
|
@@ -62,11 +61,9 @@ class AppSession:
|
|
|
62
61
|
if r.status_code >= 200 and r.status_code < 300 or r.status_code == 400:
|
|
63
62
|
try:
|
|
64
63
|
js = r.json()
|
|
65
|
-
|
|
64
|
+
with log_exc(js):
|
|
66
65
|
header, lines = json_to_csv(js, delimiter='\t')
|
|
67
|
-
|
|
68
|
-
except:
|
|
69
|
-
log(js)
|
|
66
|
+
tabulize(lines, header=header, separator='\t')
|
|
70
67
|
except:
|
|
71
68
|
if urlparse(r.url).hostname != urlparse(uri).hostname and not retried:
|
|
72
69
|
app_login = app_session.login(idp_uri=app_login.idp_uri, forced=forced, use_token_from_env=False, use_cached_creds=False)
|
|
@@ -76,7 +73,7 @@ class AppSession:
|
|
|
76
73
|
|
|
77
74
|
if r.text:
|
|
78
75
|
log2(f'{r.status_code} {r.url} Failed parsing the results.')
|
|
79
|
-
|
|
76
|
+
debug(r.text)
|
|
80
77
|
else:
|
|
81
78
|
log2(r.status_code)
|
|
82
79
|
log2(r.text)
|
|
@@ -115,7 +112,7 @@ class AppSession:
|
|
|
115
112
|
try:
|
|
116
113
|
# oidc/login may hang
|
|
117
114
|
timeout = Config().get('app.login.timeout', 5)
|
|
118
|
-
|
|
115
|
+
debug(f'-> {idp_login.app_login_url}')
|
|
119
116
|
session.post(idp_login.app_login_url, headers=headers, data=form_data, timeout=timeout)
|
|
120
117
|
except Exception:
|
|
121
118
|
pass
|
|
@@ -133,7 +130,7 @@ class AppSession:
|
|
|
133
130
|
check_uri = Config().get('app.login.session-check-url', 'https://{host}/{env}/{app}/api/8/C3/userSessionToken')
|
|
134
131
|
check_uri = check_uri.replace('{host}', self.host).replace('{env}', self.env).replace('{app}', 'c3')
|
|
135
132
|
r = session.get(check_uri)
|
|
136
|
-
|
|
133
|
+
debug(f'{r.status_code} {check_uri}')
|
|
137
134
|
|
|
138
135
|
res_text = r.text
|
|
139
136
|
js = json.loads(res_text)
|
|
@@ -142,10 +139,10 @@ class AppSession:
|
|
|
142
139
|
break
|
|
143
140
|
|
|
144
141
|
app_access_token = js['signedToken']
|
|
145
|
-
|
|
142
|
+
debug(f'{r.text}')
|
|
146
143
|
|
|
147
144
|
self.app_login = AppLogin(session, app_access_token, idp_uri)
|
|
148
|
-
except Exception:
|
|
145
|
+
except Exception as e:
|
|
149
146
|
try:
|
|
150
147
|
need = urlparse(r.url).hostname
|
|
151
148
|
if idp_login.idp_uri:
|
|
@@ -158,7 +155,7 @@ class AppSession:
|
|
|
158
155
|
log2(f"Invalid username/password.")
|
|
159
156
|
break
|
|
160
157
|
finally:
|
|
161
|
-
|
|
158
|
+
debug_trace()
|
|
162
159
|
|
|
163
160
|
if 'res_text' in locals():
|
|
164
161
|
Log.log_to_file(res_text)
|
|
@@ -12,7 +12,8 @@ from adam.utils_k8s.services import Services
|
|
|
12
12
|
from adam.utils import copy_config_file
|
|
13
13
|
|
|
14
14
|
class AppAction:
|
|
15
|
-
def __init__(self, name: str, payload: str = None, args: dict[str, str] = None, help: str = None):
|
|
15
|
+
def __init__(self, typ: str, name: str, payload: str = None, args: dict[str, str] = None, help: str = None):
|
|
16
|
+
self.typ = typ
|
|
16
17
|
self.name = name
|
|
17
18
|
self.payload = payload
|
|
18
19
|
self.args = args
|
|
@@ -33,6 +34,19 @@ class AppAction:
|
|
|
33
34
|
|
|
34
35
|
return args
|
|
35
36
|
|
|
37
|
+
def __str__(self):
|
|
38
|
+
line = None
|
|
39
|
+
|
|
40
|
+
args = ','.join(self.arguments())
|
|
41
|
+
if args:
|
|
42
|
+
line = f'{self.typ}.{self.name},{args}'
|
|
43
|
+
else:
|
|
44
|
+
line = f'{self.typ}.{self.name},'
|
|
45
|
+
if self.help:
|
|
46
|
+
line = f'{line},{self.help}'
|
|
47
|
+
|
|
48
|
+
return line
|
|
49
|
+
|
|
36
50
|
class AppType:
|
|
37
51
|
all_types: list['AppType'] = []
|
|
38
52
|
|
|
@@ -62,12 +76,12 @@ class AppType:
|
|
|
62
76
|
aa: AppAction = None
|
|
63
77
|
|
|
64
78
|
if isinstance(v, str):
|
|
65
|
-
aa = AppAction(k, help=v)
|
|
79
|
+
aa = AppAction(typ, k, help=v)
|
|
66
80
|
elif isinstance(v, dict):
|
|
67
81
|
args = {k: v1 for k, v1 in v.items()}
|
|
68
|
-
aa = AppAction(k, payload=v['payload'], args=args, help=v['help'])
|
|
82
|
+
aa = AppAction(typ, k, payload=v['payload'], args=args, help=v['help'])
|
|
69
83
|
else:
|
|
70
|
-
aa = AppAction(k)
|
|
84
|
+
aa = AppAction(typ, k)
|
|
71
85
|
|
|
72
86
|
app_actions.append(aa)
|
|
73
87
|
|
|
@@ -3,7 +3,7 @@ import click
|
|
|
3
3
|
from adam.commands.audit.audit import Audit, AuditCommandHelper
|
|
4
4
|
from adam.commands.bash.bash import Bash
|
|
5
5
|
from adam.commands.check import Check, CheckCommandHelper
|
|
6
|
-
from adam.commands.
|
|
6
|
+
from adam.commands.clipboard_copy import ClipboardCopy, CopyCommandHelper
|
|
7
7
|
from adam.commands.command import Command
|
|
8
8
|
from adam.commands.command_helpers import ClusterCommandHelper, ClusterOrPodCommandHelper, PodCommandHelper
|
|
9
9
|
from adam.commands.cql.cqlsh import CqlCommandHelper, Cqlsh
|
|
@@ -35,7 +35,7 @@ from adam.cli_group import cli
|
|
|
35
35
|
@click.option('--param', '-v', multiple=True, metavar='<key>=<value>', help='parameter override')
|
|
36
36
|
@click.argument('extra_args', nargs=-1, metavar='repair', type=click.UNPROCESSED)
|
|
37
37
|
def audit(kubeconfig: str, config: str, param: list[str], extra_args):
|
|
38
|
-
run_command(Audit(), kubeconfig, config, param, None, None, None, extra_args)
|
|
38
|
+
run_command(Audit(), kubeconfig, config, param, None, None, None, extra_args, device=ReplState.L)
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
@cli.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True), cls=ClusterOrPodCommandHelper, help='Run a single bash command.')
|
|
@@ -281,14 +281,14 @@ def watch(kubeconfig: str, config: str, param: list[str], cluster: str, namespac
|
|
|
281
281
|
run_command(Watch(), kubeconfig, config, param, cluster, namespace, None, extra_args)
|
|
282
282
|
|
|
283
283
|
|
|
284
|
-
def run_command(cmd: Command, kubeconfig: str, config: str, params: list[str], cluster:str, namespace: str, pod: str, extra_args):
|
|
284
|
+
def run_command(cmd: Command, kubeconfig: str, config: str, params: list[str], cluster:str, namespace: str, pod: str, extra_args, device=ReplState.C):
|
|
285
285
|
is_user_entry = False
|
|
286
286
|
|
|
287
287
|
KubeContext.init_config(kubeconfig, is_user_entry=is_user_entry)
|
|
288
288
|
if not KubeContext.init_params(config, params, is_user_entry=is_user_entry):
|
|
289
289
|
return
|
|
290
290
|
|
|
291
|
-
state = ReplState(ns_sts=cluster, pod=pod, namespace=namespace)
|
|
291
|
+
state = ReplState(device=device, ns_sts=cluster, pod=pod, namespace=namespace)
|
|
292
292
|
if cmd.command() == 'pg' and not extra_args:
|
|
293
293
|
state, _ = state.apply_args(extra_args)
|
|
294
294
|
state.device = ReplState.P
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from adam.checks.check import Check
|
|
2
|
+
from adam.checks.check_context import CheckContext
|
|
3
|
+
from adam.checks.check_result import CheckResult
|
|
4
|
+
from adam.checks.compactionstats import CompactionStats
|
|
5
|
+
from adam.checks.cpu import Cpu
|
|
6
|
+
from adam.checks.disk import Disk
|
|
7
|
+
from adam.checks.gossip import Gossip
|
|
8
|
+
from adam.checks.issue import Issue
|
|
9
|
+
from adam.checks.memory import Memory
|
|
10
|
+
from adam.checks.status import Status
|
|
11
|
+
from adam.config import Config
|
|
12
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
13
|
+
from adam.utils_k8s.secrets import Secrets
|
|
14
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
15
|
+
from adam.utils import parallelize, log2
|
|
16
|
+
|
|
17
|
+
def all_checks() -> list[Check]:
|
|
18
|
+
return [CompactionStats(), Cpu(), Gossip(), Memory(), Disk(), Status()]
|
|
19
|
+
|
|
20
|
+
def checks_from_csv(check_str: str):
|
|
21
|
+
checks: list[Check] = []
|
|
22
|
+
|
|
23
|
+
checks_by_name = {c.name(): c for c in all_checks()}
|
|
24
|
+
|
|
25
|
+
if check_str:
|
|
26
|
+
for check_name in check_str.strip(' ').split(','):
|
|
27
|
+
if check_name in checks_by_name:
|
|
28
|
+
checks.append(checks_by_name[check_name])
|
|
29
|
+
else:
|
|
30
|
+
log2(f'Invalid check name: {check_name}.')
|
|
31
|
+
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
return checks
|
|
35
|
+
|
|
36
|
+
def run_checks(cluster: str = None, namespace: str = None, pod: str = None, checks: list[Check] = None, show_out=True):
|
|
37
|
+
if not checks:
|
|
38
|
+
checks = all_checks()
|
|
39
|
+
|
|
40
|
+
sts_ns: list[tuple[str, str]] = StatefulSets.list_sts_name_and_ns()
|
|
41
|
+
|
|
42
|
+
sts_ns_pods: list[tuple[str, str, str]] = []
|
|
43
|
+
for sts, ns in sts_ns:
|
|
44
|
+
if (not cluster or cluster == sts) and (not namespace or namespace == ns):
|
|
45
|
+
pods = StatefulSets.pods(sts, ns)
|
|
46
|
+
for pod_name in [pod.metadata.name for pod in pods]:
|
|
47
|
+
if not pod or pod == pod_name:
|
|
48
|
+
sts_ns_pods.append((sts, ns, pod_name))
|
|
49
|
+
|
|
50
|
+
with parallelize(sts_ns_pods, Config().action_workers('issues', 30), msg='d`Running|Ran checks on {size} pods') as exec:
|
|
51
|
+
return exec.map(lambda sts_ns_pod: run_checks_on_pod(checks, sts_ns_pod[0], sts_ns_pod[1], sts_ns_pod[2], show_out))
|
|
52
|
+
|
|
53
|
+
def run_checks_on_pod(checks: list[Check], cluster: str = None, namespace: str = None, pod: str = None, show_out=True):
|
|
54
|
+
host_id = CassandraNodes.get_host_id(pod, namespace)
|
|
55
|
+
user, pw = Secrets.get_user_pass(pod, namespace)
|
|
56
|
+
results = {}
|
|
57
|
+
issues: list[Issue] = []
|
|
58
|
+
for c in checks:
|
|
59
|
+
check_results = c.check(CheckContext(cluster, host_id, pod, namespace, user, pw, show_output=show_out))
|
|
60
|
+
if check_results.details:
|
|
61
|
+
results = results | {check_results.name: check_results.details}
|
|
62
|
+
if check_results.issues:
|
|
63
|
+
issues.extend(check_results.issues)
|
|
64
|
+
|
|
65
|
+
return CheckResult(None, results, issues)
|
|
@@ -7,6 +7,7 @@ from adam.checks.issue import Issue
|
|
|
7
7
|
from adam.config import Config
|
|
8
8
|
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
9
9
|
from adam.utils_k8s.custom_resources import CustomResources
|
|
10
|
+
from adam.utils_k8s.pods import Pods
|
|
10
11
|
|
|
11
12
|
class Cpu(Check):
|
|
12
13
|
def name(self):
|
|
@@ -20,10 +21,15 @@ class Cpu(Check):
|
|
|
20
21
|
'namespace': ctx.namespace,
|
|
21
22
|
'statefulset': ctx.statefulset,
|
|
22
23
|
'cpu': 'Unknown',
|
|
23
|
-
'idle': 'Unknown'
|
|
24
|
+
'idle': 'Unknown',
|
|
25
|
+
'limit': 'NA'
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
try:
|
|
29
|
+
container = Pods.get_container(ctx.namespace, ctx.pod, container_name='cassandra')
|
|
30
|
+
if container.resources.limits and "cpu" in container.resources.limits:
|
|
31
|
+
details['limit'] = container.resources.limits["cpu"]
|
|
32
|
+
|
|
27
33
|
idle = 'Unknown'
|
|
28
34
|
result = CassandraNodes.exec(ctx.pod, ctx.namespace, "mpstat 5 2 | grep Average | awk '{print $NF}'", show_out=ctx.show_output)
|
|
29
35
|
lines = result.stdout.strip(' \r\n').split('\n')
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from kubernetes.utils import parse_quantity
|
|
2
|
+
|
|
3
|
+
from adam.checks.check import Check
|
|
4
|
+
from adam.checks.check_context import CheckContext
|
|
5
|
+
from adam.checks.check_result import CheckResult
|
|
6
|
+
from adam.checks.issue import Issue
|
|
7
|
+
from adam.config import Config
|
|
8
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
9
|
+
from adam.utils_k8s.pods import Pods
|
|
10
|
+
|
|
11
|
+
class CpuMetrics(Check):
|
|
12
|
+
def name(self):
|
|
13
|
+
return 'cpu-metrics'
|
|
14
|
+
|
|
15
|
+
def check(self, ctx: CheckContext) -> CheckResult:
|
|
16
|
+
issues: list[Issue] = []
|
|
17
|
+
|
|
18
|
+
details = {
|
|
19
|
+
'name': ctx.pod,
|
|
20
|
+
'namespace': ctx.namespace,
|
|
21
|
+
'statefulset': ctx.statefulset,
|
|
22
|
+
'cpu': 'Unknown',
|
|
23
|
+
'limit': 'NA'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
container = Pods.get_container(ctx.namespace, ctx.pod, container_name='cassandra')
|
|
28
|
+
if container.resources.limits and "cpu" in container.resources.limits:
|
|
29
|
+
details['limit'] = container.resources.limits["cpu"]
|
|
30
|
+
|
|
31
|
+
metrics = CustomResources.get_metrics(ctx.namespace, ctx.pod, container_name='cassandra')
|
|
32
|
+
usage = 'Unknown'
|
|
33
|
+
if metrics:
|
|
34
|
+
usage = details['cpu'] = metrics["usage"]["cpu"]
|
|
35
|
+
|
|
36
|
+
cpu_threshold = Config().get('checks.cpu-threshold', 0.0)
|
|
37
|
+
if cpu_threshold != 0.0 and usage != "Unknown" and parse_quantity(usage) > cpu_threshold:
|
|
38
|
+
issues.append(Issue(
|
|
39
|
+
statefulset=ctx.statefulset,
|
|
40
|
+
namespace=ctx.namespace,
|
|
41
|
+
pod=ctx.pod,
|
|
42
|
+
category='cpu',
|
|
43
|
+
desc=f'CPU is too busy: {usage}',
|
|
44
|
+
suggestion=f"qing restart {ctx.pod}@{ctx.namespace}"
|
|
45
|
+
))
|
|
46
|
+
except Exception as e:
|
|
47
|
+
issues.append(self.issue_from_err(sts_name=ctx.statefulset, ns=ctx.namespace, pod_name=ctx.pod, exception=e))
|
|
48
|
+
|
|
49
|
+
return CheckResult(self.name(), details, issues)
|
|
50
|
+
|
|
51
|
+
def help(self):
|
|
52
|
+
return f'{CpuMetrics().name()}: check cpu busy percentage with metrics'
|
|
@@ -6,6 +6,7 @@ from adam.checks.check_context import CheckContext
|
|
|
6
6
|
from adam.checks.check_result import CheckResult
|
|
7
7
|
from adam.checks.issue import Issue
|
|
8
8
|
from adam.config import Config
|
|
9
|
+
from adam.utils import log_exc
|
|
9
10
|
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
10
11
|
|
|
11
12
|
class Disk(Check):
|
|
@@ -87,10 +88,8 @@ class Disk(Check):
|
|
|
87
88
|
|
|
88
89
|
ss_size = 0.0
|
|
89
90
|
if ss_out:
|
|
90
|
-
|
|
91
|
+
with log_exc():
|
|
91
92
|
ss_size = round(float(ss_out.strip(' \r\n')) / 1024 / 1024, 2)
|
|
92
|
-
except:
|
|
93
|
-
pass
|
|
94
93
|
|
|
95
94
|
def parse_du_out(l: str, default: str = None):
|
|
96
95
|
groups = re.match(r'^(\S+)\s+(\S+)$', l.strip('\r'))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from adam.columns.column import Column
|
|
2
2
|
from adam.columns.compactions import Compactions
|
|
3
3
|
from adam.columns.cpu import Cpu
|
|
4
|
+
from adam.columns.cpu_metrics import CpuMetrics
|
|
4
5
|
from adam.columns.dir_data import DataDir
|
|
5
6
|
from adam.columns.dir_snapshots import SnapshotsDir
|
|
6
7
|
from adam.columns.gossip import Gossip
|
|
@@ -23,7 +24,7 @@ class Columns:
|
|
|
23
24
|
COLUMNS_BY_NAME = None
|
|
24
25
|
|
|
25
26
|
def all_columns():
|
|
26
|
-
return [Compactions(), Cpu(), DataDir(), SnapshotsDir(), Gossip(), HostId(), Memory(),
|
|
27
|
+
return [Compactions(), Cpu(), CpuMetrics(), DataDir(), SnapshotsDir(), Gossip(), HostId(), Memory(),
|
|
27
28
|
NodeAddress(), NodeLoad(), NodeOwns(), NodeStatus(),NodeTokens(), PodName(), CassandraVolume(), RootVolume()]
|
|
28
29
|
|
|
29
30
|
def columns_by_name():
|
|
@@ -38,6 +39,7 @@ class Columns:
|
|
|
38
39
|
name = name.strip(' ')
|
|
39
40
|
if not name in Columns.COLUMNS_BY_NAME:
|
|
40
41
|
return None
|
|
42
|
+
|
|
41
43
|
cols.append(Columns.COLUMNS_BY_NAME[name]())
|
|
42
44
|
|
|
43
45
|
return cols
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from kubernetes.utils.quantity import parse_quantity
|
|
2
|
+
|
|
1
3
|
from adam.checks.check_result import CheckResult
|
|
2
4
|
from adam.checks.cpu import Cpu as CpuCheck
|
|
3
5
|
from adam.columns.column import Column
|
|
@@ -14,4 +16,4 @@ class Cpu(Column):
|
|
|
14
16
|
cpu = r.details[CpuCheck().name()]
|
|
15
17
|
busy = 100.0 - float(cpu['idle'])
|
|
16
18
|
|
|
17
|
-
return f'{round(busy)}%'
|
|
19
|
+
return f'{round(busy)}%/{parse_quantity(cpu["limit"]) * 100}%'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from kubernetes.utils.quantity import parse_quantity
|
|
2
|
+
|
|
3
|
+
from adam.checks.check_result import CheckResult
|
|
4
|
+
from adam.checks.cpu_metrics import CpuMetrics as CpuCheck
|
|
5
|
+
from adam.columns.column import Column
|
|
6
|
+
|
|
7
|
+
class CpuMetrics(Column):
|
|
8
|
+
def name(self):
|
|
9
|
+
return 'cpu-metrics'
|
|
10
|
+
|
|
11
|
+
def checks(self):
|
|
12
|
+
return [CpuCheck()]
|
|
13
|
+
|
|
14
|
+
def pod_value(self, check_results: list[CheckResult], pod_name: str):
|
|
15
|
+
r = self.result_by_pod(check_results, pod_name)
|
|
16
|
+
cpu = r.details[CpuCheck().name()]
|
|
17
|
+
|
|
18
|
+
cpu_decimal = parse_quantity(cpu['cpu'])
|
|
19
|
+
cpu_limit = parse_quantity(cpu['limit'])
|
|
20
|
+
business = cpu_decimal * 100 / cpu_limit
|
|
21
|
+
|
|
22
|
+
return f"{business:.2f}%({cpu_decimal}/{cpu_limit})"
|
|
@@ -3,6 +3,7 @@ from kubernetes.utils import parse_quantity
|
|
|
3
3
|
from adam.checks.check_result import CheckResult
|
|
4
4
|
from adam.checks.memory import Memory as MemoryCheck
|
|
5
5
|
from adam.columns.column import Column
|
|
6
|
+
from adam.utils import log_exc
|
|
6
7
|
|
|
7
8
|
class Memory(Column):
|
|
8
9
|
def name(self):
|
|
@@ -18,7 +19,5 @@ class Memory(Column):
|
|
|
18
19
|
return f"{Memory.to_g(mem['used'])}/{Memory.to_g(mem['limit'])}"
|
|
19
20
|
|
|
20
21
|
def to_g(v: str):
|
|
21
|
-
|
|
22
|
-
return f'{round(parse_quantity(v) / 1024 / 1024 / 1024, 2)}G'
|
|
23
|
-
except:
|
|
24
|
-
return v
|
|
22
|
+
with log_exc():
|
|
23
|
+
return f'{round(parse_quantity(v) / 1024 / 1024 / 1024, 2)}G'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from adam.commands.command import ExtractAllOptionsHandler, ExtractOptionsHandler, ExtractSequenceOptionsHandler, ExtractTrailingOptionsHandler, ValidateArgCountHandler
|
|
3
|
+
from adam.repl_state import ReplState
|
|
4
|
+
from adam.commands.app.utils_app import AppHandler
|
|
5
|
+
|
|
6
|
+
def app(state: ReplState) -> AppHandler:
|
|
7
|
+
return AppHandler(state)
|
|
8
|
+
|
|
9
|
+
def extract_options(args: list[str], options: list[str]):
|
|
10
|
+
return ExtractOptionsHandler(args, options = options)
|
|
11
|
+
|
|
12
|
+
def extract_trailing_options(args: list[str], trailing: list[str]):
|
|
13
|
+
return ExtractTrailingOptionsHandler(args, trailing = trailing)
|
|
14
|
+
|
|
15
|
+
def extract_all_options(args: list[str], trailing = None, sequence = None, options = None):
|
|
16
|
+
return ExtractAllOptionsHandler(args, trailing = trailing, sequence = sequence, options = options)
|
|
17
|
+
|
|
18
|
+
def extract_sequence(args: list[str], sequence: list[str]):
|
|
19
|
+
return ExtractSequenceOptionsHandler(args, sequence = sequence)
|
|
20
|
+
|
|
21
|
+
def validate_args(args: list[str], state: ReplState, count_at_least: int = 1, name: str = None, msg: Callable[[], None] = None, default: str = None):
|
|
22
|
+
return ValidateArgCountHandler(args, state, count_at_least=count_at_least, name=name, msg=msg, default=default)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from adam.commands import extract_options, validate_args
|
|
2
|
+
from adam.commands.command import Command
|
|
3
|
+
from adam.commands.cql.utils_cql import cassandra, cassandra_tables as get_tables
|
|
4
|
+
from adam.config import Config
|
|
5
|
+
from adam.repl_state import ReplState, RequiredState
|
|
6
|
+
from adam.utils import log2, log_exc
|
|
7
|
+
|
|
8
|
+
class AlterTables(Command):
|
|
9
|
+
COMMAND = 'alter tables with'
|
|
10
|
+
|
|
11
|
+
# the singleton pattern
|
|
12
|
+
def __new__(cls, *args, **kwargs):
|
|
13
|
+
if not hasattr(cls, 'instance'): cls.instance = super(AlterTables, cls).__new__(cls)
|
|
14
|
+
|
|
15
|
+
return cls.instance
|
|
16
|
+
|
|
17
|
+
def __init__(self, successor: Command=None):
|
|
18
|
+
super().__init__(successor)
|
|
19
|
+
|
|
20
|
+
def required(self):
|
|
21
|
+
return RequiredState.CLUSTER
|
|
22
|
+
|
|
23
|
+
def command(self):
|
|
24
|
+
return AlterTables.COMMAND
|
|
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
|
+
with extract_options(args, '--include-reaper') as (args, include_reaper):
|
|
32
|
+
with validate_args(args, state, name='gc grace in seconds') as arg_str:
|
|
33
|
+
excludes = [e.strip(' \r\n') for e in Config().get(
|
|
34
|
+
'cql.alter-tables.excludes',
|
|
35
|
+
'system_auth,system_traces,reaper_db,system_distributed,system_views,system,system_schema,system_virtual_schema').split(',')]
|
|
36
|
+
batching = Config().get('cql.alter-tables.batching', True)
|
|
37
|
+
tables = get_tables(state, on_any=True)
|
|
38
|
+
for k, v in tables.items():
|
|
39
|
+
if k not in excludes or k == 'reaper_db' and include_reaper:
|
|
40
|
+
if batching:
|
|
41
|
+
# alter table <table_name> with GC_GRACE_SECONDS = <timeout>;
|
|
42
|
+
cql = ';\n'.join([f'alter table {k}.{t} with {arg_str}' for t in v])
|
|
43
|
+
with log_exc(True):
|
|
44
|
+
with cassandra(state) as pods:
|
|
45
|
+
pods.cql(cql, show_out=Config().is_debug(), show_query=not Config().is_debug(), on_any=True)
|
|
46
|
+
continue
|
|
47
|
+
else:
|
|
48
|
+
for t in v:
|
|
49
|
+
with log_exc(True):
|
|
50
|
+
# alter table <table_name> with GC_GRACE_SECONDS = <timeout>;
|
|
51
|
+
cql = f'alter table {k}.{t} with {arg_str}'
|
|
52
|
+
with cassandra(state) as pods:
|
|
53
|
+
pods.cql(show_out=Config().is_debug(), show_query=not Config().is_debug(), on_any=True)
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
log2(f'{len(v)} tables altered in {k}.')
|
|
57
|
+
|
|
58
|
+
# do not continue to cql route
|
|
59
|
+
return state
|
|
60
|
+
|
|
61
|
+
def completion(self, _: ReplState) -> dict[str, any]:
|
|
62
|
+
# auto completion is taken care of by sql completer
|
|
63
|
+
return {}
|
|
64
|
+
|
|
65
|
+
def help(self, _: ReplState) -> str:
|
|
66
|
+
return f'{AlterTables.COMMAND} <param = value> [--include-reaper] \t alter schema on all tables'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
|
+
from adam.commands import validate_args
|
|
3
4
|
from adam.commands.audit.audit_repair_tables import AuditRepairTables
|
|
4
5
|
from adam.commands.audit.audit_run import AuditRun
|
|
5
6
|
from adam.commands.audit.show_last10 import ShowLast10
|
|
@@ -7,14 +8,13 @@ from adam.commands.audit.show_slow10 import ShowSlow10
|
|
|
7
8
|
from adam.commands.audit.show_top10 import ShowTop10
|
|
8
9
|
from adam.commands.audit.utils_show_top10 import show_top10_completions_for_nesting
|
|
9
10
|
from adam.commands.command import Command
|
|
10
|
-
from adam.
|
|
11
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
11
12
|
from adam.repl_state import ReplState
|
|
12
|
-
from adam.sql.sql_completer import SqlCompleter
|
|
13
|
-
from adam.utils import log2
|
|
13
|
+
from adam.sql.sql_completer import SqlCompleter, SqlVariant
|
|
14
|
+
from adam.utils import log2, wait_log
|
|
14
15
|
from adam.utils_athena import Athena
|
|
15
|
-
from adam.utils_audits import Audits
|
|
16
16
|
|
|
17
|
-
class Audit(
|
|
17
|
+
class Audit(IntermediateCommand):
|
|
18
18
|
COMMAND = 'audit'
|
|
19
19
|
|
|
20
20
|
# the singleton pattern
|
|
@@ -37,29 +37,22 @@ class Audit(Command):
|
|
|
37
37
|
if not(args := self.args(cmd)):
|
|
38
38
|
return super().run(cmd, state)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
r = None
|
|
45
|
-
if len(args) > 0:
|
|
46
|
-
r = super().intermediate_run(cmd, state, args, Audit.cmd_list(), display_help=False)
|
|
40
|
+
with self.validate(args, state) as (args, state):
|
|
41
|
+
r = None
|
|
42
|
+
if len(args) > 0:
|
|
43
|
+
r = self.intermediate_run(cmd, state, args, self.cmd_list(), display_help=False)
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
else:
|
|
53
|
-
log2(sql)
|
|
45
|
+
if not r or isinstance(r, str) and r == 'command-missing':
|
|
46
|
+
with validate_args(args, state, default='select * from audit order by ts desc limit 10') as sql:
|
|
47
|
+
log2(sql)
|
|
48
|
+
Athena.run_query(sql)
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return state
|
|
50
|
+
return state
|
|
58
51
|
|
|
59
52
|
def completion(self, state: ReplState):
|
|
60
53
|
if state.device == ReplState.L:
|
|
61
54
|
if not self.schema_read:
|
|
62
|
-
|
|
55
|
+
wait_log(f'Inspecting audit database schema...')
|
|
63
56
|
self.schema_read = True
|
|
64
57
|
# warm up the caches first time when l: drive is accessed
|
|
65
58
|
Athena.table_names()
|
|
@@ -68,14 +61,16 @@ class Audit(Command):
|
|
|
68
61
|
|
|
69
62
|
return super().completion(state) | show_top10_completions_for_nesting() | SqlCompleter(
|
|
70
63
|
lambda: Athena.table_names(),
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
expandables={
|
|
65
|
+
'columns': lambda table: Athena.column_names(),
|
|
66
|
+
'partition_columns': lambda table: Athena.column_names(partition_cols_only=True)
|
|
67
|
+
},
|
|
68
|
+
variant=SqlVariant.ATHENA
|
|
74
69
|
).completions_for_nesting()
|
|
75
70
|
|
|
76
71
|
return {}
|
|
77
72
|
|
|
78
|
-
def cmd_list():
|
|
73
|
+
def cmd_list(self):
|
|
79
74
|
return [AuditRepairTables(), AuditRun(), ShowLast10(), ShowSlow10(), ShowTop10()]
|
|
80
75
|
|
|
81
76
|
def help(self, _: ReplState):
|
|
@@ -83,4 +78,4 @@ class Audit(Command):
|
|
|
83
78
|
|
|
84
79
|
class AuditCommandHelper(click.Command):
|
|
85
80
|
def get_help(self, ctx: click.Context):
|
|
86
|
-
|
|
81
|
+
IntermediateCommand.intermediate_help(super().get_help(ctx), Audit.COMMAND, Audit().cmd_list(), show_cluster_help=False)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import concurrent
|
|
2
1
|
import time
|
|
3
2
|
|
|
3
|
+
from adam.commands import validate_args
|
|
4
4
|
from adam.commands.command import Command
|
|
5
5
|
from adam.config import Config
|
|
6
6
|
from adam.repl_state import ReplState
|
|
@@ -31,25 +31,20 @@ class AuditRepairTables(Command):
|
|
|
31
31
|
if not(args := self.args(cmd)):
|
|
32
32
|
return super().run(cmd, state)
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
tables = Config().get('audit.athena.repair-partition-tables', 'audit').split(',')
|
|
39
|
-
if args:
|
|
40
|
-
tables = args
|
|
34
|
+
with self.validate(args, state) as (args, state):
|
|
35
|
+
with validate_args(args, state, default=Config().get('audit.athena.repair-partition-tables', 'audit').split(',')) as tables:
|
|
36
|
+
meta = Audits.get_meta()
|
|
37
|
+
self.repair(tables, meta)
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
self.repair(tables, meta)
|
|
44
|
-
|
|
45
|
-
return state
|
|
39
|
+
return state
|
|
46
40
|
|
|
47
41
|
def completion(self, state: ReplState):
|
|
42
|
+
# trigger auto repair if on l: drive
|
|
48
43
|
if state.device == ReplState.L:
|
|
49
44
|
if not self.auto_repaired:
|
|
50
45
|
if hours := Config().get('audit.athena.auto-repair.elapsed_hours', 12):
|
|
51
|
-
with
|
|
52
|
-
|
|
46
|
+
with Audits.offload() as exec:
|
|
47
|
+
exec.submit(lambda: self.auto_repair(hours))
|
|
53
48
|
|
|
54
49
|
return super().completion(state)
|
|
55
50
|
|
|
@@ -65,13 +60,13 @@ class AuditRepairTables(Command):
|
|
|
65
60
|
log2(f'Audit tables have been auto-repaired.')
|
|
66
61
|
|
|
67
62
|
def repair(self, tables: list[str], meta: AuditMeta, show_sql = False):
|
|
68
|
-
with
|
|
63
|
+
with Audits.offload() as exec:
|
|
69
64
|
for table in tables:
|
|
70
65
|
if show_sql:
|
|
71
66
|
log(f'MSCK REPAIR TABLE {table}')
|
|
72
67
|
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
exec.submit(Athena.query, f'MSCK REPAIR TABLE {table}', None,)
|
|
69
|
+
exec.submit(Audits.put_meta, Audits.PARTITIONS_ADDED, meta,)
|
|
75
70
|
|
|
76
71
|
def help(self, _: ReplState):
|
|
77
|
-
return f"{AuditRepairTables.COMMAND}
|
|
72
|
+
return f"{AuditRepairTables.COMMAND}\t run MSCK REPAIR command for new partition discovery"
|