kaqing 2.0.93__py3-none-any.whl → 2.0.115__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/apps.py +2 -2
- adam/batch.py +2 -16
- adam/checks/check_utils.py +4 -4
- adam/checks/compactionstats.py +1 -1
- adam/checks/cpu.py +2 -2
- adam/checks/disk.py +1 -1
- adam/checks/gossip.py +1 -1
- adam/checks/memory.py +3 -3
- adam/checks/status.py +1 -1
- adam/commands/alter_tables.py +3 -14
- adam/commands/app.py +3 -3
- adam/commands/app_ping.py +2 -2
- adam/commands/audit/audit.py +26 -11
- adam/commands/audit/audit_repair_tables.py +39 -4
- adam/commands/audit/audit_run.py +58 -0
- adam/commands/audit/show_last10.py +51 -0
- adam/commands/audit/show_slow10.py +50 -0
- adam/commands/audit/show_top10.py +49 -0
- adam/commands/audit/utils_show_top10.py +59 -0
- adam/commands/bash/bash.py +124 -0
- adam/commands/bash/bash_completer.py +93 -0
- adam/commands/cat.py +55 -0
- adam/commands/cd.py +26 -14
- adam/commands/check.py +6 -0
- adam/commands/cli_commands.py +3 -3
- adam/commands/code.py +60 -0
- adam/commands/command.py +9 -4
- adam/commands/commands_utils.py +4 -5
- adam/commands/cql/cql_completions.py +7 -3
- adam/commands/cql/cql_utils.py +103 -11
- adam/commands/cql/cqlsh.py +10 -5
- adam/commands/deploy/code_utils.py +2 -2
- adam/commands/deploy/deploy.py +7 -1
- adam/commands/deploy/deploy_pg_agent.py +2 -2
- adam/commands/deploy/deploy_pod.py +6 -6
- adam/commands/deploy/deploy_utils.py +2 -2
- adam/commands/deploy/undeploy.py +7 -1
- adam/commands/deploy/undeploy_pg_agent.py +2 -2
- adam/commands/deploy/undeploy_pod.py +4 -4
- adam/commands/devices.py +29 -0
- adam/commands/export/export.py +60 -0
- adam/commands/export/export_on_x.py +76 -0
- adam/commands/export/export_rmdbs.py +65 -0
- adam/commands/export/export_select.py +68 -0
- adam/commands/export/export_use.py +56 -0
- adam/commands/export/utils_export.py +253 -0
- adam/commands/help.py +9 -5
- adam/commands/issues.py +6 -0
- adam/commands/kubectl.py +41 -0
- adam/commands/login.py +6 -3
- adam/commands/logs.py +2 -1
- adam/commands/ls.py +43 -31
- adam/commands/medusa/medusa_backup.py +2 -2
- adam/commands/medusa/medusa_restore.py +2 -2
- adam/commands/medusa/medusa_show_backupjobs.py +3 -2
- adam/commands/medusa/medusa_show_restorejobs.py +2 -2
- adam/commands/nodetool.py +11 -16
- adam/commands/postgres/postgres.py +4 -4
- adam/commands/postgres/{postgres_session.py → postgres_context.py} +29 -30
- adam/commands/postgres/postgres_utils.py +5 -5
- adam/commands/postgres/psql_completions.py +1 -1
- adam/commands/preview_table.py +18 -32
- adam/commands/pwd.py +4 -3
- adam/commands/reaper/reaper.py +3 -0
- adam/commands/reaper/reaper_restart.py +1 -1
- adam/commands/reaper/reaper_session.py +1 -1
- adam/commands/repair/repair.py +3 -3
- adam/commands/repair/repair_log.py +1 -1
- adam/commands/repair/repair_run.py +2 -2
- adam/commands/repair/repair_scan.py +1 -1
- adam/commands/repair/repair_stop.py +1 -1
- adam/commands/report.py +6 -0
- adam/commands/restart.py +2 -2
- adam/commands/rollout.py +1 -1
- adam/commands/show/show.py +3 -1
- adam/commands/show/show_app_actions.py +3 -0
- adam/commands/show/show_app_id.py +1 -1
- adam/commands/show/show_app_queues.py +3 -2
- adam/commands/show/show_cassandra_status.py +3 -3
- adam/commands/show/show_cassandra_version.py +3 -3
- adam/commands/show/show_login.py +3 -0
- adam/commands/show/show_processes.py +1 -1
- adam/commands/show/show_repairs.py +2 -2
- adam/commands/show/show_storage.py +1 -1
- adam/commands/watch.py +1 -1
- adam/config.py +2 -1
- adam/embedded_params.py +1 -1
- adam/pod_exec_result.py +7 -1
- adam/repl.py +125 -99
- adam/repl_commands.py +29 -17
- adam/repl_state.py +229 -49
- adam/sql/sql_completer.py +86 -62
- adam/sql/sql_state_machine.py +563 -0
- adam/sql/term_completer.py +3 -0
- adam/sso/cred_cache.py +1 -1
- adam/sso/idp.py +1 -1
- adam/utils_athena.py +108 -74
- adam/utils_audits.py +104 -0
- adam/utils_export.py +42 -0
- adam/utils_k8s/__init__.py +0 -0
- adam/utils_k8s/app_clusters.py +33 -0
- adam/utils_k8s/app_pods.py +31 -0
- adam/{k8s_utils → utils_k8s}/cassandra_clusters.py +5 -6
- adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +11 -4
- adam/{k8s_utils → utils_k8s}/deployment.py +2 -2
- adam/{k8s_utils → utils_k8s}/pods.py +54 -11
- adam/{k8s_utils → utils_k8s}/statefulsets.py +2 -2
- adam/version.py +1 -1
- {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/METADATA +1 -1
- kaqing-2.0.115.dist-info/RECORD +203 -0
- adam/commands/bash.py +0 -91
- adam/commands/cql/cql_table_completer.py +0 -8
- adam/commands/describe/describe.py +0 -46
- adam/commands/describe/describe_keyspace.py +0 -60
- adam/commands/describe/describe_keyspaces.py +0 -50
- adam/commands/describe/describe_table.py +0 -60
- adam/commands/describe/describe_tables.py +0 -50
- adam/commands/postgres/psql_table_completer.py +0 -11
- adam/sql/state_machine.py +0 -460
- kaqing-2.0.93.dist-info/RECORD +0 -190
- /adam/commands/{describe → bash}/__init__.py +0 -0
- /adam/{k8s_utils → commands/export}/__init__.py +0 -0
- /adam/{k8s_utils → utils_k8s}/config_maps.py +0 -0
- /adam/{k8s_utils → utils_k8s}/custom_resources.py +0 -0
- /adam/{k8s_utils → utils_k8s}/ingresses.py +0 -0
- /adam/{k8s_utils → utils_k8s}/jobs.py +0 -0
- /adam/{k8s_utils → utils_k8s}/kube_context.py +0 -0
- /adam/{k8s_utils → utils_k8s}/secrets.py +0 -0
- /adam/{k8s_utils → utils_k8s}/service_accounts.py +0 -0
- /adam/{k8s_utils → utils_k8s}/services.py +0 -0
- /adam/{k8s_utils → utils_k8s}/volumes.py +0 -0
- {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/WHEEL +0 -0
- {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/entry_points.txt +0 -0
- {kaqing-2.0.93.dist-info → kaqing-2.0.115.dist-info}/top_level.txt +0 -0
|
@@ -3,12 +3,33 @@ import re
|
|
|
3
3
|
import subprocess
|
|
4
4
|
|
|
5
5
|
from adam.config import Config
|
|
6
|
-
from adam.
|
|
7
|
-
from adam.
|
|
8
|
-
from adam.
|
|
6
|
+
from adam.utils_k8s.kube_context import KubeContext
|
|
7
|
+
from adam.utils_k8s.pods import Pods
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
|
|
3
|
-
from adam.commands.postgres.
|
|
3
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
4
4
|
from adam.config import Config
|
|
5
5
|
|
|
6
6
|
TestPG = [False]
|
|
@@ -12,8 +12,8 @@ def pg_database_names(ns: str, pg_path: str):
|
|
|
12
12
|
|
|
13
13
|
Config().wait_log('Inspecting Postgres Databases...')
|
|
14
14
|
|
|
15
|
-
pg =
|
|
16
|
-
return [db['name'] for db in pg.databases() if db['owner'] ==
|
|
15
|
+
pg = PostgresContext.apply(ns, pg_path)
|
|
16
|
+
return [db['name'] for db in pg.databases() if db['owner'] == PostgresContext.default_owner()]
|
|
17
17
|
|
|
18
18
|
@functools.lru_cache()
|
|
19
19
|
def pg_table_names(ns: str, pg_path: str):
|
|
@@ -21,10 +21,10 @@ def pg_table_names(ns: str, pg_path: str):
|
|
|
21
21
|
return ['C3_2_XYZ1']
|
|
22
22
|
|
|
23
23
|
Config().wait_log('Inspecting Postgres Database...')
|
|
24
|
-
return [table['name'] for table in pg_tables(ns, pg_path) if table['schema'] ==
|
|
24
|
+
return [table['name'] for table in pg_tables(ns, pg_path) if table['schema'] == PostgresContext.default_schema()]
|
|
25
25
|
|
|
26
26
|
def pg_tables(ns: str, pg_path: str):
|
|
27
|
-
pg =
|
|
27
|
+
pg = PostgresContext.apply(ns, pg_path)
|
|
28
28
|
if pg.db:
|
|
29
29
|
return pg.tables()
|
|
30
30
|
|
adam/commands/preview_table.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
|
|
3
1
|
from adam.commands.command import Command
|
|
4
|
-
from adam.commands.cql.
|
|
5
|
-
from adam.commands.
|
|
6
|
-
from adam.commands.postgres.postgres_session import PostgresSession
|
|
7
|
-
from adam.commands.postgres.psql_table_completer import PsqlTableNameCompleter
|
|
2
|
+
from adam.commands.cql.cql_utils import cassandra_table_names, run_cql
|
|
3
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
8
4
|
from adam.config import Config
|
|
9
5
|
from adam.repl_state import ReplState, RequiredState
|
|
10
6
|
from adam.utils import lines_to_tabular, log, log2
|
|
7
|
+
from adam.utils_athena import Athena
|
|
8
|
+
from adam.utils_audits import Audits
|
|
11
9
|
|
|
12
10
|
class PreviewTable(Command):
|
|
13
11
|
COMMAND = 'preview'
|
|
@@ -25,28 +23,26 @@ class PreviewTable(Command):
|
|
|
25
23
|
return PreviewTable.COMMAND
|
|
26
24
|
|
|
27
25
|
def required(self):
|
|
28
|
-
return RequiredState.CLUSTER_OR_POD
|
|
26
|
+
return [RequiredState.CLUSTER_OR_POD, RequiredState.PG_DATABASE, ReplState.L]
|
|
29
27
|
|
|
30
28
|
def run(self, cmd: str, state: ReplState):
|
|
31
29
|
if not(args := self.args(cmd)):
|
|
32
30
|
return super().run(cmd, state)
|
|
33
31
|
|
|
34
32
|
state, args = self.apply_state(args, state)
|
|
35
|
-
if
|
|
36
|
-
|
|
37
|
-
return state
|
|
38
|
-
else:
|
|
39
|
-
if not self.validate_state(state):
|
|
40
|
-
return state
|
|
33
|
+
if not self.validate_state(state):
|
|
34
|
+
return state
|
|
41
35
|
|
|
42
36
|
if not args:
|
|
43
37
|
def show_tables():
|
|
44
38
|
if state.device == ReplState.P:
|
|
45
|
-
pg =
|
|
46
|
-
lines = [db["name"] for db in pg.tables() if db["schema"] ==
|
|
39
|
+
pg = PostgresContext.apply(state.namespace, state.pg_path)
|
|
40
|
+
lines = [db["name"] for db in pg.tables() if db["schema"] == PostgresContext.default_schema()]
|
|
47
41
|
log(lines_to_tabular(lines, separator=','))
|
|
42
|
+
elif state.device == ReplState.L:
|
|
43
|
+
log(lines_to_tabular(Athena.table_names(), separator=','))
|
|
48
44
|
else:
|
|
49
|
-
|
|
45
|
+
log(lines_to_tabular(cassandra_table_names(state), separator=','))
|
|
50
46
|
|
|
51
47
|
if state.in_repl:
|
|
52
48
|
log2('Table is required.')
|
|
@@ -65,26 +61,16 @@ class PreviewTable(Command):
|
|
|
65
61
|
|
|
66
62
|
rows = Config().get('preview.rows', 10)
|
|
67
63
|
if state.device == ReplState.P:
|
|
68
|
-
|
|
64
|
+
PostgresContext.apply(state.namespace, state.pg_path).run_sql(f'select * from {table} limit {rows}')
|
|
65
|
+
elif state.device == ReplState.L:
|
|
66
|
+
Athena.run_query(f'select * from {table} limit {rows}')
|
|
69
67
|
else:
|
|
70
|
-
run_cql(state, f'select * from {table} limit {rows}', show_out=True, use_single_quotes=True)
|
|
68
|
+
run_cql(state, f'select * from {table} limit {rows}', show_out=True, use_single_quotes=True, on_any=True)
|
|
71
69
|
|
|
72
70
|
return state
|
|
73
71
|
|
|
74
|
-
def completion(self,
|
|
75
|
-
if state.device == ReplState.P:
|
|
76
|
-
return {PreviewTable.COMMAND: PsqlTableNameCompleter(state.namespace, state.pg_path)}
|
|
77
|
-
elif state.sts:
|
|
78
|
-
return {PreviewTable.COMMAND: CqlTableNameCompleter(table_names(state))}
|
|
79
|
-
|
|
72
|
+
def completion(self, _: ReplState):
|
|
80
73
|
return {}
|
|
81
74
|
|
|
82
75
|
def help(self, _: ReplState):
|
|
83
|
-
return f'{PreviewTable.COMMAND} TABLE\t preview table'
|
|
84
|
-
|
|
85
|
-
@functools.lru_cache()
|
|
86
|
-
def cql_tables(state: ReplState):
|
|
87
|
-
if state.pod:
|
|
88
|
-
return tables(state)
|
|
89
|
-
|
|
90
|
-
return tables(state, on_any=True)
|
|
76
|
+
return f'{PreviewTable.COMMAND} TABLE\t preview table'
|
adam/commands/pwd.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.app_session import AppSession
|
|
2
2
|
from adam.commands.command import Command
|
|
3
|
-
from adam.commands.postgres.
|
|
3
|
+
from adam.commands.postgres.postgres_context import PostgresContext
|
|
4
4
|
from adam.repl_state import ReplState
|
|
5
5
|
from adam.utils import lines_to_tabular, log
|
|
6
6
|
|
|
@@ -29,7 +29,7 @@ class Pwd(Command):
|
|
|
29
29
|
words = []
|
|
30
30
|
|
|
31
31
|
if device == ReplState.P:
|
|
32
|
-
pg =
|
|
32
|
+
pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path)
|
|
33
33
|
|
|
34
34
|
if pg.host:
|
|
35
35
|
words.append(f'host/{pg.host}')
|
|
@@ -40,7 +40,7 @@ class Pwd(Command):
|
|
|
40
40
|
words.append(f'env/{state.app_env}')
|
|
41
41
|
if state.app_app:
|
|
42
42
|
words.append(f'app/{state.app_app}')
|
|
43
|
-
elif device
|
|
43
|
+
elif device in [ReplState.L, ReplState.X]:
|
|
44
44
|
pass
|
|
45
45
|
else:
|
|
46
46
|
if state.sts:
|
|
@@ -62,6 +62,7 @@ class Pwd(Command):
|
|
|
62
62
|
device_line(state, ReplState.C),
|
|
63
63
|
device_line(state, ReplState.L),
|
|
64
64
|
device_line(state, ReplState.P),
|
|
65
|
+
device_line(state, ReplState.X),
|
|
65
66
|
f'',
|
|
66
67
|
f'HOST\t{host}',
|
|
67
68
|
f'NAMESPACE\t{state.namespace if state.namespace else "/"}',
|
adam/commands/reaper/reaper.py
CHANGED
|
@@ -7,7 +7,7 @@ import requests
|
|
|
7
7
|
from typing import List, cast
|
|
8
8
|
|
|
9
9
|
from adam.config import Config
|
|
10
|
-
from adam.
|
|
10
|
+
from adam.utils_k8s.kube_context import KubeContext
|
|
11
11
|
from adam.repl_state import ReplState
|
|
12
12
|
from adam.utils import lines_to_tabular, log2
|
|
13
13
|
|
adam/commands/repair/repair.py
CHANGED
|
@@ -28,6 +28,8 @@ class Repair(Command):
|
|
|
28
28
|
def run(self, cmd: str, state: ReplState):
|
|
29
29
|
if not(args := self.args(cmd)):
|
|
30
30
|
return super().run(cmd, state)
|
|
31
|
+
if not self.validate_state(state):
|
|
32
|
+
return state
|
|
31
33
|
|
|
32
34
|
return super().intermediate_run(cmd, state, args, Repair.cmd_list())
|
|
33
35
|
|
|
@@ -35,9 +37,7 @@ class Repair(Command):
|
|
|
35
37
|
return [RepairRun(), RepairScan(), RepairStop(), RepairLog()]
|
|
36
38
|
|
|
37
39
|
def completion(self, state: ReplState):
|
|
38
|
-
|
|
39
|
-
return super().completion(state)
|
|
40
|
-
return {}
|
|
40
|
+
return super().completion(state)
|
|
41
41
|
|
|
42
42
|
class RepairCommandHelper(click.Command):
|
|
43
43
|
def get_help(self, ctx: click.Context):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
3
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.jobs import Jobs
|
|
3
|
+
from adam.utils_k8s.volumes import Volumes
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
from adam.config import Config
|
|
6
6
|
from adam.commands.reaper.reaper_session import ReaperSession
|
adam/commands/report.py
CHANGED
|
@@ -22,12 +22,18 @@ class Report(Command):
|
|
|
22
22
|
def command(self):
|
|
23
23
|
return Report.COMMAND
|
|
24
24
|
|
|
25
|
+
def required(self):
|
|
26
|
+
return ReplState.NON_L
|
|
27
|
+
|
|
25
28
|
def run(self, cmd: str, state: ReplState):
|
|
26
29
|
if not(args := self.args(cmd)):
|
|
27
30
|
return super().run(cmd, state)
|
|
28
31
|
|
|
29
32
|
output: dict[str, any] = {}
|
|
30
33
|
state, args = self.apply_state(args, state)
|
|
34
|
+
if not self.validate_state(state):
|
|
35
|
+
return state
|
|
36
|
+
|
|
31
37
|
if state.in_repl:
|
|
32
38
|
args, show = Command.extract_options(args, ['-s', '--show'])
|
|
33
39
|
|
adam/commands/restart.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
3
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.pods import Pods
|
|
3
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
from adam.utils import log2
|
|
6
6
|
|
adam/commands/rollout.py
CHANGED
|
@@ -4,7 +4,7 @@ from kubernetes.client.rest import ApiException
|
|
|
4
4
|
|
|
5
5
|
from adam.commands.command import Command
|
|
6
6
|
from adam.commands.watch import Watch
|
|
7
|
-
from adam.
|
|
7
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
8
8
|
from adam.config import Config
|
|
9
9
|
from adam.repl_state import ReplState, RequiredState
|
|
10
10
|
from adam.utils import duration, log2
|
adam/commands/show/show.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
|
+
from adam.commands.audit.show_last10 import ShowLast10
|
|
3
4
|
from adam.commands.command import Command
|
|
4
5
|
from adam.commands.medusa.medusa_show_backupjobs import MedusaShowBackupJobs
|
|
5
6
|
from adam.commands.medusa.medusa_show_restorejobs import MedusaShowRestoreJobs
|
|
@@ -42,7 +43,8 @@ class Show(Command):
|
|
|
42
43
|
def cmd_list():
|
|
43
44
|
return [ShowAppActions(), ShowAppId(), ShowAppQueues(), ShowHost(), ShowLogin(), ShowKubectlCommands(),
|
|
44
45
|
ShowParams(), ShowProcesses(), ShowRepairs(), ShowStorage(), ShowAdam(),
|
|
45
|
-
ShowCassandraStatus(), ShowCassandraVersion(), MedusaShowRestoreJobs(), MedusaShowBackupJobs()
|
|
46
|
+
ShowCassandraStatus(), ShowCassandraVersion(), MedusaShowRestoreJobs(), MedusaShowBackupJobs(),
|
|
47
|
+
ShowLast10()]
|
|
46
48
|
|
|
47
49
|
def completion(self, state: ReplState):
|
|
48
50
|
return super().completion(state)
|
|
@@ -18,14 +18,15 @@ class ShowAppQueues(Command):
|
|
|
18
18
|
return ShowAppQueues.COMMAND
|
|
19
19
|
|
|
20
20
|
def required(self):
|
|
21
|
-
return RequiredState.
|
|
21
|
+
return RequiredState.APP_APP
|
|
22
22
|
|
|
23
23
|
def run(self, cmd: str, state: ReplState):
|
|
24
24
|
if not(args := self.args(cmd)):
|
|
25
25
|
return super().run(cmd, state)
|
|
26
26
|
|
|
27
27
|
state, args = self.apply_state(args, state)
|
|
28
|
-
if not self.validate_state(state, app_required=RequiredState.APP_APP):
|
|
28
|
+
# if not self.validate_state(state, app_required=RequiredState.APP_APP):
|
|
29
|
+
if not self.validate_state(state):
|
|
29
30
|
return state
|
|
30
31
|
|
|
31
32
|
_, forced = Command.extract_options(args, '--force')
|
|
@@ -8,9 +8,9 @@ from adam.columns.columns import Columns
|
|
|
8
8
|
from adam.commands.command import Command
|
|
9
9
|
from adam.commands.issues import Issues
|
|
10
10
|
from adam.config import Config
|
|
11
|
-
from adam.
|
|
12
|
-
from adam.
|
|
13
|
-
from adam.
|
|
11
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
12
|
+
from adam.utils_k8s.secrets import Secrets
|
|
13
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
14
14
|
from adam.repl_state import ReplState, RequiredState
|
|
15
15
|
from adam.utils import lines_to_tabular, log, log2
|
|
16
16
|
from adam.checks.status import parse_nodetool_status
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
3
|
-
from adam.
|
|
4
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.cassandra_clusters import CassandraClusters
|
|
3
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
4
|
+
from adam.utils_k8s.secrets import Secrets
|
|
5
5
|
from adam.repl_state import ReplState, RequiredState
|
|
6
6
|
|
|
7
7
|
class ShowCassandraVersion(Command):
|
adam/commands/show/show_login.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.commands.commands_utils import show_table
|
|
3
3
|
from adam.config import Config
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
5
5
|
from adam.repl_state import ReplState, RequiredState
|
|
6
6
|
|
|
7
7
|
class ShowProcesses(Command):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
3
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.cassandra_clusters import CassandraClusters
|
|
3
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
|
|
6
6
|
class ShowRepairs(Command):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.commands.commands_utils import show_table
|
|
3
3
|
from adam.config import Config
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
5
5
|
from adam.repl_state import ReplState, RequiredState
|
|
6
6
|
|
|
7
7
|
class ShowStorage(Command):
|
adam/commands/watch.py
CHANGED
|
@@ -6,7 +6,7 @@ from typing import List
|
|
|
6
6
|
from adam.commands.command import Command
|
|
7
7
|
from adam.commands.commands_utils import show_pods, show_rollout
|
|
8
8
|
from adam.config import Config
|
|
9
|
-
from adam.
|
|
9
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
10
10
|
from adam.repl_state import ReplState, RequiredState
|
|
11
11
|
from adam.utils import convert_seconds, log2
|
|
12
12
|
|
adam/config.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from typing import TypeVar, cast
|
|
2
3
|
import yaml
|
|
3
4
|
|
|
@@ -38,7 +39,7 @@ class Config:
|
|
|
38
39
|
return get_deep_keys(self.params)
|
|
39
40
|
|
|
40
41
|
def is_debug(self):
|
|
41
|
-
return Config().get('debug', False)
|
|
42
|
+
return os.getenv('QING_DEV', 'false').lower() == 'true' or Config().get('debug', False)
|
|
42
43
|
|
|
43
44
|
def debug(self, s: None):
|
|
44
45
|
if self.is_debug():
|
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': {'region': 'us-west-2', 'catalog': 'AwsDataCatalog', 'database': 'audit', 'tables': 'audit', 'output': 's3://s3.ops--audit/ddl/results'}}, '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'}, 'medusa': {'restore-auto-complete': False}, 'nodetool': {'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,mem', 'header': 'POD_NAME,CPU,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': 'a', 'auto-enter
|
|
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'}}, '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}}, 'export': {'workers': 8, 'temp_dir': '/c3/cassandra/tmp', 'columns': '<keys>'}, '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'}, 'medusa': {'restore-auto-complete': False}, 'nodetool': {'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,mem', 'header': 'POD_NAME,CPU,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': 'a', 'a': {'auto-enter': 'c3/c3/*'}, 'c': {'auto-enter': 'cluster'}, 'history': {'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}, 'debug': False, 'debugs': {'timings': False, 'exit-on-error': False, 'show-parallelism': False}}
|
adam/pod_exec_result.py
CHANGED
|
@@ -32,4 +32,10 @@ class PodExecResult:
|
|
|
32
32
|
except:
|
|
33
33
|
pass
|
|
34
34
|
|
|
35
|
-
return code
|
|
35
|
+
return code
|
|
36
|
+
|
|
37
|
+
def __str__(self):
|
|
38
|
+
return f'{"OK" if self.exit_code() == 0 else self.exit_code()} {self.command}'
|
|
39
|
+
|
|
40
|
+
def __audit_extra__(self):
|
|
41
|
+
return self.log_file if self.log_file else None
|