S8RuleCreationPolicy.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using Admin.NET.Plugin.AiDOP.Entity.S8;
  2. namespace Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess;
  3. /// <summary>
  4. /// 规则创建来源。用于区分"调用方自带 SQL"与"服务端按字典生成 SQL",
  5. /// 因为两者的技术债性质与安全面完全不同。
  6. /// </summary>
  7. public static class S8RuleCreationOrigin
  8. {
  9. /// <summary>
  10. /// 裸 REST 创建(<c>POST /api/aidop/s8/config/watch-rules</c>):调用方可自带任意 expression。
  11. /// 这是新增 SQL 技术债的来源,也是注入面。
  12. /// </summary>
  13. public const string ExternalApi = "EXTERNAL_API";
  14. /// <summary>
  15. /// 配置向导生成(<c>S8ConfigDraftService.GenerateRuleAsync</c>):
  16. /// SQL 由服务端按 <c>ado_s8_monitor_object</c> / <c>ado_s8_monitor_metric</c> 字典生成,
  17. /// 标识符经 ValidateSqlIdentifier 白名单校验,调用方不提供 SQL 文本。
  18. /// </summary>
  19. public const string WizardGenerated = "WIZARD_GENERATED";
  20. }
  21. /// <summary>
  22. /// S8-LEGACY-SQL-RESIDUAL-CLEANUP-3:新增 SQL 技术债的治理策略。
  23. ///
  24. /// <b>为什么不是"一刀切禁止 LEGACY_SQL"</b>:取证显示配置向导
  25. /// (<c>wizard-drafts/{id}/generate-rule</c> → <c>S8WatchRuleService.CreateAsync</c>)
  26. /// 仍是在产的规则创建流程,且它生成的正是 LEGACY_SQL 规则。直接封死会阻断在用业务流程。
  27. ///
  28. /// 因此按来源分治:掐断"调用方自带 SQL",保留"服务端字典生成",
  29. /// 待向导迁移到 STANDARD_DATASET 后再收口最后一条通道。
  30. ///
  31. /// <b>本策略只作用于"新建"</b>:历史规则的启停与维护不受约束,
  32. /// 否则数据源一出问题,存量规则将再也无法被关停。
  33. /// </summary>
  34. public static class S8RuleCreationPolicy
  35. {
  36. /// <summary>拒绝新增裸 SQL 规则时使用的 reason code。</summary>
  37. public const string LegacySqlCreationDisabledReason = "legacy_sql_creation_disabled";
  38. /// <summary>
  39. /// 新建规则时的取数模式治理。
  40. /// 未知来源按 <see cref="S8RuleCreationOrigin.ExternalApi"/> 处理(fail-closed):
  41. /// 将来新增调用方若忘记声明来源,会被拦下而不是意外获得放行。
  42. /// </summary>
  43. public static void EnsureCreationAllowed(AdoS8WatchRule rule, string? origin)
  44. {
  45. // STANDARD_DATASET 是鼓励方向,任何来源都放行。
  46. if (S8DataAccessMode.IsAcceptable(rule.DataAccessMode)
  47. && S8DataAccessMode.Resolve(rule.DataAccessMode) == S8DataAccessMode.StandardDataset)
  48. return;
  49. if (string.Equals(origin, S8RuleCreationOrigin.WizardGenerated, StringComparison.Ordinal))
  50. return;
  51. throw new S8BizException(
  52. $"[{LegacySqlCreationDisabledReason}] 不再接受新建自带 SQL 的监控规则。" +
  53. $"请改用 data_access_mode={S8DataAccessMode.StandardDataset} 并引用已注册的 dataset_code;" +
  54. "历史 LEGACY_SQL 规则仍可正常运行与维护。");
  55. }
  56. /// <summary>
  57. /// 存量规则维护(启用 / 停用 / 改参数)时的治理。
  58. /// 当前对两个方向都放行——治理目标是"不再新增旧债",不是"让旧债无法维护"。
  59. /// 保留此入口是为了让边界显式:将来若要收紧,改这里而不是散落到各 service。
  60. /// </summary>
  61. public static void EnsureMaintenanceAllowed(AdoS8WatchRule rule, bool enabling)
  62. {
  63. // 刻意为空:存量 LEGACY_SQL 规则的启停不受创建治理约束。
  64. _ = rule;
  65. _ = enabling;
  66. }
  67. }