cancan-microstack 0.0.1__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.
Files changed (440) hide show
  1. cancan_microstack/__init__.py +14 -0
  2. cancan_microstack/__version__.py +10 -0
  3. cancan_microstack/assets/__init__.py +6 -0
  4. cancan_microstack/assets/builds/caddy/Caddyfile +187 -0
  5. cancan_microstack/assets/builds/caddy/DEPLOYMENT.md +303 -0
  6. cancan_microstack/assets/builds/caddy/Dockerfile +46 -0
  7. cancan_microstack/assets/builds/caddy/README.md +343 -0
  8. cancan_microstack/assets/builds/caddy/geoip/README.md +5 -0
  9. cancan_microstack/assets/builds/caddy/start.sh +78 -0
  10. cancan_microstack/assets/builds/caddy/waf/coraza.conf +179 -0
  11. cancan_microstack/assets/builds/service/Dockerfile +59 -0
  12. cancan_microstack/assets/builds/service/README.md +13 -0
  13. cancan_microstack/assets/ddl/create_db.sql +22 -0
  14. cancan_microstack/assets/ddl/infra/execution_log_tbl.sql +46 -0
  15. cancan_microstack/assets/ddl/infra/node_instance_tbl.sql +56 -0
  16. cancan_microstack/assets/ddl/infra/service_action_log_tbl.sql +36 -0
  17. cancan_microstack/assets/ddl/infra/service_config_tbl.sql +26 -0
  18. cancan_microstack/assets/ddl/infra/service_info_tbl.sql +45 -0
  19. cancan_microstack/assets/ddl/infra/service_instance_tbl.sql +54 -0
  20. cancan_microstack/assets/ddl/infra/service_operation_tbl.sql +47 -0
  21. cancan_microstack/assets/ddl/infra/workflow_definition_tbl.sql +60 -0
  22. cancan_microstack/assets/ddl/infra/workflow_definition_version_tbl.sql +35 -0
  23. cancan_microstack/assets/ddl/infra/workflow_engine_alert_tbl.sql +34 -0
  24. cancan_microstack/assets/ddl/infra/workflow_run_tbl.sql +52 -0
  25. cancan_microstack/assets/ddl/ops/admin_user_tbl.sql +34 -0
  26. cancan_microstack/assets/ddl/ops/caddy_access_log_tbl.sql +91 -0
  27. cancan_microstack/assets/ddl/ops/caddy_certificate_tbl.sql +59 -0
  28. cancan_microstack/assets/ddl/ops/caddy_rate_limit_tbl.sql +64 -0
  29. cancan_microstack/assets/ddl/ops/caddy_route_tbl.sql +63 -0
  30. cancan_microstack/assets/ddl/ops/caddy_stats_tbl.sql +77 -0
  31. cancan_microstack/assets/ddl/trigger.sql +21 -0
  32. cancan_microstack/assets/docker/docker-compose.infra.yml +401 -0
  33. cancan_microstack/assets/scripts/README.md +195 -0
  34. cancan_microstack/assets/scripts/docker/build_images.sh +44 -0
  35. cancan_microstack/assets/scripts/docker/force_rebuild_images.sh +38 -0
  36. cancan_microstack/assets/scripts/docker/rebuild_all.sh +34 -0
  37. cancan_microstack/assets/scripts/docker/rebuild_compose.sh +61 -0
  38. cancan_microstack/assets/scripts/docker/restart.sh +35 -0
  39. cancan_microstack/assets/scripts/docker/restart_compose.sh +35 -0
  40. cancan_microstack/assets/scripts/docker/start.sh +78 -0
  41. cancan_microstack/assets/scripts/docker/start_all.sh +46 -0
  42. cancan_microstack/assets/scripts/docker/start_compose.sh +66 -0
  43. cancan_microstack/assets/scripts/docker/stop.sh +67 -0
  44. cancan_microstack/assets/scripts/docker/stop_all.sh +38 -0
  45. cancan_microstack/assets/scripts/docker/stop_compose.sh +38 -0
  46. cancan_microstack/assets/scripts/podman/build_images_podman.sh +59 -0
  47. cancan_microstack/assets/scripts/podman/cleanup_podman.sh +25 -0
  48. cancan_microstack/assets/scripts/podman/force_rebuild_images_podman.sh +56 -0
  49. cancan_microstack/assets/scripts/podman/rebuild_all_podman.sh +37 -0
  50. cancan_microstack/assets/scripts/podman/rebuild_compose_podman.sh +60 -0
  51. cancan_microstack/assets/scripts/podman/restart_compose_podman.sh +73 -0
  52. cancan_microstack/assets/scripts/podman/start_all_podman.sh +66 -0
  53. cancan_microstack/assets/scripts/podman/start_compose_podman.sh +80 -0
  54. cancan_microstack/assets/scripts/podman/start_podman.sh +91 -0
  55. cancan_microstack/assets/scripts/podman/stop.sh +73 -0
  56. cancan_microstack/assets/scripts/podman/stop_all_podman.sh +34 -0
  57. cancan_microstack/assets/scripts/podman/stop_compose_podman.sh +58 -0
  58. cancan_microstack/assets/scripts/start_controllersrv.sh +9 -0
  59. cancan_microstack/assets/scripts/utils/check_all_db_tables.sh +104 -0
  60. cancan_microstack/assets/scripts/utils/check_env.sh +177 -0
  61. cancan_microstack/assets/scripts/utils/check_service_management_deployment.sh +225 -0
  62. cancan_microstack/assets/scripts/utils/deploy_service_management.sh +176 -0
  63. cancan_microstack/assets/scripts/utils/force_reload_infrasrv.sh +52 -0
  64. cancan_microstack/assets/scripts/utils/monitor_service_management.sh +187 -0
  65. cancan_microstack/assets/scripts/utils/reset_postgres_volume.sh +68 -0
  66. cancan_microstack/assets/scripts/utils/test_async_operations.sh +141 -0
  67. cancan_microstack/assets/scripts/utils/verify_real_operations.sh +76 -0
  68. cancan_microstack/assets/service/Dockerfile +65 -0
  69. cancan_microstack/assets/www/adminops/assets/AppEmpty.vue_vue_type_script_setup_true_lang-BOKUurnM.js +1 -0
  70. cancan_microstack/assets/www/adminops/assets/ConfigManage-DKV5YOUz.js +1 -0
  71. cancan_microstack/assets/www/adminops/assets/ConfigManage-Y5bhy7wG.css +1 -0
  72. cancan_microstack/assets/www/adminops/assets/ConsoleManage-8ljYvCW2.js +1 -0
  73. cancan_microstack/assets/www/adminops/assets/ConsoleManage-BWpyqbuQ.css +1 -0
  74. cancan_microstack/assets/www/adminops/assets/DashboardNew-B9Nf1OPl.js +1 -0
  75. cancan_microstack/assets/www/adminops/assets/DashboardNew-DYWZKQ1V.css +1 -0
  76. cancan_microstack/assets/www/adminops/assets/LogSearch-CA0Jhe78.js +1 -0
  77. cancan_microstack/assets/www/adminops/assets/LogSearch-CCZfTNPF.css +1 -0
  78. cancan_microstack/assets/www/adminops/assets/LoginView-BId3kP3M.css +1 -0
  79. cancan_microstack/assets/www/adminops/assets/LoginView-BQZTV_Qy.js +1 -0
  80. cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-BdEYwqFq.js +1 -0
  81. cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-D-pASR8G.css +1 -0
  82. cancan_microstack/assets/www/adminops/assets/PageContainer-Byss-yUC.js +1 -0
  83. cancan_microstack/assets/www/adminops/assets/PageContainer-C3nSZwM7.css +1 -0
  84. cancan_microstack/assets/www/adminops/assets/RateLimitManage-BDI8jLpC.css +1 -0
  85. cancan_microstack/assets/www/adminops/assets/RateLimitManage-DJY4NiF-.js +1 -0
  86. cancan_microstack/assets/www/adminops/assets/RouteManage-DaUQ4QLw.css +1 -0
  87. cancan_microstack/assets/www/adminops/assets/RouteManage-w9XCU0UA.js +1 -0
  88. cancan_microstack/assets/www/adminops/assets/ServiceCard-BFzHe6Tw.css +1 -0
  89. cancan_microstack/assets/www/adminops/assets/ServiceCard-BJUhWnA-.js +1 -0
  90. cancan_microstack/assets/www/adminops/assets/ServiceDetail-Cw24WuKp.js +1 -0
  91. cancan_microstack/assets/www/adminops/assets/ServiceDetail-Yum47zdB.css +1 -0
  92. cancan_microstack/assets/www/adminops/assets/ServiceList-C7ryvbhE.js +1 -0
  93. cancan_microstack/assets/www/adminops/assets/ServiceList-Cgd01fUx.css +1 -0
  94. cancan_microstack/assets/www/adminops/assets/ServiceLogs-COpG9H0h.js +1 -0
  95. cancan_microstack/assets/www/adminops/assets/ServiceLogs-H_Alq0cf.css +1 -0
  96. cancan_microstack/assets/www/adminops/assets/StatsOverview-D0TwMQkA.js +39 -0
  97. cancan_microstack/assets/www/adminops/assets/StatsOverview-lqAN6pqM.css +1 -0
  98. cancan_microstack/assets/www/adminops/assets/TotpBindView-CWlAmzFt.js +1 -0
  99. cancan_microstack/assets/www/adminops/assets/TotpBindView-HoQC1lhx.css +1 -0
  100. cancan_microstack/assets/www/adminops/assets/TotpVerifyView-BHN1VtX1.css +1 -0
  101. cancan_microstack/assets/www/adminops/assets/TotpVerifyView-D3w_lZk8.js +1 -0
  102. cancan_microstack/assets/www/adminops/assets/WorkflowCenter-DU_mpIA0.css +1 -0
  103. cancan_microstack/assets/www/adminops/assets/WorkflowCenter-i50rZyxN.js +1 -0
  104. cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-CnHokPL9.js +1 -0
  105. cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-DaZaZpLd.css +1 -0
  106. cancan_microstack/assets/www/adminops/assets/WorkflowRuns-B09hK48c.js +1 -0
  107. cancan_microstack/assets/www/adminops/assets/WorkflowRuns-wGutKIIU.css +1 -0
  108. cancan_microstack/assets/www/adminops/assets/caddy-nnCKf8fG.js +1 -0
  109. cancan_microstack/assets/www/adminops/assets/format-Cuzxgna9.js +1 -0
  110. cancan_microstack/assets/www/adminops/assets/index-CiFlm8oc.js +64 -0
  111. cancan_microstack/assets/www/adminops/assets/index-UW0T1Dkc.css +1 -0
  112. cancan_microstack/assets/www/adminops/assets/service-BYlgGPs_.js +1 -0
  113. cancan_microstack/assets/www/adminops/assets/service-operation-6GzLw2Z1.js +1 -0
  114. cancan_microstack/assets/www/adminops/assets/style-CcIXnQ5y.css +1 -0
  115. cancan_microstack/assets/www/adminops/assets/style-lRnStdGu.js +39 -0
  116. cancan_microstack/assets/www/adminops/assets/useDebounce-BRlqfXqf.js +1 -0
  117. cancan_microstack/assets/www/adminops/assets/workflow-CUXs39Ac.js +1 -0
  118. cancan_microstack/assets/www/adminops/index.html +16 -0
  119. cancan_microstack/assets/www/adminops/vite.svg +1 -0
  120. cancan_microstack/cli/__init__.py +14 -0
  121. cancan_microstack/cli/__main__.py +9 -0
  122. cancan_microstack/cli/main.py +552 -0
  123. cancan_microstack/cmd/__init__.py +54 -0
  124. cancan_microstack/cmd/cancan/__init__.py +12 -0
  125. cancan_microstack/cmd/cancan/run.py +395 -0
  126. cancan_microstack/cmd/controllersrv/__init__.py +0 -0
  127. cancan_microstack/cmd/controllersrv/run.py +131 -0
  128. cancan_microstack/cmd/infrasrv/__init__.py +5 -0
  129. cancan_microstack/cmd/infrasrv/run.py +100 -0
  130. cancan_microstack/cmd/opsbffsrv/__init__.py +5 -0
  131. cancan_microstack/cmd/opsbffsrv/run.py +96 -0
  132. cancan_microstack/core/__init__.py +5 -0
  133. cancan_microstack/core/assets.py +123 -0
  134. cancan_microstack/core/compose_builder.py +102 -0
  135. cancan_microstack/core/doctor.py +152 -0
  136. cancan_microstack/core/microstack.py +71 -0
  137. cancan_microstack/core/runner.py +56 -0
  138. cancan_microstack/core/stack_manager.py +186 -0
  139. cancan_microstack/public/__init__.py +7 -0
  140. cancan_microstack/public/api/__init__.py +1 -0
  141. cancan_microstack/public/api/controllersrv_client.py +277 -0
  142. cancan_microstack/public/api/infrasrv_client.py +404 -0
  143. cancan_microstack/public/const/__init__.py +1 -0
  144. cancan_microstack/public/const/action_consts.py +18 -0
  145. cancan_microstack/public/const/app_consts.py +42 -0
  146. cancan_microstack/public/const/caddy_consts.py +22 -0
  147. cancan_microstack/public/const/controllersrv_consts.py +163 -0
  148. cancan_microstack/public/const/docker_consts.py +15 -0
  149. cancan_microstack/public/const/error.py +56 -0
  150. cancan_microstack/public/const/health_consts.py +52 -0
  151. cancan_microstack/public/const/hook_enums.py +56 -0
  152. cancan_microstack/public/const/logging_enums.py +13 -0
  153. cancan_microstack/public/const/metrics_enums.py +36 -0
  154. cancan_microstack/public/const/monitor_enums.py +26 -0
  155. cancan_microstack/public/const/operation_consts.py +53 -0
  156. cancan_microstack/public/const/opsbffsrv_error.py +92 -0
  157. cancan_microstack/public/const/overrides_consts.py +13 -0
  158. cancan_microstack/public/const/redis.py +17 -0
  159. cancan_microstack/public/const/service_consts.py +15 -0
  160. cancan_microstack/public/const/workflow_consts.py +65 -0
  161. cancan_microstack/public/error.py +41 -0
  162. cancan_microstack/public/logging/__init__.py +0 -0
  163. cancan_microstack/public/logging/initializer.py +109 -0
  164. cancan_microstack/public/logging/mq_handler.py +279 -0
  165. cancan_microstack/public/schemas/__init__.py +1 -0
  166. cancan_microstack/public/schemas/caddy/__init__.py +381 -0
  167. cancan_microstack/public/schemas/caddy/analysis.py +90 -0
  168. cancan_microstack/public/schemas/caddy/route.py +18 -0
  169. cancan_microstack/public/schemas/common.py +79 -0
  170. cancan_microstack/public/schemas/controllersrv/__init__.py +3 -0
  171. cancan_microstack/public/schemas/controllersrv/async_requests.py +30 -0
  172. cancan_microstack/public/schemas/controllersrv/compose_models.py +47 -0
  173. cancan_microstack/public/schemas/controllersrv/const.py +24 -0
  174. cancan_microstack/public/schemas/controllersrv/docker_models.py +45 -0
  175. cancan_microstack/public/schemas/controllersrv/docker_responses.py +104 -0
  176. cancan_microstack/public/schemas/controllersrv/requests.py +54 -0
  177. cancan_microstack/public/schemas/controllersrv/responses.py +124 -0
  178. cancan_microstack/public/schemas/controllersrv/task_models.py +102 -0
  179. cancan_microstack/public/schemas/controllersrv/validation.py +23 -0
  180. cancan_microstack/public/schemas/hook_metrics.py +124 -0
  181. cancan_microstack/public/schemas/hooks.py +39 -0
  182. cancan_microstack/public/schemas/infra/__init__.py +0 -0
  183. cancan_microstack/public/schemas/infra/cleanup.py +25 -0
  184. cancan_microstack/public/schemas/infra/container.py +74 -0
  185. cancan_microstack/public/schemas/infra/enums.py +135 -0
  186. cancan_microstack/public/schemas/infra/health_check.py +42 -0
  187. cancan_microstack/public/schemas/infra/hook_log.py +42 -0
  188. cancan_microstack/public/schemas/infra/operation.py +90 -0
  189. cancan_microstack/public/schemas/infra/overview.py +25 -0
  190. cancan_microstack/public/schemas/infra/push.py +33 -0
  191. cancan_microstack/public/schemas/infra/service_action_log.py +47 -0
  192. cancan_microstack/public/schemas/infra/service_config.py +10 -0
  193. cancan_microstack/public/schemas/infra/service_info.py +69 -0
  194. cancan_microstack/public/schemas/infra/service_instance.py +93 -0
  195. cancan_microstack/public/schemas/infra/service_management.py +152 -0
  196. cancan_microstack/public/schemas/infra/service_operation.py +79 -0
  197. cancan_microstack/public/schemas/infra/service_registry.py +158 -0
  198. cancan_microstack/public/schemas/infra/status_types.py +19 -0
  199. cancan_microstack/public/schemas/infra/workflow.py +566 -0
  200. cancan_microstack/public/schemas/logging/__init__.py +1 -0
  201. cancan_microstack/public/schemas/logging/log_event.py +121 -0
  202. cancan_microstack/public/schemas/opsbffsrv/__init__.py +1 -0
  203. cancan_microstack/public/schemas/opsbffsrv/async_ops.py +17 -0
  204. cancan_microstack/public/schemas/opsbffsrv/db_admin.py +147 -0
  205. cancan_microstack/public/schemas/opsbffsrv/db_init.py +48 -0
  206. cancan_microstack/public/schemas/opsbffsrv/service_config.py +89 -0
  207. cancan_microstack/public/schemas/opsbffsrv/service_logs.py +54 -0
  208. cancan_microstack/public/schemas/service_operation.py +24 -0
  209. cancan_microstack/public/schemas/service_registry.py +40 -0
  210. cancan_microstack/public/types/__init__.py +7 -0
  211. cancan_microstack/public/web/__init__.py +0 -0
  212. cancan_microstack/public/web/config_value.py +105 -0
  213. cancan_microstack/public/web/server.py +385 -0
  214. cancan_microstack/py.typed +0 -0
  215. cancan_microstack/runtime/__init__.py +0 -0
  216. cancan_microstack/runtime/compose_cmd.py +228 -0
  217. cancan_microstack/runtime/host_daemon.py +318 -0
  218. cancan_microstack/runtime/overrides.py +103 -0
  219. cancan_microstack/runtime/resources.py +25 -0
  220. cancan_microstack/runtime/workspace.py +94 -0
  221. cancan_microstack/services/__init__.py +0 -0
  222. cancan_microstack/services/controllersrv/__init__.py +8 -0
  223. cancan_microstack/services/controllersrv/application/__init__.py +0 -0
  224. cancan_microstack/services/controllersrv/application/docker_compose_app.py +427 -0
  225. cancan_microstack/services/controllersrv/conf/__init__.py +0 -0
  226. cancan_microstack/services/controllersrv/conf/config.py +76 -0
  227. cancan_microstack/services/controllersrv/conf/settings.py +54 -0
  228. cancan_microstack/services/controllersrv/domain/__init__.py +0 -0
  229. cancan_microstack/services/controllersrv/domain/docker_compose/__init__.py +0 -0
  230. cancan_microstack/services/controllersrv/domain/docker_compose/docker_compose_domain.py +278 -0
  231. cancan_microstack/services/controllersrv/domain/service_validator.py +327 -0
  232. cancan_microstack/services/controllersrv/domain/task/__init__.py +17 -0
  233. cancan_microstack/services/controllersrv/domain/task/task_queue.py +286 -0
  234. cancan_microstack/services/controllersrv/domain/task/task_worker.py +495 -0
  235. cancan_microstack/services/controllersrv/infrastructure/__init__.py +0 -0
  236. cancan_microstack/services/controllersrv/interface/__init__.py +0 -0
  237. cancan_microstack/services/controllersrv/interface/api/__init__.py +0 -0
  238. cancan_microstack/services/controllersrv/interface/api/docker_control_api.py +470 -0
  239. cancan_microstack/services/controllersrv/router.py +132 -0
  240. cancan_microstack/services/infrasrv/__init__.py +4 -0
  241. cancan_microstack/services/infrasrv/application/__init__.py +0 -0
  242. cancan_microstack/services/infrasrv/application/health_check_app.py +24 -0
  243. cancan_microstack/services/infrasrv/application/logging/__init__.py +1 -0
  244. cancan_microstack/services/infrasrv/application/logging/log_ingestion_service.py +183 -0
  245. cancan_microstack/services/infrasrv/application/service_config.py +22 -0
  246. cancan_microstack/services/infrasrv/application/service_logs_app.py +53 -0
  247. cancan_microstack/services/infrasrv/application/service_management_app.py +689 -0
  248. cancan_microstack/services/infrasrv/application/service_operation_tracker.py +251 -0
  249. cancan_microstack/services/infrasrv/application/service_registry.py +53 -0
  250. cancan_microstack/services/infrasrv/application/workflow/__init__.py +0 -0
  251. cancan_microstack/services/infrasrv/application/workflow/workflow_app.py +991 -0
  252. cancan_microstack/services/infrasrv/application/workflow/workflow_queue.py +302 -0
  253. cancan_microstack/services/infrasrv/application/workflow/workflow_tasks.py +46 -0
  254. cancan_microstack/services/infrasrv/application/workflow/workflow_worker_runtime.py +122 -0
  255. cancan_microstack/services/infrasrv/conf/__init__.py +0 -0
  256. cancan_microstack/services/infrasrv/conf/config.py +98 -0
  257. cancan_microstack/services/infrasrv/domain/__init__.py +0 -0
  258. cancan_microstack/services/infrasrv/domain/health_check/__init__.py +3 -0
  259. cancan_microstack/services/infrasrv/domain/health_check/health_check_domain.py +576 -0
  260. cancan_microstack/services/infrasrv/domain/hooks/__init__.py +19 -0
  261. cancan_microstack/services/infrasrv/domain/hooks/builtin_hooks.py +308 -0
  262. cancan_microstack/services/infrasrv/domain/hooks/hook_registry.py +43 -0
  263. cancan_microstack/services/infrasrv/domain/hooks/hooks_log_utils.py +275 -0
  264. cancan_microstack/services/infrasrv/domain/hooks/init.py +17 -0
  265. cancan_microstack/services/infrasrv/domain/hooks/metrics.py +205 -0
  266. cancan_microstack/services/infrasrv/domain/hooks/pre_registration_hooks.py +490 -0
  267. cancan_microstack/services/infrasrv/domain/registry/__init__.py +0 -0
  268. cancan_microstack/services/infrasrv/domain/registry/service_registry.py +509 -0
  269. cancan_microstack/services/infrasrv/domain/service_config/__init__.py +0 -0
  270. cancan_microstack/services/infrasrv/domain/service_config/service_config.py +50 -0
  271. cancan_microstack/services/infrasrv/domain/service_logs/__init__.py +0 -0
  272. cancan_microstack/services/infrasrv/domain/service_logs/service_logs_domain.py +51 -0
  273. cancan_microstack/services/infrasrv/domain/workflow/__init__.py +4 -0
  274. cancan_microstack/services/infrasrv/domain/workflow/engine.py +159 -0
  275. cancan_microstack/services/infrasrv/domain/workflow/node_handlers.py +509 -0
  276. cancan_microstack/services/infrasrv/domain/workflow/workflow_domain.py +164 -0
  277. cancan_microstack/services/infrasrv/infrastructure/__init__.py +0 -0
  278. cancan_microstack/services/infrasrv/infrastructure/api/__init__.py +0 -0
  279. cancan_microstack/services/infrasrv/infrastructure/api/controllersrv_api.py +165 -0
  280. cancan_microstack/services/infrasrv/infrastructure/cache/__init__.py +0 -0
  281. cancan_microstack/services/infrasrv/infrastructure/cache/service_registry_cache.py +174 -0
  282. cancan_microstack/services/infrasrv/infrastructure/db/__init__.py +0 -0
  283. cancan_microstack/services/infrasrv/infrastructure/db/model/__init__.py +0 -0
  284. cancan_microstack/services/infrasrv/infrastructure/db/model/execution_log_tbl.py +53 -0
  285. cancan_microstack/services/infrasrv/infrastructure/db/model/node_instance_tbl.py +55 -0
  286. cancan_microstack/services/infrasrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
  287. cancan_microstack/services/infrasrv/infrastructure/db/model/service_config_tbl.py +30 -0
  288. cancan_microstack/services/infrasrv/infrastructure/db/model/service_info_tbl.py +59 -0
  289. cancan_microstack/services/infrasrv/infrastructure/db/model/service_instance_tbl.py +88 -0
  290. cancan_microstack/services/infrasrv/infrastructure/db/model/service_operation_tbl.py +73 -0
  291. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_tbl.py +55 -0
  292. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_version_tbl.py +43 -0
  293. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_engine_alert_tbl.py +57 -0
  294. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_run_tbl.py +56 -0
  295. cancan_microstack/services/infrasrv/infrastructure/db/operate/__init__.py +0 -0
  296. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_action_log_op.py +239 -0
  297. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config.py +80 -0
  298. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config_manager.py +198 -0
  299. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_info_op.py +297 -0
  300. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_instance_op.py +688 -0
  301. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_operation_op.py +387 -0
  302. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_registry.py +124 -0
  303. cancan_microstack/services/infrasrv/infrastructure/db/operate/workflow_op.py +804 -0
  304. cancan_microstack/services/infrasrv/infrastructure/ddl_manager.py +31 -0
  305. cancan_microstack/services/infrasrv/infrastructure/mongo/__init__.py +1 -0
  306. cancan_microstack/services/infrasrv/infrastructure/mongo/log_repository.py +129 -0
  307. cancan_microstack/services/infrasrv/interface/__init__.py +0 -0
  308. cancan_microstack/services/infrasrv/interface/api/__init__.py +0 -0
  309. cancan_microstack/services/infrasrv/interface/api/health_check_api.py +29 -0
  310. cancan_microstack/services/infrasrv/interface/api/hooks.py +284 -0
  311. cancan_microstack/services/infrasrv/interface/api/internal.py +49 -0
  312. cancan_microstack/services/infrasrv/interface/api/internal_instance_api.py +265 -0
  313. cancan_microstack/services/infrasrv/interface/api/internal_operation_api.py +206 -0
  314. cancan_microstack/services/infrasrv/interface/api/service_config.py +50 -0
  315. cancan_microstack/services/infrasrv/interface/api/service_logs_api.py +49 -0
  316. cancan_microstack/services/infrasrv/interface/api/service_management_api.py +113 -0
  317. cancan_microstack/services/infrasrv/interface/api/service_registry.py +117 -0
  318. cancan_microstack/services/infrasrv/interface/api/workflow_api.py +303 -0
  319. cancan_microstack/services/infrasrv/interface/schedule/__init__.py +0 -0
  320. cancan_microstack/services/infrasrv/interface/schedule/cleanup.py +13 -0
  321. cancan_microstack/services/infrasrv/interface/schedule/health_check.py +27 -0
  322. cancan_microstack/services/infrasrv/interface/schedule/log_cleanup.py +26 -0
  323. cancan_microstack/services/infrasrv/interface/schedule/operation_tracker.py +25 -0
  324. cancan_microstack/services/infrasrv/interface/schedule/scheduler.py +39 -0
  325. cancan_microstack/services/infrasrv/interface/schedule/workflow_scheduler.py +115 -0
  326. cancan_microstack/services/infrasrv/router.py +341 -0
  327. cancan_microstack/services/opsbffsrv/__init__.py +4 -0
  328. cancan_microstack/services/opsbffsrv/application/__init__.py +0 -0
  329. cancan_microstack/services/opsbffsrv/application/async_operation_app.py +150 -0
  330. cancan_microstack/services/opsbffsrv/application/auth_app.py +285 -0
  331. cancan_microstack/services/opsbffsrv/application/caddy/__init__.py +0 -0
  332. cancan_microstack/services/opsbffsrv/application/caddy/access_log_analysis_app.py +344 -0
  333. cancan_microstack/services/opsbffsrv/application/caddy/access_log_ingestion_service.py +169 -0
  334. cancan_microstack/services/opsbffsrv/application/caddy/certificate_management_app.py +355 -0
  335. cancan_microstack/services/opsbffsrv/application/caddy/rate_limit_management_app.py +496 -0
  336. cancan_microstack/services/opsbffsrv/application/caddy/route_management_app.py +401 -0
  337. cancan_microstack/services/opsbffsrv/application/caddy/stats_aggregation_app.py +364 -0
  338. cancan_microstack/services/opsbffsrv/application/db_admin_app.py +103 -0
  339. cancan_microstack/services/opsbffsrv/application/db_init_app.py +283 -0
  340. cancan_microstack/services/opsbffsrv/application/logging/__init__.py +1 -0
  341. cancan_microstack/services/opsbffsrv/application/logging/log_query_app.py +28 -0
  342. cancan_microstack/services/opsbffsrv/application/service_config.py +158 -0
  343. cancan_microstack/services/opsbffsrv/application/service_logs_app.py +74 -0
  344. cancan_microstack/services/opsbffsrv/application/service_registry.py +36 -0
  345. cancan_microstack/services/opsbffsrv/application/workflow_ops_app.py +730 -0
  346. cancan_microstack/services/opsbffsrv/conf/__init__.py +0 -0
  347. cancan_microstack/services/opsbffsrv/conf/config.py +224 -0
  348. cancan_microstack/services/opsbffsrv/domain/__init__.py +0 -0
  349. cancan_microstack/services/opsbffsrv/domain/auth/__init__.py +0 -0
  350. cancan_microstack/services/opsbffsrv/domain/auth/admin_init.py +38 -0
  351. cancan_microstack/services/opsbffsrv/domain/auth/auth_domain.py +108 -0
  352. cancan_microstack/services/opsbffsrv/domain/caddy/__init__.py +0 -0
  353. cancan_microstack/services/opsbffsrv/domain/caddy/access_log_analysis.py +358 -0
  354. cancan_microstack/services/opsbffsrv/domain/caddy/certificate_management.py +325 -0
  355. cancan_microstack/services/opsbffsrv/domain/caddy/default_routes.py +53 -0
  356. cancan_microstack/services/opsbffsrv/domain/caddy/rate_limit_management.py +308 -0
  357. cancan_microstack/services/opsbffsrv/domain/caddy/route_management.py +279 -0
  358. cancan_microstack/services/opsbffsrv/domain/caddy/stats_aggregation.py +654 -0
  359. cancan_microstack/services/opsbffsrv/domain/db_admin/__init__.py +0 -0
  360. cancan_microstack/services/opsbffsrv/domain/db_admin/db_admin_domain.py +118 -0
  361. cancan_microstack/services/opsbffsrv/domain/db_init/__init__.py +3 -0
  362. cancan_microstack/services/opsbffsrv/domain/db_init/db_init_domain.py +358 -0
  363. cancan_microstack/services/opsbffsrv/domain/logging/__init__.py +1 -0
  364. cancan_microstack/services/opsbffsrv/domain/logging/log_query_domain.py +99 -0
  365. cancan_microstack/services/opsbffsrv/domain/service_config/__init__.py +0 -0
  366. cancan_microstack/services/opsbffsrv/domain/service_config/service_config.py +81 -0
  367. cancan_microstack/services/opsbffsrv/domain/service_registry/__init__.py +0 -0
  368. cancan_microstack/services/opsbffsrv/domain/service_registry/service_registry.py +292 -0
  369. cancan_microstack/services/opsbffsrv/infrastructure/__init__.py +0 -0
  370. cancan_microstack/services/opsbffsrv/infrastructure/api/__init__.py +0 -0
  371. cancan_microstack/services/opsbffsrv/infrastructure/api/infrasrv_api.py +242 -0
  372. cancan_microstack/services/opsbffsrv/infrastructure/auth/__init__.py +0 -0
  373. cancan_microstack/services/opsbffsrv/infrastructure/auth/captcha_service.py +67 -0
  374. cancan_microstack/services/opsbffsrv/infrastructure/auth/password_service.py +12 -0
  375. cancan_microstack/services/opsbffsrv/infrastructure/auth/redis_store.py +131 -0
  376. cancan_microstack/services/opsbffsrv/infrastructure/auth/totp_service.py +59 -0
  377. cancan_microstack/services/opsbffsrv/infrastructure/caddy/__init__.py +0 -0
  378. cancan_microstack/services/opsbffsrv/infrastructure/caddy/access_log_parser.py +307 -0
  379. cancan_microstack/services/opsbffsrv/infrastructure/caddy/admin_api_client.py +678 -0
  380. cancan_microstack/services/opsbffsrv/infrastructure/caddy/ip_geo_locator.py +176 -0
  381. cancan_microstack/services/opsbffsrv/infrastructure/db/__init__.py +0 -0
  382. cancan_microstack/services/opsbffsrv/infrastructure/db/model/__init__.py +0 -0
  383. cancan_microstack/services/opsbffsrv/infrastructure/db/model/admin_user_tbl.py +33 -0
  384. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_access_log_tbl.py +90 -0
  385. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_certificate_tbl.py +65 -0
  386. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_rate_limit_tbl.py +69 -0
  387. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_route_tbl.py +66 -0
  388. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_stats_tbl.py +78 -0
  389. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
  390. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_config_tbl.py +30 -0
  391. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_info_tbl.py +51 -0
  392. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_instance_tbl.py +68 -0
  393. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/__init__.py +0 -0
  394. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/admin_user_operate.py +59 -0
  395. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_access_log.py +531 -0
  396. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_certificate.py +451 -0
  397. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_rate_limit.py +360 -0
  398. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_route.py +271 -0
  399. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_stats.py +343 -0
  400. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_action_log_op.py +57 -0
  401. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_config.py +86 -0
  402. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_info_op.py +79 -0
  403. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_instance.py +58 -0
  404. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_registry.py +138 -0
  405. cancan_microstack/services/opsbffsrv/infrastructure/ddl_manager.py +31 -0
  406. cancan_microstack/services/opsbffsrv/infrastructure/mongo/__init__.py +1 -0
  407. cancan_microstack/services/opsbffsrv/infrastructure/mongo/log_query_repository.py +87 -0
  408. cancan_microstack/services/opsbffsrv/interface/__init__.py +0 -0
  409. cancan_microstack/services/opsbffsrv/interface/api/__init__.py +0 -0
  410. cancan_microstack/services/opsbffsrv/interface/api/async_operation_api.py +137 -0
  411. cancan_microstack/services/opsbffsrv/interface/api/auth_api.py +113 -0
  412. cancan_microstack/services/opsbffsrv/interface/api/caddy/__init__.py +3 -0
  413. cancan_microstack/services/opsbffsrv/interface/api/caddy/access_log_api.py +174 -0
  414. cancan_microstack/services/opsbffsrv/interface/api/caddy/certificate_api.py +235 -0
  415. cancan_microstack/services/opsbffsrv/interface/api/caddy/rate_limit_api.py +302 -0
  416. cancan_microstack/services/opsbffsrv/interface/api/caddy/route_api.py +250 -0
  417. cancan_microstack/services/opsbffsrv/interface/api/caddy/stats_api.py +243 -0
  418. cancan_microstack/services/opsbffsrv/interface/api/db_admin_api.py +62 -0
  419. cancan_microstack/services/opsbffsrv/interface/api/db_init_api.py +109 -0
  420. cancan_microstack/services/opsbffsrv/interface/api/instance_management_api.py +165 -0
  421. cancan_microstack/services/opsbffsrv/interface/api/log_query_api.py +41 -0
  422. cancan_microstack/services/opsbffsrv/interface/api/mongo_express_proxy_api.py +181 -0
  423. cancan_microstack/services/opsbffsrv/interface/api/pgweb_proxy_api.py +154 -0
  424. cancan_microstack/services/opsbffsrv/interface/api/rabbitmq_mgmt_proxy_api.py +518 -0
  425. cancan_microstack/services/opsbffsrv/interface/api/redis_commander_proxy_api.py +133 -0
  426. cancan_microstack/services/opsbffsrv/interface/api/service_config.py +146 -0
  427. cancan_microstack/services/opsbffsrv/interface/api/service_logs_api.py +81 -0
  428. cancan_microstack/services/opsbffsrv/interface/api/service_registry.py +66 -0
  429. cancan_microstack/services/opsbffsrv/interface/api/workflow_ops_api.py +413 -0
  430. cancan_microstack/services/opsbffsrv/interface/middleware/__init__.py +0 -0
  431. cancan_microstack/services/opsbffsrv/interface/middleware/auth_middleware.py +52 -0
  432. cancan_microstack/services/opsbffsrv/router.py +901 -0
  433. cancan_microstack/utils/__init__.py +1 -0
  434. cancan_microstack/utils/container_env.py +218 -0
  435. cancan_microstack-0.0.1.dist-info/METADATA +155 -0
  436. cancan_microstack-0.0.1.dist-info/RECORD +440 -0
  437. cancan_microstack-0.0.1.dist-info/WHEEL +5 -0
  438. cancan_microstack-0.0.1.dist-info/entry_points.txt +2 -0
  439. cancan_microstack-0.0.1.dist-info/licenses/LICENSE +21 -0
  440. cancan_microstack-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,509 @@
1
+ import re
2
+ from typing import (
3
+ Any,
4
+ Dict,
5
+ List,
6
+ Optional,
7
+ )
8
+ from datetime import (
9
+ datetime,
10
+ timedelta,
11
+ timezone,
12
+ )
13
+
14
+ from linglong_web.utils import logger
15
+ from linglong_web import (
16
+ HTTPClientConfig,
17
+ http_client,
18
+ )
19
+ from linglong_web import LinglongConfig
20
+ from cancan_microstack.public.schemas.infra.service_registry import ServiceRegistryCreate
21
+ from cancan_microstack.public.schemas.infra.service_instance import ServiceInstance
22
+ from cancan_microstack.public.const.health_consts import HealthOverallStatus
23
+ from cancan_microstack.public.const.service_consts import PushStatus
24
+ from cancan_microstack.public.schemas.infra.status_types import InstanceStatus
25
+ from cancan_microstack.public.schemas.infra.push import PushResult, PushDetail
26
+ from cancan_microstack.public.const.action_consts import ActionType
27
+ from cancan_microstack.public.const.operation_consts import OperationStatus, InitiatedBy
28
+ from cancan_microstack.public.schemas.infra.overview import ServiceOverview
29
+ from cancan_microstack.public.schemas.infra.cleanup import CleanupResult, CleanupDetail
30
+ from cancan_microstack.services.infrasrv.infrastructure.db.operate.service_registry import (
31
+ upsert_service_metadata,
32
+ list_service_names,
33
+ )
34
+ from cancan_microstack.services.infrasrv.infrastructure.db.operate.service_config import (
35
+ get_service_config,
36
+ )
37
+ from cancan_microstack.services.infrasrv.infrastructure.db.operate.service_action_log_op import (
38
+ insert_service_action_log,
39
+ )
40
+ from cancan_microstack.services.infrasrv.infrastructure.db.operate.service_instance_op import (
41
+ get_instance_by_id,
42
+ list_instances_by_service,
43
+ get_all_instances as list_all_instances,
44
+ upsert_instance,
45
+ soft_delete_instance,
46
+ mark_instance_status,
47
+ hard_delete_instances_by_ids,
48
+ )
49
+
50
+
51
+ class ServiceRegistry:
52
+ """服务注册发现域"""
53
+
54
+ _INVALID_HOSTS = {"unknown", "localhost", "127.0.0.1", "0.0.0.0"}
55
+ _CONTAINER_ID_PATTERN = re.compile(r"^(?:[0-9a-f]{12}|[0-9a-f]{64})$", re.IGNORECASE)
56
+
57
+ # 健康检查配置常量
58
+ # Note: use HealthCheckDomain for multi-instance checks
59
+
60
+ async def register(self, service: ServiceRegistryCreate) -> None:
61
+ """
62
+ 注册服务实例
63
+
64
+ 验证规则:
65
+ 1. host 不能为 unknown(通常是 Docker 容器hostname 未正确设置)
66
+ 2. host 不能为空或纯空格
67
+ 3. 拒绝明显无效的服务名(infrasrv 等特殊服务)
68
+ """
69
+ normalized_host = self._normalize_instance_host(service)
70
+
71
+ # 验证服务名
72
+ if service.service_name in ("infrasrv", "controllersrv"):
73
+ logger.warning(f"Reject registration: special service '{service.service_name}' should not register itself")
74
+ raise ValueError(f"Special service '{service.service_name}' should not register")
75
+
76
+ logger.info(
77
+ "Registering service metadata and instance: %s (%s) @ %s",
78
+ service.service_name,
79
+ service.instance_id,
80
+ normalized_host,
81
+ )
82
+
83
+ await upsert_service_metadata(service.to_service_metadata())
84
+ await upsert_instance(self._build_instance_payload(service, normalized_host))
85
+
86
+ @staticmethod
87
+ def _is_local_dev_instance(service: ServiceRegistryCreate) -> bool:
88
+ """
89
+ 判断实例是否来自容器外本地环境
90
+ Determine whether the instance originates from out-of-pod local dev.
91
+ """
92
+ service_meta = service.service_metadata or {}
93
+ instance_meta = service.instance_metadata or {}
94
+ return bool(service_meta.get("is_local_dev") or instance_meta.get("is_local_dev"))
95
+
96
+ @classmethod
97
+ def _looks_like_container_hostname(cls, host: str) -> bool:
98
+ """
99
+ 检测 host 是否为容器 ID
100
+ Detect whether the host string is a container identifier.
101
+ """
102
+ return bool(cls._CONTAINER_ID_PATTERN.fullmatch(host.strip()))
103
+
104
+ @staticmethod
105
+ def _fallback_host_alias(service: ServiceRegistryCreate) -> Optional[str]:
106
+ """
107
+ 生成可回退的网络别名(优先使用 compose/metadata 提供的值)
108
+ Build the fallback alias (compose alias > metadata > service name).
109
+ """
110
+ instance_meta = service.instance_metadata or {}
111
+ candidates = [
112
+ instance_meta.get("network_alias"),
113
+ service.compose_service_name,
114
+ f"{service.service_name}.service",
115
+ ]
116
+ for candidate in candidates:
117
+ if candidate:
118
+ return candidate
119
+ return None
120
+
121
+ def _normalize_instance_host(self, service: ServiceRegistryCreate) -> str:
122
+ """
123
+ 归一化实例 host,确保 infrasrv 可以回连
124
+ Normalize the instance host so infrasrv can reach the service.
125
+ """
126
+ raw_host = (service.host or "").strip()
127
+ is_local_dev = self._is_local_dev_instance(service)
128
+
129
+ if not raw_host:
130
+ fallback = self._fallback_host_alias(service)
131
+ if fallback:
132
+ logger.warning(
133
+ "Host missing for %s:%s, falling back to alias '%s'",
134
+ service.service_name,
135
+ service.instance_id,
136
+ fallback,
137
+ )
138
+ return fallback
139
+ raise ValueError("Invalid host: host cannot be empty")
140
+
141
+ lowered = raw_host.lower()
142
+ if lowered in self._INVALID_HOSTS:
143
+ if lowered == "127.0.0.1" and is_local_dev:
144
+ return raw_host
145
+ fallback = self._fallback_host_alias(service)
146
+ if fallback:
147
+ logger.info(
148
+ "Replacing invalid host '%s' with alias '%s' for %s:%s",
149
+ raw_host,
150
+ fallback,
151
+ service.service_name,
152
+ service.instance_id,
153
+ )
154
+ return fallback
155
+ raise ValueError(
156
+ f"Invalid host: '{raw_host}' is not routable. Configure SERVICE_NETWORK_ALIAS or hostname."
157
+ )
158
+
159
+ if self._looks_like_container_hostname(raw_host):
160
+ fallback = self._fallback_host_alias(service)
161
+ if fallback:
162
+ logger.info(
163
+ "Replacing container hostname '%s' with alias '%s' for %s:%s",
164
+ raw_host,
165
+ fallback,
166
+ service.service_name,
167
+ service.instance_id,
168
+ )
169
+ return fallback
170
+ logger.warning(
171
+ "Host '%s' looks like a container ID but no alias found for %s:%s",
172
+ raw_host,
173
+ service.service_name,
174
+ service.instance_id,
175
+ )
176
+
177
+ return raw_host
178
+
179
+ def _build_instance_payload(self, service: ServiceRegistryCreate, normalized_host: str):
180
+ """
181
+ 构造用于 upsert 的实例载荷,同时保存原始 host 信息
182
+ Build the instance payload for persistence and keep host provenance.
183
+ """
184
+ payload = service.to_instance_payload()
185
+ metadata = dict(payload.instance_metadata or {})
186
+ metadata.setdefault("resolved_host", normalized_host)
187
+ if service.host != normalized_host:
188
+ metadata["reported_host"] = service.host
189
+ return payload.model_copy(update={
190
+ "host": normalized_host,
191
+ "instance_metadata": metadata,
192
+ })
193
+
194
+ async def deregister(self, service_name: str, instance_id: str) -> None:
195
+ """注销服务实例"""
196
+ logger.info(f"Deregistering service: {service_name}, instance: {instance_id}")
197
+ await mark_instance_status(service_name, instance_id, InstanceStatus.DOWN)
198
+ await soft_delete_instance(service_name, instance_id)
199
+
200
+ async def get_instances(self, service_name: str, only_healthy: bool = True) -> List[ServiceInstance]:
201
+ """获取服务实例列表"""
202
+ instances = await list_instances_by_service(service_name)
203
+ if only_healthy:
204
+ return [inst for inst in instances if inst.status == InstanceStatus.UP]
205
+ return instances
206
+
207
+ async def get_all_instances(self) -> List[ServiceInstance]:
208
+ """获取所有服务实例"""
209
+ return await list_all_instances()
210
+
211
+ async def get_instance(self, service_name: str, instance_id: str) -> Optional[ServiceInstance]:
212
+ """获取指定服务实例"""
213
+ instance = await get_instance_by_id(instance_id)
214
+ if instance and instance.service_name != service_name:
215
+ return None
216
+ return instance
217
+
218
+ async def push_config_to_service(self, service_name: str) -> Dict[str, Any]:
219
+ """向服务推送配置"""
220
+ logger.info(f"Pushing config to service: {service_name}")
221
+
222
+ # 获取服务配置
223
+ config_dict = {}
224
+ configs = await get_service_config(service_name)
225
+ if configs:
226
+ config_dict = {c.conf_key: c.conf_value for c in configs}
227
+
228
+ # 获取健康的服务实例
229
+ instances = await list_instances_by_service(service_name)
230
+ instances = [inst for inst in instances if inst.status == InstanceStatus.UP]
231
+
232
+ push_results = PushResult(service_name=service_name, total_instances=len(instances))
233
+
234
+ for instance in instances:
235
+ try:
236
+ # 确定推送配置使用的host
237
+ is_local_dev = False
238
+ if instance.instance_metadata:
239
+ is_local_dev = instance.instance_metadata.get("is_local_dev", False)
240
+
241
+ push_host = "127.0.0.1" if is_local_dev else instance.host
242
+
243
+ url = f"http://{push_host}:{instance.port}/internal/config/update"
244
+
245
+ resp = await http_client.post(url, json={"config": config_dict},
246
+ timeout=HTTPClientConfig.INTERNAL_SERVICE_TIMEOUT)
247
+
248
+ if resp and resp.status == 200:
249
+ push_results.success += 1
250
+ push_results.details.append(
251
+ PushDetail(
252
+ instance_id=instance.instance_id,
253
+ host=instance.host,
254
+ port=instance.port,
255
+ status=PushStatus.SUCCESS,
256
+ )
257
+ )
258
+ else:
259
+ push_results.failed += 1
260
+ push_results.details.append(
261
+ PushDetail(
262
+ instance_id=instance.instance_id,
263
+ host=instance.host,
264
+ port=instance.port,
265
+ status=PushStatus.FAILED,
266
+ error=f"HTTP {resp.status if resp else 'None'}",
267
+ )
268
+ )
269
+ # 推送配置失败,增加失败计数(不立即标记为DOWN)
270
+ logger.warning(
271
+ f"Failed to push config to {instance.service_name}:{instance.instance_id}, "
272
+ f"will be caught in next health check"
273
+ )
274
+ except Exception as e:
275
+ push_results.failed += 1
276
+ push_results.details.append(
277
+ PushDetail(
278
+ instance_id=instance.instance_id,
279
+ host=instance.host,
280
+ port=instance.port,
281
+ status=PushStatus.FAILED,
282
+ error=str(e),
283
+ )
284
+ )
285
+ logger.error(f"Failed to push config to {instance.instance_id}: {e}")
286
+
287
+ logger.info(f"Config push completed: {push_results.success} success, {push_results.failed} failed")
288
+ return push_results.model_dump()
289
+
290
+ async def get_all_service_names(self) -> List[str]:
291
+ return await list_service_names()
292
+
293
+ async def get_services_overview(self) -> List[Dict[str, Any]]:
294
+ """获取所有服务的概览信息(服务名、状态统计)"""
295
+ all_instances = await list_all_instances()
296
+
297
+ # 使用结构化模型返回服务概览
298
+ overview_map: Dict[str, ServiceOverview] = {}
299
+
300
+ for instance in all_instances:
301
+ service_name = instance.service_name
302
+ if service_name not in overview_map:
303
+ overview_map[service_name] = ServiceOverview(
304
+ service_name=service_name,
305
+ total_instances=0,
306
+ healthy_instances=0,
307
+ unhealthy_instances=0,
308
+ overall_status=HealthOverallStatus.UP,
309
+ )
310
+
311
+ ov = overview_map[service_name]
312
+ ov.total_instances += 1
313
+ # 尝试将实例状态转换为枚举以便比较,如果失败则回退为原始字符串
314
+ try:
315
+ inst_status = InstanceStatus(instance.status)
316
+ except Exception:
317
+ inst_status = instance.status
318
+
319
+ if inst_status == InstanceStatus.UP:
320
+ ov.healthy_instances += 1
321
+ else:
322
+ ov.unhealthy_instances += 1
323
+
324
+ # 计算整体状态
325
+ for service_name, ov in overview_map.items():
326
+ if ov.healthy_instances == 0:
327
+ ov.overall_status = HealthOverallStatus.DOWN
328
+ elif ov.unhealthy_instances > 0:
329
+ ov.overall_status = HealthOverallStatus.PARTIAL
330
+ else:
331
+ ov.overall_status = HealthOverallStatus.UP
332
+
333
+ return [ov.model_dump() for ov in overview_map.values()]
334
+
335
+ async def cleanup_dead_instances(self) -> Dict[str, Any]:
336
+ """
337
+ 清理僵尸和已下线的服务实例
338
+ Cleanup zombie and downed service instances.
339
+
340
+ 执行两个阶段的清理:
341
+ 1. **标记僵尸实例**:将心跳超时的 `UP` 状态实例标记为 `DOWN` (软删除)。
342
+ 2. **清理下线实例**:物理删除状态为 `DOWN` 且超过清理周期的实例。
343
+ """
344
+ logger.info("Starting cleanup/health-check of service instances...")
345
+ all_instances = await list_all_instances()
346
+
347
+ timeout_seconds = LinglongConfig.INSTANCE_HEARTBEAT_TIMEOUT_SECONDS
348
+ cleanup_threshold = timedelta(seconds=timeout_seconds)
349
+ current_time = datetime.now(timezone.utc)
350
+
351
+ instances_to_soft_delete = []
352
+ instances_to_hard_delete = []
353
+ kept_count = 0
354
+
355
+ for instance in all_instances:
356
+ # --- 阶段1: 识别僵尸实例 ---
357
+ if instance.status == InstanceStatus.UP:
358
+ is_stale = False
359
+ last_heartbeat = instance.last_heartbeat
360
+ if last_heartbeat:
361
+ if last_heartbeat.tzinfo is None:
362
+ last_heartbeat = last_heartbeat.replace(tzinfo=timezone.utc)
363
+ if (current_time - last_heartbeat) > cleanup_threshold:
364
+ is_stale = True
365
+ else:
366
+ created_time = instance.created_time
367
+ if created_time:
368
+ if created_time.tzinfo is None:
369
+ created_time = created_time.replace(tzinfo=timezone.utc)
370
+ if (current_time - created_time) > cleanup_threshold:
371
+ is_stale = True
372
+
373
+ if is_stale:
374
+ instances_to_soft_delete.append(instance)
375
+ else:
376
+ kept_count += 1
377
+
378
+ # --- 阶段2: 识别需要物理删除的实例 ---
379
+ elif instance.status == InstanceStatus.DOWN:
380
+ update_time = instance.update_time
381
+ if update_time:
382
+ if update_time.tzinfo is None:
383
+ update_time = update_time.replace(tzinfo=timezone.utc)
384
+ if (current_time - update_time) > cleanup_threshold:
385
+ instances_to_hard_delete.append(instance)
386
+ else:
387
+ kept_count += 1
388
+ else:
389
+ # 如果没有更新时间,默认保留
390
+ kept_count += 1
391
+ else:
392
+ kept_count += 1
393
+
394
+ # --- 执行数据库操作 ---
395
+ cleanup_results = CleanupResult(
396
+ total_checked=len(all_instances),
397
+ kept=kept_count
398
+ )
399
+
400
+ # 执行软删除
401
+ for instance in instances_to_soft_delete:
402
+ try:
403
+ await soft_delete_instance(instance.service_name, instance.instance_id)
404
+ cleanup_results.cleaned += 1
405
+ cleanup_results.details.append(CleanupDetail(
406
+ service_name=instance.service_name,
407
+ instance_id=instance.instance_id,
408
+ action="soft_deleted",
409
+ reason="Stale heartbeat",
410
+ ))
411
+ logger.info(f"Soft deleted stale instance: {instance.service_name}:{instance.instance_id}")
412
+ except Exception as e:
413
+ logger.error(f"Failed to soft-delete instance {instance.instance_id}: {e}")
414
+
415
+ # 执行物理删除
416
+ if instances_to_hard_delete:
417
+ instance_ids_to_delete = [inst.instance_id for inst in instances_to_hard_delete]
418
+ try:
419
+ deleted_count = await hard_delete_instances_by_ids(instance_ids_to_delete)
420
+ cleanup_results.cleaned += deleted_count
421
+ for inst in instances_to_hard_delete:
422
+ cleanup_results.details.append(CleanupDetail(
423
+ service_name=inst.service_name,
424
+ instance_id=inst.instance_id,
425
+ action="hard_deleted",
426
+ reason="Downed instance expired",
427
+ ))
428
+ logger.info(f"Hard deleted {deleted_count} expired downed instances.")
429
+ except Exception as e:
430
+ logger.error(f"Failed to hard-delete instances: {e}")
431
+
432
+ logger.info(
433
+ f"Health check completed: {cleanup_results.cleaned} instances cleaned, "
434
+ f"{cleanup_results.kept} instances kept."
435
+ )
436
+ return cleanup_results.model_dump()
437
+
438
+ async def _auto_restart_service(self, service_name: str, instance_id: str):
439
+ """
440
+ 自动重启失败的服务
441
+
442
+ Args:
443
+ service_name: 服务名称
444
+ instance_id: 实例ID
445
+ """
446
+ try:
447
+ # 记录日志:准备重启
448
+ logger.info(f"Auto-restarting service {service_name}:{instance_id} via controllersrv")
449
+
450
+ # 记录行为日志
451
+ await insert_service_action_log(
452
+ service_name=service_name,
453
+ action_type=ActionType.AUTO_RESTART,
454
+ action_status=OperationStatus.PENDING,
455
+ triggered_by=InitiatedBy.INFRASRV,
456
+ action_metadata={"instance_id": instance_id, "reason": "health_check_failure"}
457
+ )
458
+
459
+ # 调用 controllersrv 重启服务
460
+ controllersrv_url = f"{LinglongConfig.CONTROLLERSRV_HOST}/v1/controllersrv/service/restart"
461
+ resp = await http_client.post(
462
+ url=controllersrv_url,
463
+ json={"service_names": [service_name]},
464
+ timeout=HTTPClientConfig.INTERNAL_SERVICE_TIMEOUT
465
+ )
466
+
467
+ if resp and resp.status == 200:
468
+ data = await resp.json()
469
+ if data.get("success"):
470
+ logger.info(f"Successfully triggered restart for service {service_name}")
471
+ await insert_service_action_log(
472
+ service_name=service_name,
473
+ action_type=ActionType.AUTO_RESTART,
474
+ action_status=OperationStatus.SUCCESS,
475
+ triggered_by=InitiatedBy.INFRASRV,
476
+ action_metadata={"instance_id": instance_id, "controllersrv_response": data}
477
+ )
478
+ else:
479
+ error_msg = data.get("error", {}).get("msg", "Unknown error")
480
+ logger.error(f"Failed to restart service {service_name}: {error_msg}")
481
+ await insert_service_action_log(
482
+ service_name=service_name,
483
+ action_type=ActionType.AUTO_RESTART,
484
+ action_status=OperationStatus.FAILED,
485
+ triggered_by=InitiatedBy.INFRASRV,
486
+ error_message=error_msg,
487
+ action_metadata={"instance_id": instance_id}
488
+ )
489
+ else:
490
+ error_msg = f"HTTP error: {resp.status if resp else 'no response'}"
491
+ logger.error(f"Failed to call controllersrv for {service_name}: {error_msg}")
492
+ await insert_service_action_log(
493
+ service_name=service_name,
494
+ action_type=ActionType.AUTO_RESTART,
495
+ action_status=OperationStatus.FAILED,
496
+ triggered_by=InitiatedBy.INFRASRV,
497
+ error_message=error_msg,
498
+ action_metadata={"instance_id": instance_id}
499
+ )
500
+ except Exception as e:
501
+ logger.error(f"Error auto-restarting service {service_name}: {e}", exc_info=True)
502
+ await insert_service_action_log(
503
+ service_name=service_name,
504
+ action_type=ActionType.AUTO_RESTART,
505
+ action_status=OperationStatus.FAILED,
506
+ triggered_by=InitiatedBy.INFRASRV,
507
+ error_message=str(e),
508
+ action_metadata={"instance_id": instance_id}
509
+ )
@@ -0,0 +1,50 @@
1
+ from cancan_microstack.services.infrasrv.infrastructure.db.operate.service_config import (
2
+ insert_service_config,
3
+ get_service_config,
4
+ update_service_config,
5
+ get_all_service_configs as db_get_all_service_configs,
6
+ delete_service_config as db_delete_service_config,
7
+ )
8
+ from cancan_microstack.public.schemas.infra.service_config import ServiceConfig as ServiceConfigSchema
9
+
10
+
11
+ class ServiceConfig:
12
+
13
+ async def get_service_config(self, service_name: str) -> dict:
14
+ confs = await get_service_config(service_name)
15
+ if not confs:
16
+ return {}
17
+ return {c.conf_key: c.conf_value for c in confs}
18
+
19
+ async def insert_service_config(self, service_name: str, conf_dict: dict) -> None:
20
+ confs = [ServiceConfigSchema(
21
+ service_name=service_name,
22
+ conf_key=k,
23
+ conf_value=v
24
+ ) for k, v in conf_dict.items()]
25
+ await insert_service_config(confs)
26
+
27
+ async def update_service_config(self, service_name: str, conf_dict: dict) -> None:
28
+ confs = [ServiceConfigSchema(
29
+ service_name=service_name,
30
+ conf_key=k,
31
+ conf_value=v
32
+ ) for k, v in conf_dict.items()]
33
+ await update_service_config(confs)
34
+
35
+ async def get_all_service_configs(self) -> dict:
36
+ """获取所有服务的配置"""
37
+ all_confs = await db_get_all_service_configs()
38
+
39
+ # 按服务名分组
40
+ result = {}
41
+ for conf in all_confs:
42
+ if conf.service_name not in result:
43
+ result[conf.service_name] = {}
44
+ result[conf.service_name][conf.conf_key] = conf.conf_value
45
+
46
+ return result
47
+
48
+ async def delete_service_config(self, service_name: str, conf_key: str) -> None:
49
+ """删除服务配置项"""
50
+ await db_delete_service_config(service_name, conf_key)
@@ -0,0 +1,51 @@
1
+ """
2
+ 服务行为日志领域层
3
+ """
4
+ from typing import (
5
+ List,
6
+ Optional,
7
+ )
8
+
9
+ from linglong_web.utils import logger
10
+ from cancan_microstack.public.schemas.infra.service_action_log import ServiceActionLog
11
+ from cancan_microstack.services.infrasrv.infrastructure.db.operate.service_action_log_op import (
12
+ query_service_action_logs,
13
+ )
14
+
15
+
16
+ class ServiceLogsDomain:
17
+ """服务日志领域层:处理日志查询业务逻辑"""
18
+
19
+ async def get_service_action_logs(
20
+ self,
21
+ service_name: Optional[str] = None,
22
+ action_type: Optional[str] = None,
23
+ action_status: Optional[str] = None,
24
+ limit: int = 100
25
+ ) -> List[ServiceActionLog]:
26
+ """
27
+ 查询服务行为日志
28
+
29
+ Args:
30
+ service_name: 服务名称(可选)
31
+ action_type: 操作类型(可选)
32
+ action_status: 操作状态(可选)
33
+ limit: 返回数量限制
34
+
35
+ Returns:
36
+ 服务行为日志列表
37
+ """
38
+ logger.info(
39
+ f"ServiceLogsDomain: querying logs - service_name={service_name}, "
40
+ f"action_type={action_type}, action_status={action_status}, limit={limit}"
41
+ )
42
+
43
+ # 调用基础设施层查询数据
44
+ logs = await query_service_action_logs(
45
+ service_name=service_name,
46
+ action_type=action_type,
47
+ action_status=action_status,
48
+ limit=limit
49
+ )
50
+
51
+ return logs
@@ -0,0 +1,4 @@
1
+ """
2
+ 工作流领域服务模块
3
+ Workflow domain service module
4
+ """