kaqing 2.0.86__tar.gz → 2.0.87__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kaqing might be problematic. Click here for more details.

Files changed (196) hide show
  1. {kaqing-2.0.86 → kaqing-2.0.87}/PKG-INFO +1 -1
  2. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/audit/audit.py +13 -2
  3. kaqing-2.0.87/adam/embedded_params.py +2 -0
  4. {kaqing-2.0.86 → kaqing-2.0.87}/adam/repl.py +1 -1
  5. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sql/sql_completer.py +12 -6
  6. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sql/state_machine.py +24 -10
  7. {kaqing-2.0.86 → kaqing-2.0.87}/adam/utils_athena.py +42 -12
  8. kaqing-2.0.87/adam/version.py +5 -0
  9. {kaqing-2.0.86 → kaqing-2.0.87}/kaqing.egg-info/PKG-INFO +1 -1
  10. {kaqing-2.0.86 → kaqing-2.0.87}/setup.py +1 -1
  11. kaqing-2.0.86/adam/embedded_params.py +0 -2
  12. kaqing-2.0.86/adam/version.py +0 -5
  13. {kaqing-2.0.86 → kaqing-2.0.87}/README +0 -0
  14. {kaqing-2.0.86 → kaqing-2.0.87}/adam/__init__.py +0 -0
  15. {kaqing-2.0.86 → kaqing-2.0.87}/adam/app_session.py +0 -0
  16. {kaqing-2.0.86 → kaqing-2.0.87}/adam/apps.py +0 -0
  17. {kaqing-2.0.86 → kaqing-2.0.87}/adam/batch.py +0 -0
  18. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/__init__.py +0 -0
  19. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/check.py +0 -0
  20. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/check_context.py +0 -0
  21. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/check_result.py +0 -0
  22. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/check_utils.py +0 -0
  23. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/compactionstats.py +0 -0
  24. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/cpu.py +0 -0
  25. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/disk.py +0 -0
  26. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/gossip.py +0 -0
  27. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/issue.py +0 -0
  28. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/memory.py +0 -0
  29. {kaqing-2.0.86 → kaqing-2.0.87}/adam/checks/status.py +0 -0
  30. {kaqing-2.0.86 → kaqing-2.0.87}/adam/cli.py +0 -0
  31. {kaqing-2.0.86 → kaqing-2.0.87}/adam/cli_group.py +0 -0
  32. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/__init__.py +0 -0
  33. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/column.py +0 -0
  34. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/columns.py +0 -0
  35. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/compactions.py +0 -0
  36. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/cpu.py +0 -0
  37. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/dir_data.py +0 -0
  38. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/dir_snapshots.py +0 -0
  39. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/gossip.py +0 -0
  40. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/host_id.py +0 -0
  41. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/memory.py +0 -0
  42. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/node_address.py +0 -0
  43. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/node_load.py +0 -0
  44. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/node_owns.py +0 -0
  45. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/node_status.py +0 -0
  46. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/node_tokens.py +0 -0
  47. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/node_utils.py +0 -0
  48. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/pod_name.py +0 -0
  49. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/volume_cassandra.py +0 -0
  50. {kaqing-2.0.86 → kaqing-2.0.87}/adam/columns/volume_root.py +0 -0
  51. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/__init__.py +0 -0
  52. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/alter_tables.py +0 -0
  53. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/app.py +0 -0
  54. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/app_ping.py +0 -0
  55. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/audit/__init__.py +0 -0
  56. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/audit/audit_repair_tables.py +0 -0
  57. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/bash.py +0 -0
  58. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cd.py +0 -0
  59. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/check.py +0 -0
  60. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cli_commands.py +0 -0
  61. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/command.py +0 -0
  62. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/command_helpers.py +0 -0
  63. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/commands_utils.py +0 -0
  64. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cp.py +0 -0
  65. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cql/__init__.py +0 -0
  66. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cql/cql_completions.py +0 -0
  67. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cql/cql_table_completer.py +0 -0
  68. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cql/cql_utils.py +0 -0
  69. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/cql/cqlsh.py +0 -0
  70. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/__init__.py +0 -0
  71. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/code_start.py +0 -0
  72. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/code_stop.py +0 -0
  73. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/code_utils.py +0 -0
  74. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/deploy.py +0 -0
  75. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/deploy_frontend.py +0 -0
  76. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/deploy_pg_agent.py +0 -0
  77. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/deploy_pod.py +0 -0
  78. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/deploy_utils.py +0 -0
  79. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/undeploy.py +0 -0
  80. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/undeploy_frontend.py +0 -0
  81. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/undeploy_pg_agent.py +0 -0
  82. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/deploy/undeploy_pod.py +0 -0
  83. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/describe/__init__.py +0 -0
  84. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/describe/describe.py +0 -0
  85. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/describe/describe_keyspace.py +0 -0
  86. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/describe/describe_keyspaces.py +0 -0
  87. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/describe/describe_table.py +0 -0
  88. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/describe/describe_tables.py +0 -0
  89. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/devices.py +0 -0
  90. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/exit.py +0 -0
  91. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/help.py +0 -0
  92. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/issues.py +0 -0
  93. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/login.py +0 -0
  94. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/logs.py +0 -0
  95. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/ls.py +0 -0
  96. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/medusa/__init__.py +0 -0
  97. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/medusa/medusa.py +0 -0
  98. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/medusa/medusa_backup.py +0 -0
  99. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/medusa/medusa_restore.py +0 -0
  100. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/medusa/medusa_show_backupjobs.py +0 -0
  101. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/medusa/medusa_show_restorejobs.py +0 -0
  102. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/nodetool.py +0 -0
  103. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/nodetool_commands.py +0 -0
  104. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/param_get.py +0 -0
  105. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/param_set.py +0 -0
  106. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/__init__.py +0 -0
  107. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/postgres.py +0 -0
  108. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/postgres_ls.py +0 -0
  109. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/postgres_preview.py +0 -0
  110. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/postgres_session.py +0 -0
  111. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/postgres_utils.py +0 -0
  112. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/psql_completions.py +0 -0
  113. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/postgres/psql_table_completer.py +0 -0
  114. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/preview_table.py +0 -0
  115. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/pwd.py +0 -0
  116. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/__init__.py +0 -0
  117. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper.py +0 -0
  118. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_forward.py +0 -0
  119. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_forward_stop.py +0 -0
  120. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_restart.py +0 -0
  121. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_run_abort.py +0 -0
  122. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_runs.py +0 -0
  123. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_runs_abort.py +0 -0
  124. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_schedule_activate.py +0 -0
  125. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_schedule_start.py +0 -0
  126. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_schedule_stop.py +0 -0
  127. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_schedules.py +0 -0
  128. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_session.py +0 -0
  129. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/reaper/reaper_status.py +0 -0
  130. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/repair/__init__.py +0 -0
  131. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/repair/repair.py +0 -0
  132. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/repair/repair_log.py +0 -0
  133. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/repair/repair_run.py +0 -0
  134. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/repair/repair_scan.py +0 -0
  135. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/repair/repair_stop.py +0 -0
  136. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/report.py +0 -0
  137. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/restart.py +0 -0
  138. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/rollout.py +0 -0
  139. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/shell.py +0 -0
  140. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/__init__.py +0 -0
  141. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show.py +0 -0
  142. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_adam.py +0 -0
  143. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_app_actions.py +0 -0
  144. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_app_id.py +0 -0
  145. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_app_queues.py +0 -0
  146. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_cassandra_status.py +0 -0
  147. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_cassandra_version.py +0 -0
  148. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_commands.py +0 -0
  149. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_host.py +0 -0
  150. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_login.py +0 -0
  151. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_params.py +0 -0
  152. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_processes.py +0 -0
  153. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_repairs.py +0 -0
  154. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/show/show_storage.py +0 -0
  155. {kaqing-2.0.86 → kaqing-2.0.87}/adam/commands/watch.py +0 -0
  156. {kaqing-2.0.86 → kaqing-2.0.87}/adam/config.py +0 -0
  157. {kaqing-2.0.86 → kaqing-2.0.87}/adam/embedded_apps.py +0 -0
  158. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/__init__.py +0 -0
  159. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/cassandra_clusters.py +0 -0
  160. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/cassandra_nodes.py +0 -0
  161. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/config_maps.py +0 -0
  162. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/custom_resources.py +0 -0
  163. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/deployment.py +0 -0
  164. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/ingresses.py +0 -0
  165. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/jobs.py +0 -0
  166. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/kube_context.py +0 -0
  167. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/pods.py +0 -0
  168. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/secrets.py +0 -0
  169. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/service_accounts.py +0 -0
  170. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/services.py +0 -0
  171. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/statefulsets.py +0 -0
  172. {kaqing-2.0.86 → kaqing-2.0.87}/adam/k8s_utils/volumes.py +0 -0
  173. {kaqing-2.0.86 → kaqing-2.0.87}/adam/log.py +0 -0
  174. {kaqing-2.0.86 → kaqing-2.0.87}/adam/pod_exec_result.py +0 -0
  175. {kaqing-2.0.86 → kaqing-2.0.87}/adam/repl_commands.py +0 -0
  176. {kaqing-2.0.86 → kaqing-2.0.87}/adam/repl_session.py +0 -0
  177. {kaqing-2.0.86 → kaqing-2.0.87}/adam/repl_state.py +0 -0
  178. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sql/__init__.py +0 -0
  179. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sql/term_completer.py +0 -0
  180. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/__init__.py +0 -0
  181. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/authenticator.py +0 -0
  182. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/authn_ad.py +0 -0
  183. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/authn_okta.py +0 -0
  184. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/cred_cache.py +0 -0
  185. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/id_token.py +0 -0
  186. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/idp.py +0 -0
  187. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/idp_login.py +0 -0
  188. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/idp_session.py +0 -0
  189. {kaqing-2.0.86 → kaqing-2.0.87}/adam/sso/sso_config.py +0 -0
  190. {kaqing-2.0.86 → kaqing-2.0.87}/adam/utils.py +0 -0
  191. {kaqing-2.0.86 → kaqing-2.0.87}/adam/utils_net.py +0 -0
  192. {kaqing-2.0.86 → kaqing-2.0.87}/kaqing.egg-info/SOURCES.txt +0 -0
  193. {kaqing-2.0.86 → kaqing-2.0.87}/kaqing.egg-info/dependency_links.txt +0 -0
  194. {kaqing-2.0.86 → kaqing-2.0.87}/kaqing.egg-info/entry_points.txt +0 -0
  195. {kaqing-2.0.86 → kaqing-2.0.87}/kaqing.egg-info/top_level.txt +0 -0
  196. {kaqing-2.0.86 → kaqing-2.0.87}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kaqing
3
- Version: 2.0.86
3
+ Version: 2.0.87
4
4
  Summary: UNKNOWN
5
5
  Home-page: UNKNOWN
6
6
  License: UNKNOWN
@@ -2,10 +2,11 @@ import click
2
2
 
3
3
  from adam.commands.audit.audit_repair_tables import AuditRepairTables
4
4
  from adam.commands.command import Command
5
+ from adam.config import Config
5
6
  from adam.repl_state import ReplState
6
7
  from adam.sql.sql_completer import SqlCompleter
7
8
  from adam.utils import log2
8
- from adam.utils_athena import audit_table_names, run_audit_query
9
+ from adam.utils_athena import audit_column_names, audit_table_names, run_audit_query
9
10
 
10
11
  class Audit(Command):
11
12
  COMMAND = 'audit'
@@ -18,6 +19,7 @@ class Audit(Command):
18
19
 
19
20
  def __init__(self, successor: Command=None):
20
21
  super().__init__(successor)
22
+ self.schema_read = False
21
23
 
22
24
  def command(self):
23
25
  return Audit.COMMAND
@@ -45,7 +47,16 @@ class Audit(Command):
45
47
 
46
48
  def completion(self, state: ReplState):
47
49
  if state.device == ReplState.L:
48
- return super().completion(state) | SqlCompleter.completions(lambda: audit_table_names())
50
+ if not self.schema_read:
51
+ Config().wait_log(f'Inspecting audit database schema...')
52
+ self.schema_read = True
53
+ audit_column_names()
54
+
55
+ def columns(_):
56
+ return audit_column_names()
57
+
58
+ return super().completion(state) | SqlCompleter.completions(lambda: audit_table_names(), columns=columns) | {
59
+ 'desc': {table: None for table in audit_table_names()}}
49
60
 
50
61
  return {}
51
62
 
@@ -0,0 +1,2 @@
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-app': 'c3/c3', 'auto-enter-only-cluster': 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}}
@@ -175,7 +175,7 @@ def enter_repl(state: ReplState):
175
175
  log2(f'Timing command {cmd}: {time.time() - s0:.2f}')
176
176
 
177
177
  # offload audit logging
178
- if cmd:
178
+ if cmd and (state.device != ReplState.L or Config().get('audit.log-audit-queries', False)):
179
179
  executor.submit(audit_log, cmd, state)
180
180
 
181
181
  def audit_log(cmd: str, state: ReplState):
@@ -13,11 +13,15 @@ __all__ = [
13
13
 
14
14
  DML_COMPLETER = TermCompleter(['select', 'insert', 'delete', 'update'])
15
15
 
16
+ def default_columns(tables: list[str]):
17
+ return 'id,x.,y.,z.'.split(',')
18
+
16
19
  class SqlCompleter(Completer):
17
- def __init__(self, tables: Callable[[], list[str]], dml: str = None, debug = False):
20
+ def __init__(self, tables: Callable[[], list[str]], dml: str = None, columns: Callable[[list[str]], list[str]] = default_columns, debug = False):
18
21
  super().__init__()
19
22
  self.dml = dml
20
23
  self.tables = tables
24
+ self.columns = columns
21
25
  self.debug = debug
22
26
  self.machine = StateMachine(debug=self.debug)
23
27
 
@@ -49,6 +53,8 @@ class SqlCompleter(Completer):
49
53
  for word in self.machine.suggestions[state.to_s].strip(' ').split(','):
50
54
  if word == 'tables':
51
55
  terms.extend(self.tables())
56
+ elif word == 'columns':
57
+ terms.extend(self.columns([]))
52
58
  elif word == 'single':
53
59
  terms.append("'")
54
60
  elif word == 'comma':
@@ -63,10 +69,10 @@ class SqlCompleter(Completer):
63
69
  for c in completer.get_completions(document, complete_event):
64
70
  yield c
65
71
 
66
- def completions(table_names: Callable[[], list[str]]):
72
+ def completions(table_names: Callable[[], list[str]], columns: Callable[[list[str]], list[str]] = default_columns):
67
73
  return {
68
- 'delete': SqlCompleter(table_names, 'delete'),
69
- 'insert': SqlCompleter(table_names, 'insert'),
70
- 'select': SqlCompleter(table_names, 'select'),
71
- 'update': SqlCompleter(table_names, 'update'),
74
+ 'delete': SqlCompleter(table_names, 'delete', columns=columns),
75
+ 'insert': SqlCompleter(table_names, 'insert', columns=columns),
76
+ 'select': SqlCompleter(table_names, 'select', columns=columns),
77
+ 'update': SqlCompleter(table_names, 'update', columns=columns),
72
78
  }
@@ -141,10 +141,12 @@ SPEC = [
141
141
  'select_from_x > , > select_from_x_comma_',
142
142
  'select_from_sq_ > as > select_from_x_as ^ as',
143
143
  'select_from_x_comma_ > name > select_from_x ^ tables',
144
- 'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,limit',
145
- 'select_from_x_as_x_ > , > select_from_x_comma_ ^ where,inner join,left outer join,right outer join,full outer join,group by,limit',
144
+ 'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
145
+ 'select_from_x_as_x_ > , > select_from_x_comma_ ^ where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
146
146
  '- > as > select_from_x_as',
147
147
  '- > where > select_where',
148
+ '- > order > select_order',
149
+ '- > order by > select_order_by',
148
150
  '- > limit > select_where_sc_limit',
149
151
  '- > group > select_group',
150
152
  '- > group by > select_group_by',
@@ -161,7 +163,7 @@ SPEC = [
161
163
  'select_from_x_as_ > name > select_from_x_as_x ^ x,y,z',
162
164
  'select_from_x_as_x > , > select_from_x_as_x_comma_',
163
165
  'select_from_x_as_x_comma_ > name > select_from_x ^ tables',
164
- 'select_where_ > name > select_where_a ^ id,x.,y.,z.',
166
+ 'select_where_ > name > select_where_a ^ columns',
165
167
  'select_where_a > comparison > select_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
166
168
  'select_where_a_ > comparison > select_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
167
169
  '- > not > select_where_a_not',
@@ -177,15 +179,27 @@ SPEC = [
177
179
  'select_where_a_in_lp_a_comma_ > name|single|num > select_where_a_in_lp_a ^ single',
178
180
  'select_where_a_not_op > name|single|num > select_where_sc ^ single',
179
181
  'select_where_a_op > name|single|num > select_where_sc ^ single',
180
- 'select_where_sc_ > and|or > select_where ^ and,or,group by,limit',
182
+ 'select_where_sc_ > and|or > select_where ^ and,or,order by,group by,limit',
181
183
  '- > group > select_group',
182
184
  '- > group by > select_group_by',
185
+ '- > order > select_order',
186
+ '- > order by > select_order_by',
183
187
  '- > limit > select_where_sc_limit',
184
188
  'select_group_ > by > select_group_by ^ by',
185
- 'select_group_by_ > name > select_group_by_a ^ id,x.,y.,z.',
189
+ 'select_group_by_ > name > select_group_by_a ^ columns',
186
190
  'select_group_by_a > , > select_group_by_a_comma_',
187
- 'select_group_by_a_comma_ > name > select_group_by_a ^ id,x.,y.,z.',
188
- 'select_group_by_a_ > limit > select_where_sc_limit ^ limit',
191
+ 'select_group_by_a_comma_ > name > select_group_by_a ^ columns',
192
+ 'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by',
193
+ '- > order > select_order',
194
+ '- > order by > select_order_by',
195
+ 'select_order_ > by > select_order_by ^ by',
196
+ 'select_order_by_ > name > select_order_by_a ^ columns',
197
+ 'select_order_by_a > , > select_order_by_a_comma_',
198
+ 'select_order_by_a_comma_ > name > select_order_by_a ^ columns',
199
+ 'select_order_by_a_ > desc|asc > select_order_by_a_desc ^ desc,asc,limit',
200
+ '- > limit > select_where_sc_limit',
201
+ 'select_order_by_a_desc > , > select_order_by_a_comma_',
202
+ 'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit',
189
203
  'select_where_sc_limit_ > num > select_where_sc_limit_num ^ 1',
190
204
  'select_where_sc_limit_num_rp__ > as > select_from_x_as ^ as',
191
205
  'select_where_x_inner_ > join > select_join',
@@ -203,9 +217,9 @@ SPEC = [
203
217
  '- > on > select_x_join_y_on ^ as,on',
204
218
  'select_x_join_y_as_ > name > select_x_join_y_as_y ^ x,y,z',
205
219
  'select_x_join_y_as_y_ > on > select_x_join_y_on ^ on',
206
- 'select_x_join_y_on_ > name > select_x_join_y_on_a ^ id,x.,y.,z.',
220
+ 'select_x_join_y_on_ > name > select_x_join_y_on_a ^ columns',
207
221
  'select_x_join_y_on_a > comparison > select_x_join_y_on_a_op ^ =',
208
- 'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ id,x.,y.,z.',
222
+ 'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ columns',
209
223
  'select_x_join_y_on_a_op_b > _ > select_from_x_as_x_',
210
224
 
211
225
 
@@ -264,7 +278,7 @@ SPEC = [
264
278
 
265
279
  KEYWORDS = [
266
280
  'select', 'from', 'as', 'not', 'in', 'where',
267
- 'and', 'or', 'group', 'by', 'group by', 'limit',
281
+ 'and', 'or', 'group', 'by', 'group by', 'order', 'order by', 'limit', 'asc', 'desc',
268
282
  'inner join', 'on', 'left', 'right', 'full', 'outer', 'left outer join',
269
283
  'left join', 'right outer join', 'right join', 'full join', 'full outer join',
270
284
  'insert', 'into', 'values',
@@ -21,16 +21,52 @@ def audit_table_names():
21
21
 
22
22
  return table_names
23
23
 
24
- def run_audit_query(sql: str):
24
+ @functools.lru_cache()
25
+ def audit_column_names(tables: list[str] = [], database: str = None):
26
+ if not database:
27
+ database = Config().get('audit.athena.database', 'audit')
28
+
29
+ if not tables:
30
+ tables = Config().get('audit.athena.tables', 'audit').split(',')
31
+
32
+ table_names = "'" + "','".join([table.strip() for table in tables]) + "'"
33
+
34
+ query = f"select column_name from information_schema.columns where table_name in ({table_names}) and table_schema = '{database}'"
35
+ _, _, rs = audit_query(query)
36
+ if rs:
37
+ return [row['Data'][0].get('VarCharValue') for row in rs[1:]]
38
+
39
+ return []
40
+
41
+ def run_audit_query(sql: str, database: str = None):
42
+ state, reason, rs = audit_query(sql, database)
43
+
44
+ if state == 'SUCCEEDED':
45
+ if rs:
46
+ column_info = rs[0]['Data']
47
+ columns = [col.get('VarCharValue') for col in column_info]
48
+ lines = []
49
+ for row in rs[1:]:
50
+ row_data = [col.get('VarCharValue') for col in row['Data']]
51
+ lines.append('\t'.join(row_data))
52
+
53
+ log(lines_to_tabular(lines, header='\t'.join(columns), separator='\t'))
54
+ else:
55
+ log2(f"Query failed or was cancelled. State: {state}")
56
+ log2(f"Reason: {reason}")
57
+
58
+ def audit_query(sql: str, database: str = None) -> tuple[str, str, list]:
25
59
  athena_client = boto3.client('athena')
26
60
 
27
- database_name = Config().get('audit.athena.database', 'audit')
61
+ if not database:
62
+ database = Config().get('audit.athena.database', 'audit')
63
+
28
64
  s3_output_location = Config().get('audit.athena.output', 's3://s3.ops--audit/ddl/results')
29
65
 
30
66
  response = athena_client.start_query_execution(
31
67
  QueryString=sql,
32
68
  QueryExecutionContext={
33
- 'Database': database_name
69
+ 'Database': database
34
70
  },
35
71
  ResultConfiguration={
36
72
  'OutputLocation': s3_output_location
@@ -49,14 +85,8 @@ def run_audit_query(sql: str):
49
85
  if state == 'SUCCEEDED':
50
86
  results_response = athena_client.get_query_results(QueryExecutionId=query_execution_id)
51
87
  if results_response['ResultSet']['Rows']:
52
- column_info = results_response['ResultSet']['Rows'][0]['Data']
53
- columns = [col.get('VarCharValue') for col in column_info]
54
- lines = []
55
- for row in results_response['ResultSet']['Rows'][1:]:
56
- row_data = [col.get('VarCharValue') for col in row['Data']]
57
- lines.append('\t'.join(row_data))
88
+ return (state, None, results_response['ResultSet']['Rows'])
58
89
 
59
- log(lines_to_tabular(lines, header='\t'.join(columns), separator='\t'))
90
+ return (state, None, [])
60
91
  else:
61
- log2(f"Query failed or was cancelled. State: {state}")
62
- log2(f"Reason: {query_status['QueryExecution']['Status'].get('StateChangeReason')}")
92
+ return (state, query_status['QueryExecution']['Status'].get('StateChangeReason'), [])
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ __version__ = "2.0.87" #: the working version
5
+ __release__ = "1.0.0" #: the release version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kaqing
3
- Version: 2.0.86
3
+ Version: 2.0.87
4
4
  Summary: UNKNOWN
5
5
  Home-page: UNKNOWN
6
6
  License: UNKNOWN
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='kaqing',
5
- version='2.0.86',
5
+ version='2.0.87',
6
6
  packages=find_packages(),
7
7
  entry_points={
8
8
  'console_scripts': [
@@ -1,2 +0,0 @@
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, 'athena': {'region': 'us-west-2', 'catalog': 'AwsDataCatalog', 'database': '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-app': 'c3/c3', 'auto-enter-only-cluster': 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}}
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- __version__ = "2.0.86" #: the working version
5
- __release__ = "1.0.0" #: the release version
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes