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.
- cancan_microstack/__init__.py +14 -0
- cancan_microstack/__version__.py +10 -0
- cancan_microstack/assets/__init__.py +6 -0
- cancan_microstack/assets/builds/caddy/Caddyfile +187 -0
- cancan_microstack/assets/builds/caddy/DEPLOYMENT.md +303 -0
- cancan_microstack/assets/builds/caddy/Dockerfile +46 -0
- cancan_microstack/assets/builds/caddy/README.md +343 -0
- cancan_microstack/assets/builds/caddy/geoip/README.md +5 -0
- cancan_microstack/assets/builds/caddy/start.sh +78 -0
- cancan_microstack/assets/builds/caddy/waf/coraza.conf +179 -0
- cancan_microstack/assets/builds/service/Dockerfile +59 -0
- cancan_microstack/assets/builds/service/README.md +13 -0
- cancan_microstack/assets/ddl/create_db.sql +22 -0
- cancan_microstack/assets/ddl/infra/execution_log_tbl.sql +46 -0
- cancan_microstack/assets/ddl/infra/node_instance_tbl.sql +56 -0
- cancan_microstack/assets/ddl/infra/service_action_log_tbl.sql +36 -0
- cancan_microstack/assets/ddl/infra/service_config_tbl.sql +26 -0
- cancan_microstack/assets/ddl/infra/service_info_tbl.sql +45 -0
- cancan_microstack/assets/ddl/infra/service_instance_tbl.sql +54 -0
- cancan_microstack/assets/ddl/infra/service_operation_tbl.sql +47 -0
- cancan_microstack/assets/ddl/infra/workflow_definition_tbl.sql +60 -0
- cancan_microstack/assets/ddl/infra/workflow_definition_version_tbl.sql +35 -0
- cancan_microstack/assets/ddl/infra/workflow_engine_alert_tbl.sql +34 -0
- cancan_microstack/assets/ddl/infra/workflow_run_tbl.sql +52 -0
- cancan_microstack/assets/ddl/ops/admin_user_tbl.sql +34 -0
- cancan_microstack/assets/ddl/ops/caddy_access_log_tbl.sql +91 -0
- cancan_microstack/assets/ddl/ops/caddy_certificate_tbl.sql +59 -0
- cancan_microstack/assets/ddl/ops/caddy_rate_limit_tbl.sql +64 -0
- cancan_microstack/assets/ddl/ops/caddy_route_tbl.sql +63 -0
- cancan_microstack/assets/ddl/ops/caddy_stats_tbl.sql +77 -0
- cancan_microstack/assets/ddl/trigger.sql +21 -0
- cancan_microstack/assets/docker/docker-compose.infra.yml +401 -0
- cancan_microstack/assets/scripts/README.md +195 -0
- cancan_microstack/assets/scripts/docker/build_images.sh +44 -0
- cancan_microstack/assets/scripts/docker/force_rebuild_images.sh +38 -0
- cancan_microstack/assets/scripts/docker/rebuild_all.sh +34 -0
- cancan_microstack/assets/scripts/docker/rebuild_compose.sh +61 -0
- cancan_microstack/assets/scripts/docker/restart.sh +35 -0
- cancan_microstack/assets/scripts/docker/restart_compose.sh +35 -0
- cancan_microstack/assets/scripts/docker/start.sh +78 -0
- cancan_microstack/assets/scripts/docker/start_all.sh +46 -0
- cancan_microstack/assets/scripts/docker/start_compose.sh +66 -0
- cancan_microstack/assets/scripts/docker/stop.sh +67 -0
- cancan_microstack/assets/scripts/docker/stop_all.sh +38 -0
- cancan_microstack/assets/scripts/docker/stop_compose.sh +38 -0
- cancan_microstack/assets/scripts/podman/build_images_podman.sh +59 -0
- cancan_microstack/assets/scripts/podman/cleanup_podman.sh +25 -0
- cancan_microstack/assets/scripts/podman/force_rebuild_images_podman.sh +56 -0
- cancan_microstack/assets/scripts/podman/rebuild_all_podman.sh +37 -0
- cancan_microstack/assets/scripts/podman/rebuild_compose_podman.sh +60 -0
- cancan_microstack/assets/scripts/podman/restart_compose_podman.sh +73 -0
- cancan_microstack/assets/scripts/podman/start_all_podman.sh +66 -0
- cancan_microstack/assets/scripts/podman/start_compose_podman.sh +80 -0
- cancan_microstack/assets/scripts/podman/start_podman.sh +91 -0
- cancan_microstack/assets/scripts/podman/stop.sh +73 -0
- cancan_microstack/assets/scripts/podman/stop_all_podman.sh +34 -0
- cancan_microstack/assets/scripts/podman/stop_compose_podman.sh +58 -0
- cancan_microstack/assets/scripts/start_controllersrv.sh +9 -0
- cancan_microstack/assets/scripts/utils/check_all_db_tables.sh +104 -0
- cancan_microstack/assets/scripts/utils/check_env.sh +177 -0
- cancan_microstack/assets/scripts/utils/check_service_management_deployment.sh +225 -0
- cancan_microstack/assets/scripts/utils/deploy_service_management.sh +176 -0
- cancan_microstack/assets/scripts/utils/force_reload_infrasrv.sh +52 -0
- cancan_microstack/assets/scripts/utils/monitor_service_management.sh +187 -0
- cancan_microstack/assets/scripts/utils/reset_postgres_volume.sh +68 -0
- cancan_microstack/assets/scripts/utils/test_async_operations.sh +141 -0
- cancan_microstack/assets/scripts/utils/verify_real_operations.sh +76 -0
- cancan_microstack/assets/service/Dockerfile +65 -0
- cancan_microstack/assets/www/adminops/assets/AppEmpty.vue_vue_type_script_setup_true_lang-BOKUurnM.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ConfigManage-DKV5YOUz.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ConfigManage-Y5bhy7wG.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ConsoleManage-8ljYvCW2.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ConsoleManage-BWpyqbuQ.css +1 -0
- cancan_microstack/assets/www/adminops/assets/DashboardNew-B9Nf1OPl.js +1 -0
- cancan_microstack/assets/www/adminops/assets/DashboardNew-DYWZKQ1V.css +1 -0
- cancan_microstack/assets/www/adminops/assets/LogSearch-CA0Jhe78.js +1 -0
- cancan_microstack/assets/www/adminops/assets/LogSearch-CCZfTNPF.css +1 -0
- cancan_microstack/assets/www/adminops/assets/LoginView-BId3kP3M.css +1 -0
- cancan_microstack/assets/www/adminops/assets/LoginView-BQZTV_Qy.js +1 -0
- cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-BdEYwqFq.js +1 -0
- cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-D-pASR8G.css +1 -0
- cancan_microstack/assets/www/adminops/assets/PageContainer-Byss-yUC.js +1 -0
- cancan_microstack/assets/www/adminops/assets/PageContainer-C3nSZwM7.css +1 -0
- cancan_microstack/assets/www/adminops/assets/RateLimitManage-BDI8jLpC.css +1 -0
- cancan_microstack/assets/www/adminops/assets/RateLimitManage-DJY4NiF-.js +1 -0
- cancan_microstack/assets/www/adminops/assets/RouteManage-DaUQ4QLw.css +1 -0
- cancan_microstack/assets/www/adminops/assets/RouteManage-w9XCU0UA.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceCard-BFzHe6Tw.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceCard-BJUhWnA-.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceDetail-Cw24WuKp.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceDetail-Yum47zdB.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceList-C7ryvbhE.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceList-Cgd01fUx.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceLogs-COpG9H0h.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceLogs-H_Alq0cf.css +1 -0
- cancan_microstack/assets/www/adminops/assets/StatsOverview-D0TwMQkA.js +39 -0
- cancan_microstack/assets/www/adminops/assets/StatsOverview-lqAN6pqM.css +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpBindView-CWlAmzFt.js +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpBindView-HoQC1lhx.css +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpVerifyView-BHN1VtX1.css +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpVerifyView-D3w_lZk8.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowCenter-DU_mpIA0.css +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowCenter-i50rZyxN.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-CnHokPL9.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-DaZaZpLd.css +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowRuns-B09hK48c.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowRuns-wGutKIIU.css +1 -0
- cancan_microstack/assets/www/adminops/assets/caddy-nnCKf8fG.js +1 -0
- cancan_microstack/assets/www/adminops/assets/format-Cuzxgna9.js +1 -0
- cancan_microstack/assets/www/adminops/assets/index-CiFlm8oc.js +64 -0
- cancan_microstack/assets/www/adminops/assets/index-UW0T1Dkc.css +1 -0
- cancan_microstack/assets/www/adminops/assets/service-BYlgGPs_.js +1 -0
- cancan_microstack/assets/www/adminops/assets/service-operation-6GzLw2Z1.js +1 -0
- cancan_microstack/assets/www/adminops/assets/style-CcIXnQ5y.css +1 -0
- cancan_microstack/assets/www/adminops/assets/style-lRnStdGu.js +39 -0
- cancan_microstack/assets/www/adminops/assets/useDebounce-BRlqfXqf.js +1 -0
- cancan_microstack/assets/www/adminops/assets/workflow-CUXs39Ac.js +1 -0
- cancan_microstack/assets/www/adminops/index.html +16 -0
- cancan_microstack/assets/www/adminops/vite.svg +1 -0
- cancan_microstack/cli/__init__.py +14 -0
- cancan_microstack/cli/__main__.py +9 -0
- cancan_microstack/cli/main.py +552 -0
- cancan_microstack/cmd/__init__.py +54 -0
- cancan_microstack/cmd/cancan/__init__.py +12 -0
- cancan_microstack/cmd/cancan/run.py +395 -0
- cancan_microstack/cmd/controllersrv/__init__.py +0 -0
- cancan_microstack/cmd/controllersrv/run.py +131 -0
- cancan_microstack/cmd/infrasrv/__init__.py +5 -0
- cancan_microstack/cmd/infrasrv/run.py +100 -0
- cancan_microstack/cmd/opsbffsrv/__init__.py +5 -0
- cancan_microstack/cmd/opsbffsrv/run.py +96 -0
- cancan_microstack/core/__init__.py +5 -0
- cancan_microstack/core/assets.py +123 -0
- cancan_microstack/core/compose_builder.py +102 -0
- cancan_microstack/core/doctor.py +152 -0
- cancan_microstack/core/microstack.py +71 -0
- cancan_microstack/core/runner.py +56 -0
- cancan_microstack/core/stack_manager.py +186 -0
- cancan_microstack/public/__init__.py +7 -0
- cancan_microstack/public/api/__init__.py +1 -0
- cancan_microstack/public/api/controllersrv_client.py +277 -0
- cancan_microstack/public/api/infrasrv_client.py +404 -0
- cancan_microstack/public/const/__init__.py +1 -0
- cancan_microstack/public/const/action_consts.py +18 -0
- cancan_microstack/public/const/app_consts.py +42 -0
- cancan_microstack/public/const/caddy_consts.py +22 -0
- cancan_microstack/public/const/controllersrv_consts.py +163 -0
- cancan_microstack/public/const/docker_consts.py +15 -0
- cancan_microstack/public/const/error.py +56 -0
- cancan_microstack/public/const/health_consts.py +52 -0
- cancan_microstack/public/const/hook_enums.py +56 -0
- cancan_microstack/public/const/logging_enums.py +13 -0
- cancan_microstack/public/const/metrics_enums.py +36 -0
- cancan_microstack/public/const/monitor_enums.py +26 -0
- cancan_microstack/public/const/operation_consts.py +53 -0
- cancan_microstack/public/const/opsbffsrv_error.py +92 -0
- cancan_microstack/public/const/overrides_consts.py +13 -0
- cancan_microstack/public/const/redis.py +17 -0
- cancan_microstack/public/const/service_consts.py +15 -0
- cancan_microstack/public/const/workflow_consts.py +65 -0
- cancan_microstack/public/error.py +41 -0
- cancan_microstack/public/logging/__init__.py +0 -0
- cancan_microstack/public/logging/initializer.py +109 -0
- cancan_microstack/public/logging/mq_handler.py +279 -0
- cancan_microstack/public/schemas/__init__.py +1 -0
- cancan_microstack/public/schemas/caddy/__init__.py +381 -0
- cancan_microstack/public/schemas/caddy/analysis.py +90 -0
- cancan_microstack/public/schemas/caddy/route.py +18 -0
- cancan_microstack/public/schemas/common.py +79 -0
- cancan_microstack/public/schemas/controllersrv/__init__.py +3 -0
- cancan_microstack/public/schemas/controllersrv/async_requests.py +30 -0
- cancan_microstack/public/schemas/controllersrv/compose_models.py +47 -0
- cancan_microstack/public/schemas/controllersrv/const.py +24 -0
- cancan_microstack/public/schemas/controllersrv/docker_models.py +45 -0
- cancan_microstack/public/schemas/controllersrv/docker_responses.py +104 -0
- cancan_microstack/public/schemas/controllersrv/requests.py +54 -0
- cancan_microstack/public/schemas/controllersrv/responses.py +124 -0
- cancan_microstack/public/schemas/controllersrv/task_models.py +102 -0
- cancan_microstack/public/schemas/controllersrv/validation.py +23 -0
- cancan_microstack/public/schemas/hook_metrics.py +124 -0
- cancan_microstack/public/schemas/hooks.py +39 -0
- cancan_microstack/public/schemas/infra/__init__.py +0 -0
- cancan_microstack/public/schemas/infra/cleanup.py +25 -0
- cancan_microstack/public/schemas/infra/container.py +74 -0
- cancan_microstack/public/schemas/infra/enums.py +135 -0
- cancan_microstack/public/schemas/infra/health_check.py +42 -0
- cancan_microstack/public/schemas/infra/hook_log.py +42 -0
- cancan_microstack/public/schemas/infra/operation.py +90 -0
- cancan_microstack/public/schemas/infra/overview.py +25 -0
- cancan_microstack/public/schemas/infra/push.py +33 -0
- cancan_microstack/public/schemas/infra/service_action_log.py +47 -0
- cancan_microstack/public/schemas/infra/service_config.py +10 -0
- cancan_microstack/public/schemas/infra/service_info.py +69 -0
- cancan_microstack/public/schemas/infra/service_instance.py +93 -0
- cancan_microstack/public/schemas/infra/service_management.py +152 -0
- cancan_microstack/public/schemas/infra/service_operation.py +79 -0
- cancan_microstack/public/schemas/infra/service_registry.py +158 -0
- cancan_microstack/public/schemas/infra/status_types.py +19 -0
- cancan_microstack/public/schemas/infra/workflow.py +566 -0
- cancan_microstack/public/schemas/logging/__init__.py +1 -0
- cancan_microstack/public/schemas/logging/log_event.py +121 -0
- cancan_microstack/public/schemas/opsbffsrv/__init__.py +1 -0
- cancan_microstack/public/schemas/opsbffsrv/async_ops.py +17 -0
- cancan_microstack/public/schemas/opsbffsrv/db_admin.py +147 -0
- cancan_microstack/public/schemas/opsbffsrv/db_init.py +48 -0
- cancan_microstack/public/schemas/opsbffsrv/service_config.py +89 -0
- cancan_microstack/public/schemas/opsbffsrv/service_logs.py +54 -0
- cancan_microstack/public/schemas/service_operation.py +24 -0
- cancan_microstack/public/schemas/service_registry.py +40 -0
- cancan_microstack/public/types/__init__.py +7 -0
- cancan_microstack/public/web/__init__.py +0 -0
- cancan_microstack/public/web/config_value.py +105 -0
- cancan_microstack/public/web/server.py +385 -0
- cancan_microstack/py.typed +0 -0
- cancan_microstack/runtime/__init__.py +0 -0
- cancan_microstack/runtime/compose_cmd.py +228 -0
- cancan_microstack/runtime/host_daemon.py +318 -0
- cancan_microstack/runtime/overrides.py +103 -0
- cancan_microstack/runtime/resources.py +25 -0
- cancan_microstack/runtime/workspace.py +94 -0
- cancan_microstack/services/__init__.py +0 -0
- cancan_microstack/services/controllersrv/__init__.py +8 -0
- cancan_microstack/services/controllersrv/application/__init__.py +0 -0
- cancan_microstack/services/controllersrv/application/docker_compose_app.py +427 -0
- cancan_microstack/services/controllersrv/conf/__init__.py +0 -0
- cancan_microstack/services/controllersrv/conf/config.py +76 -0
- cancan_microstack/services/controllersrv/conf/settings.py +54 -0
- cancan_microstack/services/controllersrv/domain/__init__.py +0 -0
- cancan_microstack/services/controllersrv/domain/docker_compose/__init__.py +0 -0
- cancan_microstack/services/controllersrv/domain/docker_compose/docker_compose_domain.py +278 -0
- cancan_microstack/services/controllersrv/domain/service_validator.py +327 -0
- cancan_microstack/services/controllersrv/domain/task/__init__.py +17 -0
- cancan_microstack/services/controllersrv/domain/task/task_queue.py +286 -0
- cancan_microstack/services/controllersrv/domain/task/task_worker.py +495 -0
- cancan_microstack/services/controllersrv/infrastructure/__init__.py +0 -0
- cancan_microstack/services/controllersrv/interface/__init__.py +0 -0
- cancan_microstack/services/controllersrv/interface/api/__init__.py +0 -0
- cancan_microstack/services/controllersrv/interface/api/docker_control_api.py +470 -0
- cancan_microstack/services/controllersrv/router.py +132 -0
- cancan_microstack/services/infrasrv/__init__.py +4 -0
- cancan_microstack/services/infrasrv/application/__init__.py +0 -0
- cancan_microstack/services/infrasrv/application/health_check_app.py +24 -0
- cancan_microstack/services/infrasrv/application/logging/__init__.py +1 -0
- cancan_microstack/services/infrasrv/application/logging/log_ingestion_service.py +183 -0
- cancan_microstack/services/infrasrv/application/service_config.py +22 -0
- cancan_microstack/services/infrasrv/application/service_logs_app.py +53 -0
- cancan_microstack/services/infrasrv/application/service_management_app.py +689 -0
- cancan_microstack/services/infrasrv/application/service_operation_tracker.py +251 -0
- cancan_microstack/services/infrasrv/application/service_registry.py +53 -0
- cancan_microstack/services/infrasrv/application/workflow/__init__.py +0 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_app.py +991 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_queue.py +302 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_tasks.py +46 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_worker_runtime.py +122 -0
- cancan_microstack/services/infrasrv/conf/__init__.py +0 -0
- cancan_microstack/services/infrasrv/conf/config.py +98 -0
- cancan_microstack/services/infrasrv/domain/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/health_check/__init__.py +3 -0
- cancan_microstack/services/infrasrv/domain/health_check/health_check_domain.py +576 -0
- cancan_microstack/services/infrasrv/domain/hooks/__init__.py +19 -0
- cancan_microstack/services/infrasrv/domain/hooks/builtin_hooks.py +308 -0
- cancan_microstack/services/infrasrv/domain/hooks/hook_registry.py +43 -0
- cancan_microstack/services/infrasrv/domain/hooks/hooks_log_utils.py +275 -0
- cancan_microstack/services/infrasrv/domain/hooks/init.py +17 -0
- cancan_microstack/services/infrasrv/domain/hooks/metrics.py +205 -0
- cancan_microstack/services/infrasrv/domain/hooks/pre_registration_hooks.py +490 -0
- cancan_microstack/services/infrasrv/domain/registry/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/registry/service_registry.py +509 -0
- cancan_microstack/services/infrasrv/domain/service_config/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/service_config/service_config.py +50 -0
- cancan_microstack/services/infrasrv/domain/service_logs/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/service_logs/service_logs_domain.py +51 -0
- cancan_microstack/services/infrasrv/domain/workflow/__init__.py +4 -0
- cancan_microstack/services/infrasrv/domain/workflow/engine.py +159 -0
- cancan_microstack/services/infrasrv/domain/workflow/node_handlers.py +509 -0
- cancan_microstack/services/infrasrv/domain/workflow/workflow_domain.py +164 -0
- cancan_microstack/services/infrasrv/infrastructure/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/api/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/api/controllersrv_api.py +165 -0
- cancan_microstack/services/infrasrv/infrastructure/cache/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/cache/service_registry_cache.py +174 -0
- cancan_microstack/services/infrasrv/infrastructure/db/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/execution_log_tbl.py +53 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/node_instance_tbl.py +55 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_config_tbl.py +30 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_info_tbl.py +59 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_instance_tbl.py +88 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_operation_tbl.py +73 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_tbl.py +55 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_version_tbl.py +43 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_engine_alert_tbl.py +57 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_run_tbl.py +56 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_action_log_op.py +239 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config.py +80 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config_manager.py +198 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_info_op.py +297 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_instance_op.py +688 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_operation_op.py +387 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_registry.py +124 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/workflow_op.py +804 -0
- cancan_microstack/services/infrasrv/infrastructure/ddl_manager.py +31 -0
- cancan_microstack/services/infrasrv/infrastructure/mongo/__init__.py +1 -0
- cancan_microstack/services/infrasrv/infrastructure/mongo/log_repository.py +129 -0
- cancan_microstack/services/infrasrv/interface/__init__.py +0 -0
- cancan_microstack/services/infrasrv/interface/api/__init__.py +0 -0
- cancan_microstack/services/infrasrv/interface/api/health_check_api.py +29 -0
- cancan_microstack/services/infrasrv/interface/api/hooks.py +284 -0
- cancan_microstack/services/infrasrv/interface/api/internal.py +49 -0
- cancan_microstack/services/infrasrv/interface/api/internal_instance_api.py +265 -0
- cancan_microstack/services/infrasrv/interface/api/internal_operation_api.py +206 -0
- cancan_microstack/services/infrasrv/interface/api/service_config.py +50 -0
- cancan_microstack/services/infrasrv/interface/api/service_logs_api.py +49 -0
- cancan_microstack/services/infrasrv/interface/api/service_management_api.py +113 -0
- cancan_microstack/services/infrasrv/interface/api/service_registry.py +117 -0
- cancan_microstack/services/infrasrv/interface/api/workflow_api.py +303 -0
- cancan_microstack/services/infrasrv/interface/schedule/__init__.py +0 -0
- cancan_microstack/services/infrasrv/interface/schedule/cleanup.py +13 -0
- cancan_microstack/services/infrasrv/interface/schedule/health_check.py +27 -0
- cancan_microstack/services/infrasrv/interface/schedule/log_cleanup.py +26 -0
- cancan_microstack/services/infrasrv/interface/schedule/operation_tracker.py +25 -0
- cancan_microstack/services/infrasrv/interface/schedule/scheduler.py +39 -0
- cancan_microstack/services/infrasrv/interface/schedule/workflow_scheduler.py +115 -0
- cancan_microstack/services/infrasrv/router.py +341 -0
- cancan_microstack/services/opsbffsrv/__init__.py +4 -0
- cancan_microstack/services/opsbffsrv/application/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/application/async_operation_app.py +150 -0
- cancan_microstack/services/opsbffsrv/application/auth_app.py +285 -0
- cancan_microstack/services/opsbffsrv/application/caddy/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/application/caddy/access_log_analysis_app.py +344 -0
- cancan_microstack/services/opsbffsrv/application/caddy/access_log_ingestion_service.py +169 -0
- cancan_microstack/services/opsbffsrv/application/caddy/certificate_management_app.py +355 -0
- cancan_microstack/services/opsbffsrv/application/caddy/rate_limit_management_app.py +496 -0
- cancan_microstack/services/opsbffsrv/application/caddy/route_management_app.py +401 -0
- cancan_microstack/services/opsbffsrv/application/caddy/stats_aggregation_app.py +364 -0
- cancan_microstack/services/opsbffsrv/application/db_admin_app.py +103 -0
- cancan_microstack/services/opsbffsrv/application/db_init_app.py +283 -0
- cancan_microstack/services/opsbffsrv/application/logging/__init__.py +1 -0
- cancan_microstack/services/opsbffsrv/application/logging/log_query_app.py +28 -0
- cancan_microstack/services/opsbffsrv/application/service_config.py +158 -0
- cancan_microstack/services/opsbffsrv/application/service_logs_app.py +74 -0
- cancan_microstack/services/opsbffsrv/application/service_registry.py +36 -0
- cancan_microstack/services/opsbffsrv/application/workflow_ops_app.py +730 -0
- cancan_microstack/services/opsbffsrv/conf/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/conf/config.py +224 -0
- cancan_microstack/services/opsbffsrv/domain/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/auth/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/auth/admin_init.py +38 -0
- cancan_microstack/services/opsbffsrv/domain/auth/auth_domain.py +108 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/access_log_analysis.py +358 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/certificate_management.py +325 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/default_routes.py +53 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/rate_limit_management.py +308 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/route_management.py +279 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/stats_aggregation.py +654 -0
- cancan_microstack/services/opsbffsrv/domain/db_admin/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/db_admin/db_admin_domain.py +118 -0
- cancan_microstack/services/opsbffsrv/domain/db_init/__init__.py +3 -0
- cancan_microstack/services/opsbffsrv/domain/db_init/db_init_domain.py +358 -0
- cancan_microstack/services/opsbffsrv/domain/logging/__init__.py +1 -0
- cancan_microstack/services/opsbffsrv/domain/logging/log_query_domain.py +99 -0
- cancan_microstack/services/opsbffsrv/domain/service_config/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/service_config/service_config.py +81 -0
- cancan_microstack/services/opsbffsrv/domain/service_registry/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/service_registry/service_registry.py +292 -0
- cancan_microstack/services/opsbffsrv/infrastructure/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/api/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/api/infrasrv_api.py +242 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/captcha_service.py +67 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/password_service.py +12 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/redis_store.py +131 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/totp_service.py +59 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/access_log_parser.py +307 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/admin_api_client.py +678 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/ip_geo_locator.py +176 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/admin_user_tbl.py +33 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_access_log_tbl.py +90 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_certificate_tbl.py +65 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_rate_limit_tbl.py +69 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_route_tbl.py +66 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_stats_tbl.py +78 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_config_tbl.py +30 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_info_tbl.py +51 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_instance_tbl.py +68 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/admin_user_operate.py +59 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_access_log.py +531 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_certificate.py +451 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_rate_limit.py +360 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_route.py +271 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_stats.py +343 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_action_log_op.py +57 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_config.py +86 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_info_op.py +79 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_instance.py +58 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_registry.py +138 -0
- cancan_microstack/services/opsbffsrv/infrastructure/ddl_manager.py +31 -0
- cancan_microstack/services/opsbffsrv/infrastructure/mongo/__init__.py +1 -0
- cancan_microstack/services/opsbffsrv/infrastructure/mongo/log_query_repository.py +87 -0
- cancan_microstack/services/opsbffsrv/interface/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/interface/api/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/interface/api/async_operation_api.py +137 -0
- cancan_microstack/services/opsbffsrv/interface/api/auth_api.py +113 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/__init__.py +3 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/access_log_api.py +174 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/certificate_api.py +235 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/rate_limit_api.py +302 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/route_api.py +250 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/stats_api.py +243 -0
- cancan_microstack/services/opsbffsrv/interface/api/db_admin_api.py +62 -0
- cancan_microstack/services/opsbffsrv/interface/api/db_init_api.py +109 -0
- cancan_microstack/services/opsbffsrv/interface/api/instance_management_api.py +165 -0
- cancan_microstack/services/opsbffsrv/interface/api/log_query_api.py +41 -0
- cancan_microstack/services/opsbffsrv/interface/api/mongo_express_proxy_api.py +181 -0
- cancan_microstack/services/opsbffsrv/interface/api/pgweb_proxy_api.py +154 -0
- cancan_microstack/services/opsbffsrv/interface/api/rabbitmq_mgmt_proxy_api.py +518 -0
- cancan_microstack/services/opsbffsrv/interface/api/redis_commander_proxy_api.py +133 -0
- cancan_microstack/services/opsbffsrv/interface/api/service_config.py +146 -0
- cancan_microstack/services/opsbffsrv/interface/api/service_logs_api.py +81 -0
- cancan_microstack/services/opsbffsrv/interface/api/service_registry.py +66 -0
- cancan_microstack/services/opsbffsrv/interface/api/workflow_ops_api.py +413 -0
- cancan_microstack/services/opsbffsrv/interface/middleware/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/interface/middleware/auth_middleware.py +52 -0
- cancan_microstack/services/opsbffsrv/router.py +901 -0
- cancan_microstack/utils/__init__.py +1 -0
- cancan_microstack/utils/container_env.py +218 -0
- cancan_microstack-0.0.1.dist-info/METADATA +155 -0
- cancan_microstack-0.0.1.dist-info/RECORD +440 -0
- cancan_microstack-0.0.1.dist-info/WHEEL +5 -0
- cancan_microstack-0.0.1.dist-info/entry_points.txt +2 -0
- cancan_microstack-0.0.1.dist-info/licenses/LICENSE +21 -0
- cancan_microstack-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
工作流领域服务
|
|
3
|
+
Workflow Domain Service
|
|
4
|
+
|
|
5
|
+
负责工作流的核心业务逻辑和规则验证,包括分布式锁保护的更新操作。
|
|
6
|
+
Handles workflow core business logic and rule validation, including update operations protected by distributed locks.
|
|
7
|
+
"""
|
|
8
|
+
import uuid
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from contextlib import asynccontextmanager
|
|
11
|
+
|
|
12
|
+
import redis.asyncio as redis
|
|
13
|
+
|
|
14
|
+
from cancan_microstack.public.const.redis import RedisKey
|
|
15
|
+
from cancan_microstack.public.error import HTTPException
|
|
16
|
+
from cancan_microstack.public.schemas.infra import workflow as wt
|
|
17
|
+
from linglong_web import Rmanager
|
|
18
|
+
from cancan_microstack.services.infrasrv.infrastructure.db.operate import workflow_op
|
|
19
|
+
from linglong_web.utils import logger
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class WorkflowDomain:
|
|
23
|
+
"""
|
|
24
|
+
工作流领域服务
|
|
25
|
+
Workflow domain service for core business logic.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# Redis 锁的过期时间(秒)
|
|
29
|
+
# Redis lock expiration time in seconds
|
|
30
|
+
LOCK_EXPIRE_SECONDS = 60 * 5 # 5分钟
|
|
31
|
+
|
|
32
|
+
def _get_workflow_lock(self, workflow_id: uuid.UUID):
|
|
33
|
+
"""
|
|
34
|
+
基于 Redis 连接池创建分布式锁对象
|
|
35
|
+
Create distributed lock object using Redis connection pool
|
|
36
|
+
"""
|
|
37
|
+
if not Rmanager.RedisPool:
|
|
38
|
+
raise HTTPException(status_code=500, msg="Redis pool is not initialized")
|
|
39
|
+
|
|
40
|
+
redis_client = redis.Redis(connection_pool=Rmanager.RedisPool)
|
|
41
|
+
lock_key = f"{RedisKey.WORKFLOW_UPDATE_PREFIX}{workflow_id}"
|
|
42
|
+
return redis_client.lock(lock_key, timeout=self.LOCK_EXPIRE_SECONDS)
|
|
43
|
+
|
|
44
|
+
@asynccontextmanager
|
|
45
|
+
async def _acquire_workflow_lock(self, workflow_id: uuid.UUID):
|
|
46
|
+
"""
|
|
47
|
+
获取工作流的分布式锁
|
|
48
|
+
Acquire distributed lock for a workflow.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
workflow_id: 工作流 ID / Workflow ID
|
|
52
|
+
|
|
53
|
+
Yields:
|
|
54
|
+
None
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
HTTPException: 如果获取锁超时 / If lock acquisition times out
|
|
58
|
+
"""
|
|
59
|
+
lock = self._get_workflow_lock(workflow_id)
|
|
60
|
+
|
|
61
|
+
# blocking=True 结合 blocking_timeout 确保不会无限等待
|
|
62
|
+
# blocking=True with blocking_timeout ensures we don't wait forever
|
|
63
|
+
lock_acquired = await lock.acquire(blocking=True, blocking_timeout=self.LOCK_EXPIRE_SECONDS)
|
|
64
|
+
|
|
65
|
+
if not lock_acquired:
|
|
66
|
+
logger.warning(f"Failed to acquire lock for workflow {workflow_id}")
|
|
67
|
+
raise HTTPException(
|
|
68
|
+
status_code=409,
|
|
69
|
+
msg=f"Workflow {workflow_id} is being modified by another process, please retry later"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
logger.debug(f"Acquired lock for workflow {workflow_id}")
|
|
74
|
+
yield
|
|
75
|
+
finally:
|
|
76
|
+
if lock.locked():
|
|
77
|
+
await lock.release()
|
|
78
|
+
logger.debug(f"Released lock for workflow {workflow_id}")
|
|
79
|
+
|
|
80
|
+
async def update_workflow_definition(
|
|
81
|
+
self,
|
|
82
|
+
workflow_id: uuid.UUID,
|
|
83
|
+
data: wt.WorkflowDefinitionUpdate
|
|
84
|
+
) -> Optional[wt.WorkflowDefinition]:
|
|
85
|
+
"""
|
|
86
|
+
更新工作流定义(带分布式锁保护)
|
|
87
|
+
Update workflow definition with distributed lock protection.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
workflow_id: 工作流 ID / Workflow ID
|
|
91
|
+
data: 更新数据 / Update data
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
更新后的工作流定义,如果不存在则返回 None
|
|
95
|
+
Updated workflow definition, or None if not found
|
|
96
|
+
|
|
97
|
+
Raises:
|
|
98
|
+
HTTPException: 如果无法获取锁 / If lock cannot be acquired
|
|
99
|
+
"""
|
|
100
|
+
# 使用分布式锁保护更新操作
|
|
101
|
+
# Protect update operation with distributed lock
|
|
102
|
+
async with self._acquire_workflow_lock(workflow_id):
|
|
103
|
+
logger.info(f"Updating workflow definition {workflow_id} with lock protection")
|
|
104
|
+
|
|
105
|
+
# 调用基础设施层执行数据库更新
|
|
106
|
+
# Call infrastructure layer to execute database update
|
|
107
|
+
updated = await workflow_op.update_workflow_definition(workflow_id, data)
|
|
108
|
+
|
|
109
|
+
if not updated:
|
|
110
|
+
logger.warning(f"Workflow {workflow_id} not found during update")
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
logger.info(f"Successfully updated workflow definition {workflow_id}")
|
|
114
|
+
return updated
|
|
115
|
+
|
|
116
|
+
async def rollback_workflow_definition(
|
|
117
|
+
self,
|
|
118
|
+
workflow_id: uuid.UUID,
|
|
119
|
+
target_version: int,
|
|
120
|
+
reason: Optional[str] = None,
|
|
121
|
+
) -> Optional[wt.WorkflowDefinition]:
|
|
122
|
+
"""
|
|
123
|
+
回滚工作流定义(带分布式锁保护)
|
|
124
|
+
Roll back workflow definition with distributed lock protection.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
workflow_id: 工作流 ID / Workflow ID
|
|
128
|
+
target_version: 目标版本号 / Target version number
|
|
129
|
+
reason: 回滚原因 / Rollback reason
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
回滚后的工作流定义 / Workflow definition after rollback
|
|
133
|
+
"""
|
|
134
|
+
async with self._acquire_workflow_lock(workflow_id):
|
|
135
|
+
logger.info(
|
|
136
|
+
"Rolling back workflow %s to version %s with lock protection",
|
|
137
|
+
workflow_id,
|
|
138
|
+
target_version,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
updated = await workflow_op.rollback_workflow_definition(
|
|
142
|
+
workflow_id,
|
|
143
|
+
target_version=target_version,
|
|
144
|
+
reason=reason,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if not updated:
|
|
148
|
+
logger.warning(
|
|
149
|
+
"Workflow %s rollback failed, version %s not found",
|
|
150
|
+
workflow_id,
|
|
151
|
+
target_version,
|
|
152
|
+
)
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
logger.info(
|
|
156
|
+
"Workflow %s rolled back to version %s successfully",
|
|
157
|
+
workflow_id,
|
|
158
|
+
target_version,
|
|
159
|
+
)
|
|
160
|
+
return updated
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# 全局实例 / Global instance
|
|
164
|
+
workflow_domain = WorkflowDomain()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""
|
|
2
|
+
controllersrv API 客户端(用于 infrasrv)/ controllersrv API Client (for infrasrv)
|
|
3
|
+
|
|
4
|
+
infrasrv 用于调用 controllersrv 的 API 客户端 / API client for infrasrv to call controllersrv
|
|
5
|
+
继承自公共的 ControllerSrvApiClient / Inherits from common ControllerSrvApiClient
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
from typing import (
|
|
9
|
+
List,
|
|
10
|
+
Optional,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from linglong_web.utils import logger
|
|
14
|
+
from linglong_web import LinglongConfig
|
|
15
|
+
|
|
16
|
+
from cancan_microstack.public.api.controllersrv_client import (
|
|
17
|
+
ControllerSrvApiClient,
|
|
18
|
+
ServiceOperationResponse,
|
|
19
|
+
)
|
|
20
|
+
from cancan_microstack.public.schemas.common import APIResponse
|
|
21
|
+
from cancan_microstack.public.schemas.controllersrv.responses import (
|
|
22
|
+
EnqueueErrorResponse,
|
|
23
|
+
EnqueueSuccessResponse,
|
|
24
|
+
TaskStatusResponse,
|
|
25
|
+
)
|
|
26
|
+
from cancan_microstack.public.schemas.controllersrv.validation import ValidationResult
|
|
27
|
+
from cancan_microstack.public.schemas.infra.service_management import ControllerSrvResult
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ControllerSrvApi(ControllerSrvApiClient):
|
|
31
|
+
"""
|
|
32
|
+
用于与 controllersrv 通信的 API 客户端(infrasrv 专用)
|
|
33
|
+
API client for communicating with controllersrv (for infrasrv)
|
|
34
|
+
|
|
35
|
+
继承自公共的 ControllerSrvApiClient,添加特定于 infrasrv 的配置
|
|
36
|
+
Inherits from common ControllerSrvApiClient with infrasrv-specific configuration
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self):
|
|
40
|
+
"""
|
|
41
|
+
初始化 API 客户端,使用 infrasrv 的配置
|
|
42
|
+
Initialize API client with infrasrv configuration
|
|
43
|
+
"""
|
|
44
|
+
# 从配置获取 controllersrv 的地址 / Get controllersrv address from config
|
|
45
|
+
# 优先使用环境变量,确保在容器环境中能获取到正确的值
|
|
46
|
+
# 注意:该类可能会在 LinglongConfig 初始化前被 import。
|
|
47
|
+
# Note: This class may be imported before LinglongConfig is initialized.
|
|
48
|
+
config_host = getattr(LinglongConfig, "CONTROLLERSRV_HOST", None)
|
|
49
|
+
controllersrv_host = os.getenv(
|
|
50
|
+
"CONTROLLERSRV_HOST",
|
|
51
|
+
config_host or "http://host.containers.internal:22100",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
base_url = f"{controllersrv_host}/v1/controllersrv"
|
|
55
|
+
|
|
56
|
+
# 调用父类初始化 / Call parent class initialization
|
|
57
|
+
super().__init__(base_url=base_url)
|
|
58
|
+
logger.info(f"ControllerSrvApi initialized (infrasrv) with base_url: {base_url}")
|
|
59
|
+
|
|
60
|
+
async def start_services(self, service_names: List[str], serial_number: str) -> ControllerSrvResult:
|
|
61
|
+
"""
|
|
62
|
+
调用 controllersrv 启动服务 / Call controllersrv to start services
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
service_names: 服务名称列表 / List of service names
|
|
66
|
+
serial_number: 操作序列号(operation_id)/ Operation serial number (operation_id)
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
操作结果 / Operation result
|
|
70
|
+
"""
|
|
71
|
+
logger.info(f"[infrasrv → controllersrv] Starting services: {service_names}, serial_number: {serial_number}")
|
|
72
|
+
response = await super().start_services(service_names, serial_number)
|
|
73
|
+
return self._to_controller_result(response, operation="start")
|
|
74
|
+
|
|
75
|
+
async def stop_services(self, service_names: List[str], serial_number: str) -> ControllerSrvResult:
|
|
76
|
+
"""
|
|
77
|
+
调用 controllersrv 停止服务 / Call controllersrv to stop services
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
service_names: 服务名称列表 / List of service names
|
|
81
|
+
serial_number: 操作序列号(operation_id)/ Operation serial number (operation_id)
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
操作结果 / Operation result
|
|
85
|
+
"""
|
|
86
|
+
logger.info(f"[infrasrv → controllersrv] Stopping services: {service_names}, serial_number: {serial_number}")
|
|
87
|
+
response = await super().stop_services(service_names, serial_number)
|
|
88
|
+
return self._to_controller_result(response, operation="stop")
|
|
89
|
+
|
|
90
|
+
async def restart_services(self, service_names: List[str], serial_number: str) -> ControllerSrvResult:
|
|
91
|
+
"""
|
|
92
|
+
调用 controllersrv 重启服务 / Call controllersrv to restart services
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
service_names: 服务名称列表 / List of service names
|
|
96
|
+
serial_number: 操作序列号(operation_id)/ Operation serial number (operation_id)
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
操作结果 / Operation result
|
|
100
|
+
"""
|
|
101
|
+
logger.info(f"[infrasrv → controllersrv] Restarting services: {service_names}, serial_number: {serial_number}")
|
|
102
|
+
response = await super().restart_services(service_names, serial_number)
|
|
103
|
+
return self._to_controller_result(response, operation="restart")
|
|
104
|
+
|
|
105
|
+
async def get_operation_status(self, serial_number: str) -> Optional[TaskStatusResponse]:
|
|
106
|
+
"""
|
|
107
|
+
查询 controllersrv 中任务的最新状态
|
|
108
|
+
Query latest task status from controllersrv
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
response = await super().get_operation_status(serial_number)
|
|
112
|
+
if response.success and isinstance(response.data, TaskStatusResponse):
|
|
113
|
+
return response.data
|
|
114
|
+
|
|
115
|
+
logger.warning(
|
|
116
|
+
"Failed to fetch controllersrv task status: serial=%s, error=%s",
|
|
117
|
+
serial_number,
|
|
118
|
+
response.error.msg if response.error else "unknown",
|
|
119
|
+
)
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
def _to_controller_result(
|
|
123
|
+
self,
|
|
124
|
+
response: APIResponse[Optional[ServiceOperationResponse]],
|
|
125
|
+
operation: str,
|
|
126
|
+
) -> ControllerSrvResult:
|
|
127
|
+
"""将 controllersrv 响应转换为 ControllerSrvResult / Convert controllersrv response to ControllerSrvResult"""
|
|
128
|
+
|
|
129
|
+
data = response.data
|
|
130
|
+
|
|
131
|
+
if isinstance(data, EnqueueSuccessResponse):
|
|
132
|
+
message = data.message or f"{operation} operation accepted"
|
|
133
|
+
return ControllerSrvResult(success=True, message=message)
|
|
134
|
+
|
|
135
|
+
if isinstance(data, EnqueueErrorResponse):
|
|
136
|
+
message = data.message or f"{operation} operation rejected"
|
|
137
|
+
return ControllerSrvResult(success=False, message=message, error=message)
|
|
138
|
+
|
|
139
|
+
if isinstance(data, ValidationResult):
|
|
140
|
+
message = self._build_validation_message(data)
|
|
141
|
+
return ControllerSrvResult(success=False, message=message, error=message)
|
|
142
|
+
|
|
143
|
+
if response.success:
|
|
144
|
+
# controllersrv 成功但未返回详细数据 / controllersrv succeeded without detail
|
|
145
|
+
return ControllerSrvResult(success=True, message=f"{operation} operation accepted")
|
|
146
|
+
|
|
147
|
+
error_message = response.error.msg or f"controllersrv {operation} request failed"
|
|
148
|
+
return ControllerSrvResult(
|
|
149
|
+
success=False,
|
|
150
|
+
message=error_message,
|
|
151
|
+
error=error_message,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def _build_validation_message(validation: ValidationResult) -> str:
|
|
156
|
+
"""拼接服务校验失败原因 / Build validation failure message"""
|
|
157
|
+
|
|
158
|
+
parts: List[str] = []
|
|
159
|
+
if validation.invalid_services:
|
|
160
|
+
parts.append(f"Invalid services: {', '.join(validation.invalid_services)}")
|
|
161
|
+
if validation.non_operable_services:
|
|
162
|
+
parts.append(f"Non-operable services: {', '.join(validation.non_operable_services)}")
|
|
163
|
+
if validation.valid_services and not validation.valid:
|
|
164
|
+
parts.append(f"Valid subset: {', '.join(validation.valid_services)}")
|
|
165
|
+
return "; ".join(parts) if parts else "Service validation failed"
|
|
File without changes
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
服务注册 Redis 缓存辅助类
|
|
3
|
+
"""
|
|
4
|
+
import orjson
|
|
5
|
+
from typing import (
|
|
6
|
+
Optional,
|
|
7
|
+
List,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from cancan_microstack.public.const.redis import RedisKey
|
|
11
|
+
from linglong_web import Rmanager
|
|
12
|
+
from linglong_web.utils import logger
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ServiceRegistryCache:
|
|
16
|
+
"""服务注册缓存管理"""
|
|
17
|
+
|
|
18
|
+
# 缓存过期时间(秒)
|
|
19
|
+
CACHE_TTL_INSTANCE = 60 # 单个实例缓存60秒
|
|
20
|
+
CACHE_TTL_LIST = 30 # 列表缓存30秒
|
|
21
|
+
|
|
22
|
+
SERVICE_NAME = "infrasrv"
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def _get_cache_key(cls, key_template: str, **kwargs) -> str:
|
|
26
|
+
"""
|
|
27
|
+
生成缓存 key
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
key_template: key 模板
|
|
31
|
+
**kwargs: 模板参数
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
完整的缓存 key
|
|
35
|
+
"""
|
|
36
|
+
key = key_template.format(**kwargs)
|
|
37
|
+
return f"{cls.SERVICE_NAME}:{RedisKey.SERVICE_REGISTRY_PREFIX}{key}"
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
async def get_instance(cls, service_name: str, instance_id: str) -> Optional[dict]:
|
|
41
|
+
"""
|
|
42
|
+
从缓存获取服务实例
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
service_name: 服务名称
|
|
46
|
+
instance_id: 实例ID
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
服务实例数据,不存在则返回 None
|
|
50
|
+
"""
|
|
51
|
+
key = cls._get_cache_key(RedisKey.SERVICE_REGISTRY_INSTANCE, service_name=service_name, instance_id=instance_id)
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
cached_data = await Rmanager.redis().get(key)
|
|
55
|
+
if cached_data:
|
|
56
|
+
return orjson.loads(cached_data)
|
|
57
|
+
except Exception as e:
|
|
58
|
+
logger.error(f"Failed to get cache for instance {service_name}:{instance_id}: {e}")
|
|
59
|
+
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
async def set_instance(cls, service_name: str, instance_id: str, data: dict) -> None:
|
|
64
|
+
"""
|
|
65
|
+
缓存服务实例
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
service_name: 服务名称
|
|
69
|
+
instance_id: 实例ID
|
|
70
|
+
data: 实例数据
|
|
71
|
+
"""
|
|
72
|
+
key = cls._get_cache_key(RedisKey.SERVICE_REGISTRY_INSTANCE, service_name=service_name, instance_id=instance_id)
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
await Rmanager.redis().setex(
|
|
76
|
+
key,
|
|
77
|
+
cls.CACHE_TTL_INSTANCE,
|
|
78
|
+
orjson.dumps(data)
|
|
79
|
+
)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.error(f"Failed to cache instance {service_name}:{instance_id}: {e}")
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
async def delete_instance(cls, service_name: str, instance_id: str) -> None:
|
|
85
|
+
"""
|
|
86
|
+
删除服务实例缓存
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
service_name: 服务名称
|
|
90
|
+
instance_id: 实例ID
|
|
91
|
+
"""
|
|
92
|
+
key = cls._get_cache_key(RedisKey.SERVICE_REGISTRY_INSTANCE, service_name=service_name, instance_id=instance_id)
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
await Rmanager.redis().delete(key)
|
|
96
|
+
except Exception as e:
|
|
97
|
+
logger.error(f"Failed to delete cache for instance {service_name}:{instance_id}: {e}")
|
|
98
|
+
|
|
99
|
+
@classmethod
|
|
100
|
+
async def get_service_instances(cls, service_name: str) -> Optional[List[dict]]:
|
|
101
|
+
"""
|
|
102
|
+
从缓存获取服务的所有实例
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
service_name: 服务名称
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
实例列表,不存在则返回 None
|
|
109
|
+
"""
|
|
110
|
+
key = cls._get_cache_key(RedisKey.SERVICE_REGISTRY_SERVICE_INSTANCES, service_name=service_name)
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
cached_data = await Rmanager.redis().get(key)
|
|
114
|
+
if cached_data:
|
|
115
|
+
return orjson.loads(cached_data)
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"Failed to get cache for service instances {service_name}: {e}")
|
|
118
|
+
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
async def set_service_instances(cls, service_name: str, data: List[dict]) -> None:
|
|
123
|
+
"""
|
|
124
|
+
缓存服务的所有实例
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
service_name: 服务名称
|
|
128
|
+
data: 实例列表
|
|
129
|
+
"""
|
|
130
|
+
key = cls._get_cache_key(RedisKey.SERVICE_REGISTRY_SERVICE_INSTANCES, service_name=service_name)
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
await Rmanager.redis().setex(
|
|
134
|
+
key,
|
|
135
|
+
cls.CACHE_TTL_LIST,
|
|
136
|
+
orjson.dumps(data)
|
|
137
|
+
)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
logger.error(f"Failed to cache service instances {service_name}: {e}")
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
async def delete_service_instances(cls, service_name: str) -> None:
|
|
143
|
+
"""
|
|
144
|
+
删除服务实例列表缓存
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
service_name: 服务名称
|
|
148
|
+
"""
|
|
149
|
+
key = cls._get_cache_key(RedisKey.SERVICE_REGISTRY_SERVICE_INSTANCES, service_name=service_name)
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
await Rmanager.redis().delete(key)
|
|
153
|
+
except Exception as e:
|
|
154
|
+
logger.error(f"Failed to delete cache for service instances {service_name}: {e}")
|
|
155
|
+
|
|
156
|
+
@classmethod
|
|
157
|
+
async def invalidate_all(cls) -> None:
|
|
158
|
+
"""清空所有服务注册相关缓存"""
|
|
159
|
+
try:
|
|
160
|
+
# 使用 SCAN 查找所有匹配的 key
|
|
161
|
+
pattern = f"{cls.SERVICE_NAME}:{RedisKey.SERVICE_REGISTRY_PREFIX}*"
|
|
162
|
+
cursor = 0
|
|
163
|
+
|
|
164
|
+
while True:
|
|
165
|
+
cursor, keys = await Rmanager.redis().scan(cursor, match=pattern, count=100)
|
|
166
|
+
if keys:
|
|
167
|
+
await Rmanager.redis().delete(*keys)
|
|
168
|
+
|
|
169
|
+
if cursor == 0:
|
|
170
|
+
break
|
|
171
|
+
|
|
172
|
+
logger.info("All service registry cache invalidated")
|
|
173
|
+
except Exception as e:
|
|
174
|
+
logger.error(f"Failed to invalidate all cache: {e}")
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
执行审计日志表模型 / Execution Audit Log Table Model
|
|
3
|
+
"""
|
|
4
|
+
import uuid
|
|
5
|
+
from sqlalchemy import (
|
|
6
|
+
Column,
|
|
7
|
+
String,
|
|
8
|
+
Integer,
|
|
9
|
+
Text,
|
|
10
|
+
SmallInteger,
|
|
11
|
+
TIMESTAMP,
|
|
12
|
+
ForeignKey,
|
|
13
|
+
)
|
|
14
|
+
from sqlalchemy.dialects.postgresql import (
|
|
15
|
+
JSONB,
|
|
16
|
+
UUID,
|
|
17
|
+
)
|
|
18
|
+
from sqlalchemy.sql import func
|
|
19
|
+
from linglong_web import TableBase
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ExecutionLogTbl(TableBase):
|
|
23
|
+
"""
|
|
24
|
+
执行审计日志表 execution log
|
|
25
|
+
"""
|
|
26
|
+
__tablename__ = 'execution_log_tbl'
|
|
27
|
+
|
|
28
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
29
|
+
node_instance_id = Column(UUID(as_uuid=True), ForeignKey('node_instance_tbl.id'), nullable=False)
|
|
30
|
+
|
|
31
|
+
attempt_no = Column(Integer, nullable=False) # 第几次尝试
|
|
32
|
+
|
|
33
|
+
# 动作快照 (请求前)
|
|
34
|
+
request_snapshot = Column(JSONB)
|
|
35
|
+
|
|
36
|
+
# 结果快照 (响应后)
|
|
37
|
+
response_snapshot = Column(JSONB)
|
|
38
|
+
|
|
39
|
+
status = Column(String(20)) # SUCCESS, FAILURE, TIMEOUT (可以是字符串,比Enum灵活点)
|
|
40
|
+
error_detail = Column(Text)
|
|
41
|
+
|
|
42
|
+
start_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp())
|
|
43
|
+
end_time = Column(TIMESTAMP(timezone=True))
|
|
44
|
+
duration_ms = Column(Integer)
|
|
45
|
+
|
|
46
|
+
# 标准字段 (与 SQL schema 保持一致)
|
|
47
|
+
flag = Column(SmallInteger, default=0)
|
|
48
|
+
created_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp())
|
|
49
|
+
update_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp(), onupdate=func.current_timestamp())
|
|
50
|
+
|
|
51
|
+
__table_args__ = (
|
|
52
|
+
{'extend_existing': True},
|
|
53
|
+
)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
节点运行实例表模型 / Node Run Instance Table Model
|
|
3
|
+
"""
|
|
4
|
+
import uuid
|
|
5
|
+
from sqlalchemy import (
|
|
6
|
+
Column,
|
|
7
|
+
String,
|
|
8
|
+
Integer,
|
|
9
|
+
Text,
|
|
10
|
+
SmallInteger,
|
|
11
|
+
TIMESTAMP,
|
|
12
|
+
ForeignKey,
|
|
13
|
+
)
|
|
14
|
+
from sqlalchemy.dialects.postgresql import (
|
|
15
|
+
JSONB,
|
|
16
|
+
UUID,
|
|
17
|
+
)
|
|
18
|
+
from sqlalchemy.sql import func
|
|
19
|
+
from linglong_web import TableBase
|
|
20
|
+
from cancan_microstack.public.const.workflow_consts import NodeStatusEnum
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NodeInstanceTbl(TableBase):
|
|
24
|
+
"""
|
|
25
|
+
节点运行实例表 node instance
|
|
26
|
+
"""
|
|
27
|
+
__tablename__ = 'node_instance_tbl'
|
|
28
|
+
|
|
29
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
30
|
+
run_id = Column(UUID(as_uuid=True), ForeignKey('workflow_run_tbl.id'), nullable=False)
|
|
31
|
+
|
|
32
|
+
# 对应 JSON 图中的 key (如 "step_1")
|
|
33
|
+
node_id = Column(String(50), nullable=False)
|
|
34
|
+
|
|
35
|
+
# 循环轮次 (默认为 1)
|
|
36
|
+
loop_index = Column(Integer, default=1, nullable=False)
|
|
37
|
+
|
|
38
|
+
status = Column(String(20), default=NodeStatusEnum.PENDING.value, index=True)
|
|
39
|
+
|
|
40
|
+
# 数据流转
|
|
41
|
+
input_data = Column(JSONB, default=dict) # 进入该节点时的入参
|
|
42
|
+
final_output = Column(JSONB, default=dict) # 该节点产出的结果
|
|
43
|
+
|
|
44
|
+
# 统计
|
|
45
|
+
attempt_count = Column(Integer, default=0)
|
|
46
|
+
error_msg = Column(Text)
|
|
47
|
+
|
|
48
|
+
# 标准字段 (与 SQL schema 保持一致)
|
|
49
|
+
flag = Column(SmallInteger, default=0)
|
|
50
|
+
created_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp())
|
|
51
|
+
update_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp(), onupdate=func.current_timestamp())
|
|
52
|
+
|
|
53
|
+
__table_args__ = (
|
|
54
|
+
{'extend_existing': True},
|
|
55
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
服务行为日志表 ORM 模型
|
|
3
|
+
"""
|
|
4
|
+
from sqlalchemy import (
|
|
5
|
+
Column,
|
|
6
|
+
Integer,
|
|
7
|
+
String,
|
|
8
|
+
Text,
|
|
9
|
+
SmallInteger,
|
|
10
|
+
TIMESTAMP,
|
|
11
|
+
)
|
|
12
|
+
from sqlalchemy.dialects.postgresql import JSONB
|
|
13
|
+
from sqlalchemy.sql import func
|
|
14
|
+
from linglong_web import TableBase
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ServiceActionLogTbl(TableBase):
|
|
18
|
+
"""服务行为日志表"""
|
|
19
|
+
__tablename__ = 'service_action_log_tbl'
|
|
20
|
+
|
|
21
|
+
# 主键
|
|
22
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
23
|
+
|
|
24
|
+
# 业务字段
|
|
25
|
+
service_name = Column(String(100), nullable=False)
|
|
26
|
+
instance_id = Column(String(50))
|
|
27
|
+
action_type = Column(String(50), nullable=False)
|
|
28
|
+
action_status = Column(String(20), nullable=False)
|
|
29
|
+
action_detail = Column(JSONB, default={})
|
|
30
|
+
error_message = Column(Text)
|
|
31
|
+
triggered_by = Column(String(50), default='system')
|
|
32
|
+
action_metadata = Column(JSONB, default={})
|
|
33
|
+
|
|
34
|
+
# 标准字段
|
|
35
|
+
flag = Column(SmallInteger, default=0)
|
|
36
|
+
created_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp())
|
|
37
|
+
update_time = Column(TIMESTAMP(timezone=True), default=func.current_timestamp(), onupdate=func.current_timestamp())
|
|
38
|
+
|
|
39
|
+
__table_args__ = (
|
|
40
|
+
{'extend_existing': True},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def __repr__(self):
|
|
44
|
+
return f"ServiceActionLogTbl(id={self.id}, service={self.service_name}, action={self.action_type}, status={self.action_status})"
|