kaqing 2.0.52__py3-none-any.whl → 2.0.110__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 +11 -15
- 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 +2 -2
- adam/commands/app_ping.py +2 -2
- adam/commands/audit/audit.py +85 -0
- adam/commands/audit/audit_repair_tables.py +76 -0
- adam/commands/audit/audit_run.py +57 -0
- adam/commands/audit/show_last10.py +50 -0
- adam/commands/audit/show_slow10.py +49 -0
- adam/commands/audit/show_top10.py +48 -0
- adam/commands/audit/utils_show_top10.py +59 -0
- adam/commands/bash.py +76 -13
- adam/commands/cd.py +22 -13
- adam/commands/check.py +6 -0
- adam/commands/cli_commands.py +3 -3
- adam/commands/command.py +15 -11
- adam/commands/commands_utils.py +4 -5
- adam/commands/cql/cql_completions.py +7 -3
- adam/commands/cql/cql_utils.py +13 -10
- adam/commands/cql/cqlsh.py +6 -3
- 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/help.py +10 -7
- adam/commands/issues.py +6 -0
- adam/commands/login.py +6 -3
- adam/commands/logs.py +2 -1
- adam/commands/ls.py +30 -24
- 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 +5 -3
- adam/commands/postgres/postgres.py +3 -3
- 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 +17 -32
- adam/commands/pwd.py +5 -2
- 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 +5 -2
- 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_host.py +33 -0
- 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 -2
- adam/repl.py +141 -88
- adam/repl_commands.py +21 -20
- adam/repl_state.py +167 -39
- adam/sql/sql_completer.py +76 -386
- adam/sql/sql_state_machine.py +518 -0
- adam/sql/term_completer.py +14 -4
- adam/sso/cred_cache.py +1 -1
- adam/sso/idp.py +1 -1
- adam/utils.py +0 -1
- adam/utils_audits.py +193 -0
- adam/{k8s_utils → utils_k8s}/cassandra_clusters.py +6 -8
- 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 +33 -9
- adam/{k8s_utils → utils_k8s}/secrets.py +4 -0
- adam/{k8s_utils → utils_k8s}/statefulsets.py +4 -4
- adam/utils_net.py +24 -0
- adam/version.py +1 -1
- {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/METADATA +1 -1
- kaqing-2.0.110.dist-info/RECORD +187 -0
- 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/sql_utils.py +0 -5
- kaqing-2.0.52.dist-info/RECORD +0 -184
- /adam/commands/{describe → audit}/__init__.py +0 -0
- /adam/{k8s_utils → utils_k8s}/__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}/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.52.dist-info → kaqing-2.0.110.dist-info}/WHEEL +0 -0
- {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/entry_points.txt +0 -0
- {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/top_level.txt +0 -0
adam/commands/help.py
CHANGED
|
@@ -23,20 +23,23 @@ class Help(Command):
|
|
|
23
23
|
return super().run(cmd, state)
|
|
24
24
|
|
|
25
25
|
def section(cmds : list[ReplCommands]):
|
|
26
|
-
|
|
26
|
+
sorted_cmds = sorted(cmds, key=lambda cmd: cmd.command())
|
|
27
|
+
return [f' {c.help(state)}' for c in sorted_cmds if c.help(state)]
|
|
27
28
|
|
|
28
29
|
lines = []
|
|
29
30
|
lines.append('NAVIGATION')
|
|
30
|
-
lines.append(' a: | c: | p:\t switch to another operational device: App, Cassandra or Postgres')
|
|
31
|
+
lines.append(' a: | c: | l: | p:\t switch to another operational device: App, Cassandra, Audit or Postgres')
|
|
31
32
|
lines.extend(section(ReplCommands.navigation()))
|
|
32
|
-
lines.append('
|
|
33
|
-
lines.extend(section(ReplCommands.cassandra_check()))
|
|
34
|
-
lines.append('CASSANDRA OPERATIONS')
|
|
33
|
+
lines.append('CASSANDRA')
|
|
35
34
|
lines.extend(section(ReplCommands.cassandra_ops()))
|
|
35
|
+
lines.append('POSTGRES')
|
|
36
|
+
lines.extend(section(ReplCommands.postgres_ops()))
|
|
37
|
+
lines.append('APP')
|
|
38
|
+
lines.extend(section(ReplCommands.app_ops()))
|
|
39
|
+
lines.append('AUDIT')
|
|
40
|
+
lines.extend(section(ReplCommands.audit_ops()))
|
|
36
41
|
lines.append('TOOLS')
|
|
37
42
|
lines.extend(section(ReplCommands.tools()))
|
|
38
|
-
lines.append('APP')
|
|
39
|
-
lines.extend(section(ReplCommands.app()))
|
|
40
43
|
lines.append('')
|
|
41
44
|
lines.extend(section(ReplCommands.exit()))
|
|
42
45
|
|
adam/commands/issues.py
CHANGED
|
@@ -21,11 +21,17 @@ class Issues(Command):
|
|
|
21
21
|
def command(self):
|
|
22
22
|
return Issues.COMMAND
|
|
23
23
|
|
|
24
|
+
def required(self):
|
|
25
|
+
return ReplState.NON_L
|
|
26
|
+
|
|
24
27
|
def run(self, cmd: str, state: ReplState):
|
|
25
28
|
if not(args := self.args(cmd)):
|
|
26
29
|
return super().run(cmd, state)
|
|
27
30
|
|
|
28
31
|
state, args = self.apply_state(args, state)
|
|
32
|
+
if not self.validate_state(state):
|
|
33
|
+
return state
|
|
34
|
+
|
|
29
35
|
args, show = Command.extract_options(args, ['-s', '--show'])
|
|
30
36
|
|
|
31
37
|
results = run_checks(state.sts, state.namespace, state.pod, show_output=show)
|
adam/commands/login.py
CHANGED
|
@@ -8,7 +8,7 @@ from adam.config import Config
|
|
|
8
8
|
from adam.sso.idp import Idp
|
|
9
9
|
from adam.sso.idp_login import IdpLogin
|
|
10
10
|
from adam.commands.command import Command
|
|
11
|
-
from adam.repl_state import ReplState
|
|
11
|
+
from adam.repl_state import ReplState, RequiredState
|
|
12
12
|
from adam.utils import log, log2
|
|
13
13
|
|
|
14
14
|
class Login(Command):
|
|
@@ -26,6 +26,9 @@ class Login(Command):
|
|
|
26
26
|
def command(self):
|
|
27
27
|
return Login.COMMAND
|
|
28
28
|
|
|
29
|
+
def required(self):
|
|
30
|
+
return ReplState.NON_L
|
|
31
|
+
|
|
29
32
|
def run(self, cmd: str, state: ReplState):
|
|
30
33
|
def custom_handler(signum, frame):
|
|
31
34
|
AppSession.ctrl_c_entered = True
|
|
@@ -59,8 +62,8 @@ class Login(Command):
|
|
|
59
62
|
|
|
60
63
|
return state
|
|
61
64
|
|
|
62
|
-
def completion(self,
|
|
63
|
-
return
|
|
65
|
+
def completion(self, state: ReplState):
|
|
66
|
+
return super().completion(state)
|
|
64
67
|
|
|
65
68
|
def help(self, _: ReplState):
|
|
66
69
|
return f'{Login.COMMAND}\t SSO login'
|
adam/commands/logs.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
2
|
from adam.config import Config
|
|
3
|
-
from adam.
|
|
3
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
|
|
6
6
|
class Logs(Command):
|
|
@@ -33,6 +33,7 @@ class Logs(Command):
|
|
|
33
33
|
return CassandraNodes.exec(state.pod, state.namespace, f'cat {path}')
|
|
34
34
|
|
|
35
35
|
def completion(self, _: ReplState):
|
|
36
|
+
# available only on cli
|
|
36
37
|
return {}
|
|
37
38
|
|
|
38
39
|
def help(self, _: ReplState):
|
adam/commands/ls.py
CHANGED
|
@@ -4,16 +4,17 @@ 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
|
-
from adam.
|
|
10
|
-
from adam.
|
|
11
|
-
from adam.
|
|
12
|
-
from adam.
|
|
9
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
10
|
+
from adam.utils_k8s.ingresses import Ingresses
|
|
11
|
+
from adam.utils_k8s.kube_context import KubeContext
|
|
12
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
13
13
|
from adam.pod_exec_result import PodExecResult
|
|
14
14
|
from adam.repl_state import ReplState
|
|
15
15
|
from adam.utils import lines_to_tabular, log, log2
|
|
16
16
|
from adam.apps import Apps
|
|
17
|
+
from adam.utils_audits import Audits
|
|
17
18
|
|
|
18
19
|
class Ls(Command):
|
|
19
20
|
COMMAND = 'ls'
|
|
@@ -44,7 +45,7 @@ class Ls(Command):
|
|
|
44
45
|
|
|
45
46
|
if state.device == ReplState.P:
|
|
46
47
|
if state.pg_path:
|
|
47
|
-
pg =
|
|
48
|
+
pg: PostgresContext = PostgresContext.apply(state.namespace, state.pg_path)
|
|
48
49
|
if pg.db:
|
|
49
50
|
self.show_pg_tables(pg)
|
|
50
51
|
else:
|
|
@@ -71,6 +72,8 @@ class Ls(Command):
|
|
|
71
72
|
svcs = [n for n, ns in Apps.envs()]
|
|
72
73
|
|
|
73
74
|
log(lines_to_tabular(svcs, 'ENV', separator=','))
|
|
75
|
+
elif state.device == ReplState.L:
|
|
76
|
+
self.show_audit_log_tables()
|
|
74
77
|
else:
|
|
75
78
|
if state.pod:
|
|
76
79
|
r: PodExecResult = Cqlsh().run(f'cql describe tables', state)
|
|
@@ -86,9 +89,9 @@ class Ls(Command):
|
|
|
86
89
|
return state
|
|
87
90
|
|
|
88
91
|
def show_statefulsets(self):
|
|
89
|
-
ss = StatefulSets.list_sts_names(
|
|
92
|
+
ss = StatefulSets.list_sts_names()
|
|
90
93
|
if len(ss) == 0:
|
|
91
|
-
log2('No
|
|
94
|
+
log2('No Cassandra clusters found.')
|
|
92
95
|
return
|
|
93
96
|
|
|
94
97
|
app_ids = CustomResources.get_app_ids()
|
|
@@ -107,34 +110,37 @@ class Ls(Command):
|
|
|
107
110
|
|
|
108
111
|
def show_pg_hosts(self, state: ReplState):
|
|
109
112
|
if state.namespace:
|
|
110
|
-
def line(pg:
|
|
111
|
-
return f'{pg.
|
|
113
|
+
def line(pg: PostgresContext):
|
|
114
|
+
return f'{pg.path()},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
|
|
112
115
|
|
|
113
|
-
lines = [line(
|
|
116
|
+
lines = [line(PostgresContext.apply(state.namespace, pg)) for pg in PostgresContext.hosts(state.namespace)]
|
|
114
117
|
|
|
115
118
|
log(lines_to_tabular(lines, 'NAME,ENDPOINT,USERNAME,PASSWORD', separator=','))
|
|
116
119
|
else:
|
|
117
|
-
def line(pg:
|
|
118
|
-
return f'{pg.
|
|
120
|
+
def line(pg: PostgresContext):
|
|
121
|
+
return f'{pg.path()},{pg.namespace},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
|
|
119
122
|
|
|
120
|
-
lines = [line(
|
|
123
|
+
lines = [line(PostgresContext.apply(state.namespace, pg)) for pg in PostgresContext.hosts(state.namespace)]
|
|
121
124
|
|
|
122
125
|
log(lines_to_tabular(lines, 'NAME,NAMESPACE,ENDPOINT,USERNAME,PASSWORD', separator=','))
|
|
123
126
|
|
|
124
|
-
def show_pg_databases(self, pg:
|
|
125
|
-
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=','))
|
|
126
129
|
|
|
127
|
-
def show_pg_tables(self, pg:
|
|
128
|
-
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=','))
|
|
129
132
|
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
return {}
|
|
133
|
+
def show_audit_log_tables(self):
|
|
134
|
+
log(lines_to_tabular(Audits.audit_table_names(), 'NAME', separator=','))
|
|
133
135
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
def completion(self, state: ReplState):
|
|
137
|
+
if state.device == ReplState.C:
|
|
138
|
+
if state.pod:
|
|
139
|
+
return super().completion(state)
|
|
140
|
+
elif not state.sts:
|
|
141
|
+
return {Ls.COMMAND: {n: None for n in StatefulSets.list_sts_names()}}
|
|
136
142
|
|
|
137
|
-
return
|
|
143
|
+
return super().completion(state)
|
|
138
144
|
|
|
139
145
|
def help(self, _: ReplState):
|
|
140
146
|
return f'{Ls.COMMAND} [device:]\t list apps, envs, clusters, nodes, pg hosts or pg databases'
|
|
@@ -2,9 +2,9 @@ from datetime import datetime
|
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
4
|
from adam.commands.command import Command
|
|
5
|
-
from adam.
|
|
5
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
6
6
|
from adam.repl_state import ReplState, RequiredState
|
|
7
|
-
from adam.
|
|
7
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
8
8
|
from adam.utils import log2
|
|
9
9
|
|
|
10
10
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
|
|
3
3
|
from adam.commands.command import Command
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
5
5
|
from adam.repl_state import ReplState, RequiredState
|
|
6
|
-
from adam.
|
|
6
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
7
7
|
from adam.config import Config
|
|
8
8
|
from adam.utils import lines_to_tabular, log2
|
|
9
9
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
3
3
|
from adam.repl_state import ReplState, RequiredState
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
5
5
|
from adam.utils import lines_to_tabular, log2
|
|
6
6
|
|
|
7
7
|
|
|
@@ -29,6 +29,7 @@ class MedusaShowBackupJobs(Command):
|
|
|
29
29
|
state, args = self.apply_state(args, state)
|
|
30
30
|
if not self.validate_state(state):
|
|
31
31
|
return state
|
|
32
|
+
|
|
32
33
|
ns = state.namespace
|
|
33
34
|
dc = StatefulSets.get_datacenter(state.sts, ns)
|
|
34
35
|
if not dc:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
2
|
+
from adam.utils_k8s.statefulsets import StatefulSets
|
|
3
3
|
from adam.repl_state import ReplState, RequiredState
|
|
4
|
-
from adam.
|
|
4
|
+
from adam.utils_k8s.custom_resources import CustomResources
|
|
5
5
|
from adam.utils import lines_to_tabular, log2
|
|
6
6
|
|
|
7
7
|
class MedusaShowRestoreJobs(Command):
|
adam/commands/nodetool.py
CHANGED
|
@@ -4,8 +4,8 @@ from adam.commands.command import Command
|
|
|
4
4
|
from adam.commands.command_helpers import ClusterOrPodCommandHelper
|
|
5
5
|
from adam.commands.nodetool_commands import NODETOOL_COMMANDS
|
|
6
6
|
from adam.config import Config
|
|
7
|
-
from adam.
|
|
8
|
-
from adam.
|
|
7
|
+
from adam.utils_k8s.cassandra_clusters import CassandraClusters
|
|
8
|
+
from adam.utils_k8s.cassandra_nodes import CassandraNodes
|
|
9
9
|
from adam.repl_state import ReplState, RequiredState
|
|
10
10
|
from adam.utils import log
|
|
11
11
|
|
|
@@ -43,9 +43,11 @@ class NodeTool(Command):
|
|
|
43
43
|
elif state.sts:
|
|
44
44
|
return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool', show_out=True)
|
|
45
45
|
|
|
46
|
+
return state
|
|
47
|
+
|
|
46
48
|
def completion(self, state: ReplState):
|
|
47
49
|
if state.pod or state.sts:
|
|
48
|
-
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}}
|
|
49
51
|
|
|
50
52
|
return {}
|
|
51
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)
|
|
@@ -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,10 @@
|
|
|
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_audits import Audits
|
|
11
8
|
|
|
12
9
|
class PreviewTable(Command):
|
|
13
10
|
COMMAND = 'preview'
|
|
@@ -25,28 +22,26 @@ class PreviewTable(Command):
|
|
|
25
22
|
return PreviewTable.COMMAND
|
|
26
23
|
|
|
27
24
|
def required(self):
|
|
28
|
-
return RequiredState.CLUSTER_OR_POD
|
|
25
|
+
return [RequiredState.CLUSTER_OR_POD, RequiredState.PG_DATABASE, ReplState.L]
|
|
29
26
|
|
|
30
27
|
def run(self, cmd: str, state: ReplState):
|
|
31
28
|
if not(args := self.args(cmd)):
|
|
32
29
|
return super().run(cmd, state)
|
|
33
30
|
|
|
34
31
|
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
|
|
32
|
+
if not self.validate_state(state):
|
|
33
|
+
return state
|
|
41
34
|
|
|
42
35
|
if not args:
|
|
43
36
|
def show_tables():
|
|
44
37
|
if state.device == ReplState.P:
|
|
45
|
-
pg =
|
|
46
|
-
lines = [db["name"] for db in pg.tables() if db["schema"] ==
|
|
38
|
+
pg = PostgresContext.apply(state.namespace, state.pg_path)
|
|
39
|
+
lines = [db["name"] for db in pg.tables() if db["schema"] == PostgresContext.default_schema()]
|
|
47
40
|
log(lines_to_tabular(lines, separator=','))
|
|
41
|
+
elif state.device == ReplState.L:
|
|
42
|
+
log(lines_to_tabular(Audits.audit_table_names(), separator=','))
|
|
48
43
|
else:
|
|
49
|
-
|
|
44
|
+
log(lines_to_tabular(cassandra_table_names(state), separator=','))
|
|
50
45
|
|
|
51
46
|
if state.in_repl:
|
|
52
47
|
log2('Table is required.')
|
|
@@ -65,26 +60,16 @@ class PreviewTable(Command):
|
|
|
65
60
|
|
|
66
61
|
rows = Config().get('preview.rows', 10)
|
|
67
62
|
if state.device == ReplState.P:
|
|
68
|
-
|
|
63
|
+
PostgresContext.apply(state.namespace, state.pg_path).run_sql(f'select * from {table} limit {rows}')
|
|
64
|
+
elif state.device == ReplState.L:
|
|
65
|
+
Audits.run_audit_query(f'select * from {table} limit {rows}')
|
|
69
66
|
else:
|
|
70
|
-
run_cql(state, f'select * from {table} limit {rows}', show_out=True, use_single_quotes=True)
|
|
67
|
+
run_cql(state, f'select * from {table} limit {rows}', show_out=True, use_single_quotes=True, on_any=True)
|
|
71
68
|
|
|
72
69
|
return state
|
|
73
70
|
|
|
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
|
-
|
|
71
|
+
def completion(self, _: ReplState):
|
|
80
72
|
return {}
|
|
81
73
|
|
|
82
74
|
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)
|
|
75
|
+
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,6 +40,8 @@ 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 == ReplState.L:
|
|
44
|
+
pass
|
|
43
45
|
else:
|
|
44
46
|
if state.sts:
|
|
45
47
|
words.append(f'sts/{state.sts}')
|
|
@@ -58,6 +60,7 @@ class Pwd(Command):
|
|
|
58
60
|
log(lines_to_tabular([
|
|
59
61
|
device_line(state, ReplState.A),
|
|
60
62
|
device_line(state, ReplState.C),
|
|
63
|
+
device_line(state, ReplState.L),
|
|
61
64
|
device_line(state, ReplState.P),
|
|
62
65
|
f'',
|
|
63
66
|
f'HOST\t{host}',
|
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
|