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.

Files changed (121) hide show
  1. adam/apps.py +2 -2
  2. adam/batch.py +11 -15
  3. adam/checks/check_utils.py +4 -4
  4. adam/checks/compactionstats.py +1 -1
  5. adam/checks/cpu.py +2 -2
  6. adam/checks/disk.py +1 -1
  7. adam/checks/gossip.py +1 -1
  8. adam/checks/memory.py +3 -3
  9. adam/checks/status.py +1 -1
  10. adam/commands/alter_tables.py +3 -14
  11. adam/commands/app.py +2 -2
  12. adam/commands/app_ping.py +2 -2
  13. adam/commands/audit/audit.py +85 -0
  14. adam/commands/audit/audit_repair_tables.py +76 -0
  15. adam/commands/audit/audit_run.py +57 -0
  16. adam/commands/audit/show_last10.py +50 -0
  17. adam/commands/audit/show_slow10.py +49 -0
  18. adam/commands/audit/show_top10.py +48 -0
  19. adam/commands/audit/utils_show_top10.py +59 -0
  20. adam/commands/bash.py +76 -13
  21. adam/commands/cd.py +22 -13
  22. adam/commands/check.py +6 -0
  23. adam/commands/cli_commands.py +3 -3
  24. adam/commands/command.py +15 -11
  25. adam/commands/commands_utils.py +4 -5
  26. adam/commands/cql/cql_completions.py +7 -3
  27. adam/commands/cql/cql_utils.py +13 -10
  28. adam/commands/cql/cqlsh.py +6 -3
  29. adam/commands/deploy/code_utils.py +2 -2
  30. adam/commands/deploy/deploy.py +7 -1
  31. adam/commands/deploy/deploy_pg_agent.py +2 -2
  32. adam/commands/deploy/deploy_pod.py +6 -6
  33. adam/commands/deploy/deploy_utils.py +2 -2
  34. adam/commands/deploy/undeploy.py +7 -1
  35. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  36. adam/commands/deploy/undeploy_pod.py +4 -4
  37. adam/commands/devices.py +29 -0
  38. adam/commands/help.py +10 -7
  39. adam/commands/issues.py +6 -0
  40. adam/commands/login.py +6 -3
  41. adam/commands/logs.py +2 -1
  42. adam/commands/ls.py +30 -24
  43. adam/commands/medusa/medusa_backup.py +2 -2
  44. adam/commands/medusa/medusa_restore.py +2 -2
  45. adam/commands/medusa/medusa_show_backupjobs.py +3 -2
  46. adam/commands/medusa/medusa_show_restorejobs.py +2 -2
  47. adam/commands/nodetool.py +5 -3
  48. adam/commands/postgres/postgres.py +3 -3
  49. adam/commands/postgres/{postgres_session.py → postgres_context.py} +29 -30
  50. adam/commands/postgres/postgres_utils.py +5 -5
  51. adam/commands/postgres/psql_completions.py +1 -1
  52. adam/commands/preview_table.py +17 -32
  53. adam/commands/pwd.py +5 -2
  54. adam/commands/reaper/reaper.py +3 -0
  55. adam/commands/reaper/reaper_restart.py +1 -1
  56. adam/commands/reaper/reaper_session.py +1 -1
  57. adam/commands/repair/repair.py +3 -3
  58. adam/commands/repair/repair_log.py +1 -1
  59. adam/commands/repair/repair_run.py +2 -2
  60. adam/commands/repair/repair_scan.py +1 -1
  61. adam/commands/repair/repair_stop.py +1 -1
  62. adam/commands/report.py +6 -0
  63. adam/commands/restart.py +2 -2
  64. adam/commands/rollout.py +1 -1
  65. adam/commands/show/show.py +5 -2
  66. adam/commands/show/show_app_actions.py +3 -0
  67. adam/commands/show/show_app_id.py +1 -1
  68. adam/commands/show/show_app_queues.py +3 -2
  69. adam/commands/show/show_cassandra_status.py +3 -3
  70. adam/commands/show/show_cassandra_version.py +3 -3
  71. adam/commands/show/show_host.py +33 -0
  72. adam/commands/show/show_login.py +3 -0
  73. adam/commands/show/show_processes.py +1 -1
  74. adam/commands/show/show_repairs.py +2 -2
  75. adam/commands/show/show_storage.py +1 -1
  76. adam/commands/watch.py +1 -1
  77. adam/config.py +2 -1
  78. adam/embedded_params.py +1 -1
  79. adam/pod_exec_result.py +7 -2
  80. adam/repl.py +141 -88
  81. adam/repl_commands.py +21 -20
  82. adam/repl_state.py +167 -39
  83. adam/sql/sql_completer.py +76 -386
  84. adam/sql/sql_state_machine.py +518 -0
  85. adam/sql/term_completer.py +14 -4
  86. adam/sso/cred_cache.py +1 -1
  87. adam/sso/idp.py +1 -1
  88. adam/utils.py +0 -1
  89. adam/utils_audits.py +193 -0
  90. adam/{k8s_utils → utils_k8s}/cassandra_clusters.py +6 -8
  91. adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +11 -4
  92. adam/{k8s_utils → utils_k8s}/deployment.py +2 -2
  93. adam/{k8s_utils → utils_k8s}/pods.py +33 -9
  94. adam/{k8s_utils → utils_k8s}/secrets.py +4 -0
  95. adam/{k8s_utils → utils_k8s}/statefulsets.py +4 -4
  96. adam/utils_net.py +24 -0
  97. adam/version.py +1 -1
  98. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/METADATA +1 -1
  99. kaqing-2.0.110.dist-info/RECORD +187 -0
  100. adam/commands/cql/cql_table_completer.py +0 -8
  101. adam/commands/describe/describe.py +0 -46
  102. adam/commands/describe/describe_keyspace.py +0 -60
  103. adam/commands/describe/describe_keyspaces.py +0 -50
  104. adam/commands/describe/describe_table.py +0 -60
  105. adam/commands/describe/describe_tables.py +0 -50
  106. adam/commands/postgres/psql_table_completer.py +0 -11
  107. adam/sql/sql_utils.py +0 -5
  108. kaqing-2.0.52.dist-info/RECORD +0 -184
  109. /adam/commands/{describe → audit}/__init__.py +0 -0
  110. /adam/{k8s_utils → utils_k8s}/__init__.py +0 -0
  111. /adam/{k8s_utils → utils_k8s}/config_maps.py +0 -0
  112. /adam/{k8s_utils → utils_k8s}/custom_resources.py +0 -0
  113. /adam/{k8s_utils → utils_k8s}/ingresses.py +0 -0
  114. /adam/{k8s_utils → utils_k8s}/jobs.py +0 -0
  115. /adam/{k8s_utils → utils_k8s}/kube_context.py +0 -0
  116. /adam/{k8s_utils → utils_k8s}/service_accounts.py +0 -0
  117. /adam/{k8s_utils → utils_k8s}/services.py +0 -0
  118. /adam/{k8s_utils → utils_k8s}/volumes.py +0 -0
  119. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/WHEEL +0 -0
  120. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/entry_points.txt +0 -0
  121. {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
- return [f' {c.help(state)}' for c in cmds if c.help(state)]
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('CHECK CASSANDRA')
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, _: ReplState):
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.k8s_utils.cassandra_nodes import CassandraNodes
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.postgres_session import PostgresSession
7
+ from adam.commands.postgres.postgres_context import PostgresContext
8
8
  from adam.config import Config
9
- from adam.k8s_utils.custom_resources import CustomResources
10
- from adam.k8s_utils.ingresses import Ingresses
11
- from adam.k8s_utils.kube_context import KubeContext
12
- from adam.k8s_utils.statefulsets import StatefulSets
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 = PostgresSession(state.namespace, state.pg_path)
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(show_namespace=not KubeContext.in_cluster_namespace())
92
+ ss = StatefulSets.list_sts_names()
90
93
  if len(ss) == 0:
91
- log2('No cassandra statefulsets found.')
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: PostgresSession):
111
- return f'{pg.directory()},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
113
+ def line(pg: PostgresContext):
114
+ return f'{pg.path()},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
112
115
 
113
- lines = [line(PostgresSession(state.namespace, pg)) for pg in PostgresSession.hosts(state.namespace)]
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: PostgresSession):
118
- return f'{pg.directory()},{pg.namespace},{pg.endpoint()}:{pg.port()},{pg.username()},{pg.password()}'
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(PostgresSession(state.namespace, pg)) for pg in PostgresSession.hosts(state.namespace)]
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: PostgresSession):
125
- log(lines_to_tabular(pg_database_names(pg.namespace, pg.directory()), 'DATABASE', separator=','))
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: PostgresSession):
128
- log(lines_to_tabular(pg_table_names(pg.namespace, pg.directory()), 'NAME', separator=','))
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 completion(self, state: ReplState):
131
- if state.pod:
132
- return {}
133
+ def show_audit_log_tables(self):
134
+ log(lines_to_tabular(Audits.audit_table_names(), 'NAME', separator=','))
133
135
 
134
- if not state.sts:
135
- return {Ls.COMMAND: {n: None for n in StatefulSets.list_sts_names()}}
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 {Ls.COMMAND: None}
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.k8s_utils.statefulsets import StatefulSets
5
+ from adam.utils_k8s.statefulsets import StatefulSets
6
6
  from adam.repl_state import ReplState, RequiredState
7
- from adam.k8s_utils.custom_resources import CustomResources
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.k8s_utils.statefulsets import StatefulSets
4
+ from adam.utils_k8s.statefulsets import StatefulSets
5
5
  from adam.repl_state import ReplState, RequiredState
6
- from adam.k8s_utils.custom_resources import CustomResources
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.k8s_utils.statefulsets import StatefulSets
2
+ from adam.utils_k8s.statefulsets import StatefulSets
3
3
  from adam.repl_state import ReplState, RequiredState
4
- from adam.k8s_utils.custom_resources import CustomResources
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.k8s_utils.statefulsets import StatefulSets
2
+ from adam.utils_k8s.statefulsets import StatefulSets
3
3
  from adam.repl_state import ReplState, RequiredState
4
- from adam.k8s_utils.custom_resources import CustomResources
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.k8s_utils.cassandra_clusters import CassandraClusters
8
- from adam.k8s_utils.cassandra_nodes import CassandraNodes
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 .postgres_session import PostgresSession
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
- PostgresSession(state.namespace, state.pg_path).run_sql(' '.join(args))
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 = PostgresSession(state.namespace, state.pg_path)
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.k8s_utils.kube_context import KubeContext
7
- from adam.k8s_utils.pods import Pods
8
- from adam.k8s_utils.secrets import Secrets
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 PostgresSession:
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 find_namespace(self, arg: str):
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 PostgresSession.hosts_for_namespace(ns)
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 PostgresSession.default_db()
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 PostgresSession.deploy_pg_agent(pod_name, ns):
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.postgres_session import PostgresSession
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 = PostgresSession(ns, pg_path)
16
- return [db['name'] for db in pg.databases() if db['owner'] == PostgresSession.default_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'] == PostgresSession.default_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 = PostgresSession(ns, pg_path)
27
+ pg = PostgresContext.apply(ns, pg_path)
28
28
  if pg.db:
29
29
  return pg.tables()
30
30
 
@@ -7,4 +7,4 @@ def psql_completions(ns: str, pg_path: str):
7
7
  '\d': None,
8
8
  '\dt': None,
9
9
  '\du': None
10
- } | SqlCompleter.completions(lambda: pg_table_names(ns, pg_path))
10
+ } | SqlCompleter(lambda: pg_table_names(ns, pg_path)).completions_for_nesting()
@@ -1,13 +1,10 @@
1
- import functools
2
-
3
1
  from adam.commands.command import Command
4
- from adam.commands.cql.cql_table_completer import CqlTableNameCompleter
5
- from adam.commands.cql.cql_utils import run_cql, table_names, tables
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 state.device == ReplState.P:
36
- if not self.validate_state(state, RequiredState.PG_DATABASE):
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 = PostgresSession(state.namespace, state.pg_path)
46
- lines = [db["name"] for db in pg.tables() if db["schema"] == PostgresSession.default_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
- run_cql(state, f'describe tables', show_out=True)
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
- PostgresSession(state.namespace, state.pg_path).run_sql(f'select * from {table} limit {rows}')
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, state: ReplState):
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.postgres_session import PostgresSession
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 = PostgresSession(state.namespace, state.pg_path)
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}',
@@ -37,6 +37,9 @@ class Reaper(Command):
37
37
  if not(args := self.args(cmd)):
38
38
  return super().run(cmd, state)
39
39
 
40
+ if not self.validate_state(state):
41
+ return state
42
+
40
43
  return super().intermediate_run(cmd, state, args, Reaper.cmd_list())
41
44
 
42
45
  def cmd_list():
@@ -1,5 +1,5 @@
1
1
  from adam.commands.command import Command
2
- from adam.k8s_utils.pods import Pods
2
+ from adam.utils_k8s.pods import Pods
3
3
  from .reaper_session import ReaperSession
4
4
  from adam.repl_state import ReplState, RequiredState
5
5
 
@@ -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.k8s_utils.kube_context import KubeContext
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
 
@@ -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
- if state.sts:
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,5 +1,5 @@
1
1
  from adam.commands.command import Command
2
- from adam.k8s_utils.jobs import Jobs
2
+ from adam.utils_k8s.jobs import Jobs
3
3
  from adam.repl_state import ReplState, RequiredState
4
4
 
5
5
  class RepairLog(Command):
@@ -1,6 +1,6 @@
1
1
  from adam.commands.command import Command
2
- from adam.k8s_utils.jobs import Jobs
3
- from adam.k8s_utils.volumes import Volumes
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
@@ -1,7 +1,7 @@
1
1
  import time
2
2
 
3
3
  from adam.commands.command import Command
4
- from adam.k8s_utils.pods import Pods
4
+ from adam.utils_k8s.pods import Pods
5
5
  from adam.repl_state import ReplState, RequiredState
6
6
  from adam.utils import log2
7
7
  from adam.config import Config
@@ -1,5 +1,5 @@
1
1
  from adam.commands.command import Command
2
- from adam.k8s_utils.jobs import Jobs
2
+ from adam.utils_k8s.jobs import Jobs
3
3
  from adam.repl_state import ReplState, RequiredState
4
4
  from adam.config import Config
5
5