@oneuptime/common 14.0.0 → 14.0.1

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 (196) hide show
  1. package/Models/DatabaseModels/Index.ts +4 -0
  2. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +2 -0
  3. package/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.ts +522 -0
  4. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +38 -4
  5. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.ts +603 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.ts +248 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.ts +19 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  9. package/Server/Services/DatabaseService.ts +10 -0
  10. package/Server/Services/Index.ts +4 -0
  11. package/Server/Services/MonitorService.ts +3 -2
  12. package/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.ts +385 -0
  13. package/Server/Services/ServiceLevelObjectiveLabelRuleService.ts +51 -0
  14. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +92 -16
  15. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +36 -1
  16. package/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.ts +521 -0
  17. package/Server/Services/ServiceLevelObjectiveOwnerRuleService.ts +51 -0
  18. package/Server/Services/ServiceLevelObjectiveService.ts +28 -0
  19. package/Server/Types/Workflow/Components/Telegram/SendMessageToChat.ts +27 -1
  20. package/Server/Utils/AI/Toolbox/SloTools.ts +1 -0
  21. package/Server/Utils/Monitor/AffectedResourceList.ts +31 -73
  22. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +1 -1
  23. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +1 -1
  24. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +181 -136
  25. package/Server/Utils/Monitor/RootCauseList.ts +139 -0
  26. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +28 -0
  27. package/Server/Utils/Slo/SloRulePatternValidator.ts +42 -0
  28. package/Tests/App/Dashboard/FeedFilterSortIntegration.test.tsx +1632 -0
  29. package/Tests/App/Dashboard/FeedOptionsLocales.test.ts +250 -0
  30. package/Tests/App/Dashboard/FeedOrdering.test.ts +279 -9
  31. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +60 -1
  32. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +594 -3
  33. package/Tests/App/Dashboard/ProductOrientation.test.tsx +646 -0
  34. package/Tests/App/Dashboard/ResourceFeed.test.tsx +612 -2
  35. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +30 -0
  36. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +1202 -0
  37. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +52 -1
  38. package/Tests/App/Dashboard/SloFeed.test.tsx +106 -1
  39. package/Tests/App/Dashboard/SloMonitorRuleCriteria.test.tsx +566 -0
  40. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +6 -4
  41. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +186 -0
  42. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +388 -44
  43. package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +613 -0
  44. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +0 -8
  45. package/Tests/Models/DatabaseModels/SloLabelAndOwnerRuleModels.test.ts +404 -0
  46. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +17 -1
  47. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  48. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  49. package/Tests/Server/Infrastructure/Postgres/AddSloLabelAndOwnerRulesMigration.test.ts +407 -0
  50. package/Tests/Server/Infrastructure/Postgres/AddSloMonitorRuleMonitorTypeMigration.test.ts +171 -0
  51. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +88 -4
  52. package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +104 -0
  53. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +48 -1
  54. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -0
  55. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +1170 -0
  56. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleServices.test.ts +172 -0
  57. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +323 -0
  58. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +115 -0
  59. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleTriggers.test.ts +21 -2
  60. package/Tests/Server/Services/ServiceLevelObjectiveMonitorTypePostgres.test.ts +480 -0
  61. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +162 -0
  62. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +45 -6
  63. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +745 -0
  64. package/Tests/Server/Types/Markdown.test.ts +2 -1
  65. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +49 -0
  66. package/Tests/Server/Types/Workflow/Components/TelegramSendMessageToChat.test.ts +331 -0
  67. package/Tests/Server/Utils/AI/SloTools.test.ts +10 -0
  68. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +1 -1
  69. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +405 -0
  70. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +1101 -0
  71. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +106 -80
  72. package/Tests/Server/Utils/Monitor/RootCauseList.test.ts +252 -0
  73. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +154 -0
  74. package/Tests/Server/Utils/SSRFProtection.test.ts +111 -0
  75. package/Tests/Server/Utils/Slo/SloRulePatternValidator.test.ts +67 -0
  76. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +213 -0
  77. package/Tests/Types/API/Route.test.ts +56 -0
  78. package/Tests/Types/API/URLSchemeLikePath.test.ts +304 -0
  79. package/Tests/UI/Components/FeedOptions.test.ts +1404 -0
  80. package/Tests/UI/Components/FeedOptionsButton.test.tsx +2603 -0
  81. package/Tests/UI/Components/Icon.test.tsx +26 -0
  82. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  83. package/Tests/UI/Components/useFeedItemsViewKey.test.tsx +1017 -0
  84. package/Tests/UI/Components/useFeedOptions.test.tsx +1107 -0
  85. package/Tests/Utils/LabelRuleImportExport.test.ts +102 -0
  86. package/Tests/Utils/Slo/SloDuration.test.ts +115 -24
  87. package/Tests/Utils/Slo/SloHealth.test.ts +93 -10
  88. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +109 -0
  89. package/Tests/Utils/Slo/SloOverviewText.test.ts +64 -0
  90. package/Types/API/Route.ts +19 -2
  91. package/Types/API/URL.ts +26 -2
  92. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +6 -5
  93. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +9 -0
  94. package/Types/Permission.ts +90 -0
  95. package/Types/Rules/RuleCriteriaFieldRegistry.ts +11 -0
  96. package/Types/Rules/RuleRun.ts +4 -0
  97. package/UI/Components/Feed/FeedOptions.ts +427 -0
  98. package/UI/Components/Feed/FeedOptionsButton.tsx +692 -0
  99. package/UI/Components/Feed/useFeedItems.ts +28 -9
  100. package/UI/Components/Feed/useFeedOptions.ts +225 -0
  101. package/UI/Components/Icon/Icon.tsx +1 -1
  102. package/Utils/LabelRuleImportExport.ts +27 -9
  103. package/Utils/Monitor/MetricValueFormatter.ts +2 -2
  104. package/Utils/Rules/MonitorTypeRuleCriteria.ts +31 -0
  105. package/Utils/Slo/SloDuration.ts +22 -6
  106. package/Utils/Slo/SloHealth.ts +8 -7
  107. package/Utils/Slo/SloMonitorRuleCriteria.ts +33 -1
  108. package/Utils/Slo/SloOverviewText.ts +33 -0
  109. package/Utils/Slo/SloProjection.ts +4 -3
  110. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  111. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  112. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +2 -0
  113. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -1
  114. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js +530 -0
  115. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js.map +1 -0
  116. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +39 -4
  117. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -1
  118. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js +612 -0
  119. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js.map +1 -0
  120. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js +93 -0
  121. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js.map +1 -0
  122. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js +12 -0
  123. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js.map +1 -0
  124. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  125. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  126. package/build/dist/Server/Services/DatabaseService.js +7 -0
  127. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  128. package/build/dist/Server/Services/Index.js +4 -0
  129. package/build/dist/Server/Services/Index.js.map +1 -1
  130. package/build/dist/Server/Services/MonitorService.js +3 -2
  131. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  132. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js +295 -0
  133. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js.map +1 -0
  134. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js +56 -0
  135. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js.map +1 -0
  136. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +59 -14
  137. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  138. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +22 -1
  139. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -1
  140. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js +400 -0
  141. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js.map +1 -0
  142. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js +56 -0
  143. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js.map +1 -0
  144. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +21 -0
  145. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  146. package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js +20 -1
  147. package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js.map +1 -1
  148. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +1 -0
  149. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  150. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +22 -51
  151. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -1
  152. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +1 -1
  153. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +1 -1
  154. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +139 -109
  155. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  156. package/build/dist/Server/Utils/Monitor/RootCauseList.js +101 -0
  157. package/build/dist/Server/Utils/Monitor/RootCauseList.js.map +1 -0
  158. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +28 -0
  159. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  160. package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js +28 -0
  161. package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js.map +1 -0
  162. package/build/dist/Types/API/Route.js +18 -2
  163. package/build/dist/Types/API/Route.js.map +1 -1
  164. package/build/dist/Types/API/URL.js +23 -2
  165. package/build/dist/Types/API/URL.js.map +1 -1
  166. package/build/dist/Types/Permission.js +84 -0
  167. package/build/dist/Types/Permission.js.map +1 -1
  168. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +11 -0
  169. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  170. package/build/dist/Types/Rules/RuleRun.js +4 -0
  171. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  172. package/build/dist/UI/Components/Feed/FeedOptions.js +235 -0
  173. package/build/dist/UI/Components/Feed/FeedOptions.js.map +1 -0
  174. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +346 -0
  175. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -0
  176. package/build/dist/UI/Components/Feed/useFeedItems.js +17 -7
  177. package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -1
  178. package/build/dist/UI/Components/Feed/useFeedOptions.js +130 -0
  179. package/build/dist/UI/Components/Feed/useFeedOptions.js.map +1 -0
  180. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  181. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  182. package/build/dist/Utils/LabelRuleImportExport.js +22 -6
  183. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  184. package/build/dist/Utils/Monitor/MetricValueFormatter.js +2 -2
  185. package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js +18 -0
  186. package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js.map +1 -0
  187. package/build/dist/Utils/Slo/SloDuration.js +13 -5
  188. package/build/dist/Utils/Slo/SloDuration.js.map +1 -1
  189. package/build/dist/Utils/Slo/SloHealth.js +8 -7
  190. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  191. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +16 -1
  192. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -1
  193. package/build/dist/Utils/Slo/SloOverviewText.js +16 -0
  194. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -1
  195. package/build/dist/Utils/Slo/SloProjection.js.map +1 -1
  196. package/package.json +1 -1
@@ -0,0 +1,400 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import ServiceLevelObjective from "../../Models/DatabaseModels/ServiceLevelObjective";
11
+ import { ServiceLevelObjectiveFeedEventType } from "../../Models/DatabaseModels/ServiceLevelObjectiveFeed";
12
+ import ServiceLevelObjectiveOwnerTeam from "../../Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam";
13
+ import ServiceLevelObjectiveOwnerUser from "../../Models/DatabaseModels/ServiceLevelObjectiveOwnerUser";
14
+ import { Purple500 } from "../../Types/BrandColors";
15
+ import BadDataException from "../../Types/Exception/BadDataException";
16
+ import ObjectID from "../../Types/ObjectID";
17
+ import { escapeMarkdownInline } from "../../Utils/Markdown/MarkdownEscape";
18
+ import { MAX_RULES_EVALUATED_PER_PROJECT } from "../../Utils/Rules/RuleEngineLimits";
19
+ import { RuleCriteriaMatcher } from "../../Utils/Rules/RuleCriteriaMatcher";
20
+ import RulePatternMatchUtil from "../../Utils/Rules/RulePatternMatchUtil";
21
+ import logger from "../Utils/Logger";
22
+ import OwnerRuleAssignment from "../Utils/Rules/OwnerRuleAssignment";
23
+ import logIfRuleReadWasTruncated from "../Utils/Rules/RuleEngineRuleRead";
24
+ import { RuleApplicationResultUtil, } from "../Utils/Rules/RuleRun/RuleApplication";
25
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
26
+ import ServiceLevelObjectiveFeedService from "./ServiceLevelObjectiveFeedService";
27
+ import ServiceLevelObjectiveOwnerRuleService from "./ServiceLevelObjectiveOwnerRuleService";
28
+ import ServiceLevelObjectiveOwnerTeamService from "./ServiceLevelObjectiveOwnerTeamService";
29
+ import ServiceLevelObjectiveOwnerUserService from "./ServiceLevelObjectiveOwnerUserService";
30
+ import ServiceLevelObjectiveService from "./ServiceLevelObjectiveService";
31
+ // What adding one owner row did.
32
+ var OwnerWriteOutcome;
33
+ (function (OwnerWriteOutcome) {
34
+ OwnerWriteOutcome["Added"] = "Added";
35
+ OwnerWriteOutcome["AlreadyOwner"] = "AlreadyOwner";
36
+ OwnerWriteOutcome["Rejected"] = "Rejected";
37
+ })(OwnerWriteOutcome || (OwnerWriteOutcome = {}));
38
+ class ServiceLevelObjectiveOwnerRuleEngineServiceClass {
39
+ constructor() {
40
+ this.ruleSelect = {
41
+ _id: true,
42
+ name: true,
43
+ criteria: true,
44
+ notifyOwners: true,
45
+ serviceLevelObjectiveLabels: { _id: true },
46
+ serviceLevelObjectiveNamePattern: true,
47
+ serviceLevelObjectiveDescriptionPattern: true,
48
+ ownerUsers: { _id: true },
49
+ ownerTeams: { _id: true },
50
+ };
51
+ // Evaluation re-reads the SLO, so a run only has to name it.
52
+ this.resourceSelectForRuleRun = {
53
+ _id: true,
54
+ projectId: true,
55
+ };
56
+ }
57
+ /**
58
+ * Evaluates ServiceLevelObjectiveOwnerRule rows for the given SLO and adds
59
+ * matched owner users / teams through the SLO owner services, so each one
60
+ * gets the usual owner-added feed item and notification. Rules with
61
+ * notifyOwners set notify the added owners; rules with notifyOwners off add
62
+ * silently.
63
+ */
64
+ async applyRulesToServiceLevelObjective(serviceLevelObjective) {
65
+ var _a, _b;
66
+ if (!serviceLevelObjective.id || !serviceLevelObjective.projectId) {
67
+ return;
68
+ }
69
+ try {
70
+ const rules = await ServiceLevelObjectiveOwnerRuleService.findBy({
71
+ query: {
72
+ projectId: serviceLevelObjective.projectId,
73
+ isEnabled: true,
74
+ },
75
+ props: { isRoot: true },
76
+ select: this.ruleSelect,
77
+ limit: MAX_RULES_EVALUATED_PER_PROJECT,
78
+ skip: 0,
79
+ });
80
+ logIfRuleReadWasTruncated({
81
+ ruleKind: "ServiceLevelObjectiveOwnerRule",
82
+ projectId: serviceLevelObjective.projectId,
83
+ rulesRead: rules.length,
84
+ });
85
+ if (rules.length === 0) {
86
+ return;
87
+ }
88
+ await this.applyRules({
89
+ serviceLevelObjective: serviceLevelObjective,
90
+ rules: rules,
91
+ allowOwnerNotification: true,
92
+ });
93
+ }
94
+ catch (error) {
95
+ logger.error(`Error applying SLO owner rules: ${error}`, {
96
+ projectId: (_a = serviceLevelObjective.projectId) === null || _a === void 0 ? void 0 : _a.toString(),
97
+ serviceLevelObjectiveId: (_b = serviceLevelObjective.id) === null || _b === void 0 ? void 0 : _b.toString(),
98
+ });
99
+ }
100
+ }
101
+ /*
102
+ * "Run now": the same evaluation, for an SLO that already exists and only
103
+ * the rules being run.
104
+ */
105
+ async applyRulesToExistingResource(data) {
106
+ var _a, _b;
107
+ try {
108
+ return await this.applyRules({
109
+ serviceLevelObjective: data.resource,
110
+ rules: data.rules,
111
+ allowOwnerNotification: data.allowOwnerNotification,
112
+ });
113
+ }
114
+ catch (error) {
115
+ logger.error(`Error running SLO owner rules: ${error}`, {
116
+ projectId: (_a = data.resource.projectId) === null || _a === void 0 ? void 0 : _a.toString(),
117
+ serviceLevelObjectiveId: (_b = data.resource.id) === null || _b === void 0 ? void 0 : _b.toString(),
118
+ });
119
+ return RuleApplicationResultUtil.failed();
120
+ }
121
+ }
122
+ async applyRules(data) {
123
+ const { serviceLevelObjective, rules } = data;
124
+ if (!serviceLevelObjective.id ||
125
+ !serviceLevelObjective.projectId ||
126
+ rules.length === 0) {
127
+ return RuleApplicationResultUtil.noMatch();
128
+ }
129
+ const sloWithDetails = await ServiceLevelObjectiveService.findOneById({
130
+ id: serviceLevelObjective.id,
131
+ select: {
132
+ name: true,
133
+ description: true,
134
+ labels: { _id: true },
135
+ },
136
+ props: { isRoot: true },
137
+ });
138
+ if (!sloWithDetails) {
139
+ return RuleApplicationResultUtil.noMatch();
140
+ }
141
+ const usersByNotify = new Map([
142
+ [true, new Set()],
143
+ [false, new Set()],
144
+ ]);
145
+ const teamsByNotify = new Map([
146
+ [true, new Set()],
147
+ [false, new Set()],
148
+ ]);
149
+ const matchedRules = [];
150
+ const allUserIds = new Set();
151
+ const allTeamIds = new Set();
152
+ let anyRuleMatched = false;
153
+ for (const rule of rules) {
154
+ if (!this.doesServiceLevelObjectiveMatchRule(sloWithDetails, rule)) {
155
+ continue;
156
+ }
157
+ anyRuleMatched = true;
158
+ let ruleAddedAny = false;
159
+ const notify = rule.notifyOwners !== false && data.allowOwnerNotification;
160
+ for (const user of rule.ownerUsers || []) {
161
+ if (user.id) {
162
+ usersByNotify.get(notify).add(user.id.toString());
163
+ allUserIds.add(user.id.toString());
164
+ ruleAddedAny = true;
165
+ }
166
+ }
167
+ for (const team of rule.ownerTeams || []) {
168
+ if (team.id) {
169
+ teamsByNotify.get(notify).add(team.id.toString());
170
+ allTeamIds.add(team.id.toString());
171
+ ruleAddedAny = true;
172
+ }
173
+ }
174
+ if (ruleAddedAny) {
175
+ matchedRules.push(rule);
176
+ }
177
+ }
178
+ if (!anyRuleMatched) {
179
+ return RuleApplicationResultUtil.noMatch();
180
+ }
181
+ // The rules that matched name no owners, so there is nothing to add.
182
+ if (matchedRules.length === 0) {
183
+ return RuleApplicationResultUtil.alreadyApplied();
184
+ }
185
+ // Owners already on the SLO are skipped rather than duplicated.
186
+ const notYetAssigned = await OwnerRuleAssignment.getOwnersNotYetAssigned({
187
+ ownerUserService: ServiceLevelObjectiveOwnerUserService,
188
+ ownerTeamService: ServiceLevelObjectiveOwnerTeamService,
189
+ resourceIdColumn: "serviceLevelObjectiveId",
190
+ resourceId: serviceLevelObjective.id,
191
+ userIds: Array.from(allUserIds),
192
+ teamIds: Array.from(allTeamIds),
193
+ });
194
+ const userIdsToAdd = new Set(notYetAssigned.userIds.map((id) => {
195
+ return id.toString();
196
+ }));
197
+ const teamIdsToAdd = new Set(notYetAssigned.teamIds.map((id) => {
198
+ return id.toString();
199
+ }));
200
+ let ownersAdded = 0;
201
+ let ownersRejected = 0;
202
+ const count = (outcome) => {
203
+ if (outcome === OwnerWriteOutcome.Added) {
204
+ ownersAdded++;
205
+ }
206
+ else if (outcome === OwnerWriteOutcome.Rejected) {
207
+ ownersRejected++;
208
+ }
209
+ };
210
+ /*
211
+ * The notifying set goes first, so an owner two matching rules disagree
212
+ * about is added once, and notified.
213
+ */
214
+ for (const notify of [true, false]) {
215
+ const userIds = Array.from(usersByNotify.get(notify)).filter((id) => {
216
+ return userIdsToAdd.delete(id);
217
+ });
218
+ const teamIds = Array.from(teamsByNotify.get(notify)).filter((id) => {
219
+ return teamIdsToAdd.delete(id);
220
+ });
221
+ for (const userId of userIds) {
222
+ const owner = new ServiceLevelObjectiveOwnerUser();
223
+ owner.serviceLevelObjectiveId = serviceLevelObjective.id;
224
+ owner.projectId = serviceLevelObjective.projectId;
225
+ owner.userId = new ObjectID(userId);
226
+ owner.isOwnerNotified = !notify;
227
+ count(await this.addOwner({
228
+ ownerService: ServiceLevelObjectiveOwnerUserService,
229
+ owner: owner,
230
+ serviceLevelObjective: serviceLevelObjective,
231
+ }));
232
+ }
233
+ for (const teamId of teamIds) {
234
+ const owner = new ServiceLevelObjectiveOwnerTeam();
235
+ owner.serviceLevelObjectiveId = serviceLevelObjective.id;
236
+ owner.projectId = serviceLevelObjective.projectId;
237
+ owner.teamId = new ObjectID(teamId);
238
+ owner.isOwnerNotified = !notify;
239
+ count(await this.addOwner({
240
+ ownerService: ServiceLevelObjectiveOwnerTeamService,
241
+ owner: owner,
242
+ serviceLevelObjective: serviceLevelObjective,
243
+ }));
244
+ }
245
+ }
246
+ if (ownersAdded === 0) {
247
+ /*
248
+ * Every owner the rules name was refused - a user who has since left the
249
+ * project, say. Nothing was added, and "already applied" would claim the
250
+ * SLO has owners it does not, so report the SLO as one the run could not
251
+ * update.
252
+ */
253
+ return ownersRejected > 0
254
+ ? RuleApplicationResultUtil.failed()
255
+ : RuleApplicationResultUtil.alreadyApplied();
256
+ }
257
+ logger.debug(`ServiceLevelObjectiveOwnerRuleEngine added owners to SLO ${serviceLevelObjective.id}`, {
258
+ projectId: serviceLevelObjective.projectId.toString(),
259
+ });
260
+ await this.postOwnerRuleFeedItem({
261
+ serviceLevelObjectiveId: serviceLevelObjective.id,
262
+ projectId: serviceLevelObjective.projectId,
263
+ sloName: sloWithDetails.name,
264
+ matchedRules: matchedRules,
265
+ });
266
+ return RuleApplicationResultUtil.updated(ownersAdded);
267
+ }
268
+ /*
269
+ * SLO owner services refuse a user who is not a member of the project, or a
270
+ * team from another one (see SloOwnerReferenceValidator) - which a rule can
271
+ * still name after the user left, or when it was written through the API.
272
+ * That owner is skipped so the rule's other owners are still added; any
273
+ * other failure is thrown as before.
274
+ */
275
+ async addOwner(data) {
276
+ var _a, _b;
277
+ try {
278
+ const added = await OwnerRuleAssignment.createOwner({
279
+ ownerService: data.ownerService,
280
+ owner: data.owner,
281
+ props: { isRoot: true },
282
+ });
283
+ return added ? OwnerWriteOutcome.Added : OwnerWriteOutcome.AlreadyOwner;
284
+ }
285
+ catch (error) {
286
+ if (!(error instanceof BadDataException)) {
287
+ throw error;
288
+ }
289
+ logger.warn(`SLO owner rule could not add an owner to SLO ${(_a = data.serviceLevelObjective.id) === null || _a === void 0 ? void 0 : _a.toString()}: ${error.message}`, {
290
+ projectId: (_b = data.serviceLevelObjective.projectId) === null || _b === void 0 ? void 0 : _b.toString(),
291
+ });
292
+ return OwnerWriteOutcome.Rejected;
293
+ }
294
+ }
295
+ /*
296
+ * The individual OwnerUserAdded / OwnerTeamAdded items say who was added;
297
+ * this one says which rule is responsible, which is what somebody asking
298
+ * "why am I on the hook for this SLO?" actually needs. The owners are
299
+ * already added by now, so a feed failure is logged, never thrown.
300
+ */
301
+ async postOwnerRuleFeedItem(data) {
302
+ try {
303
+ const sloLink = await ServiceLevelObjectiveService.getSloMarkdownLink({
304
+ projectId: data.projectId,
305
+ sloId: data.serviceLevelObjectiveId,
306
+ sloName: data.sloName,
307
+ });
308
+ await ServiceLevelObjectiveFeedService.createServiceLevelObjectiveFeedItem({
309
+ serviceLevelObjectiveId: data.serviceLevelObjectiveId,
310
+ projectId: data.projectId,
311
+ serviceLevelObjectiveFeedEventType: ServiceLevelObjectiveFeedEventType.OwnerRuleExecuted,
312
+ displayColor: Purple500,
313
+ feedInfoInMarkdown: `👥 Owners were added to ${sloLink} by ${data.matchedRules.length} owner ${data.matchedRules.length === 1 ? "rule" : "rules"}.`,
314
+ moreInformationInMarkdown: `**Owner rules that matched**: ${data.matchedRules
315
+ .map((rule) => {
316
+ var _a;
317
+ // Rule names are user-controlled and the feed renders markdown.
318
+ return `**${escapeMarkdownInline(rule.name || ((_a = rule.id) === null || _a === void 0 ? void 0 : _a.toString()) || "Unnamed rule")}**`;
319
+ })
320
+ .join(", ")}`,
321
+ });
322
+ }
323
+ catch (error) {
324
+ logger.error(`Error writing the owner rule feed item for SLO ${data.serviceLevelObjectiveId.toString()}: ${error}`, { projectId: data.projectId.toString() });
325
+ }
326
+ }
327
+ doesServiceLevelObjectiveMatchRule(serviceLevelObjective, rule) {
328
+ return RuleCriteriaMatcher.matchesWithLegacySync({
329
+ rule,
330
+ legacyFields: [
331
+ "serviceLevelObjectiveLabels",
332
+ "serviceLevelObjectiveNamePattern",
333
+ "serviceLevelObjectiveDescriptionPattern",
334
+ ],
335
+ emptyResult: true,
336
+ matchesLegacyRule: (legacyRule) => {
337
+ return this.doesServiceLevelObjectiveMatchLegacyRule(serviceLevelObjective, legacyRule);
338
+ },
339
+ });
340
+ }
341
+ doesServiceLevelObjectiveMatchLegacyRule(serviceLevelObjective, rule) {
342
+ if (rule.serviceLevelObjectiveLabels &&
343
+ rule.serviceLevelObjectiveLabels.length > 0) {
344
+ if (!serviceLevelObjective.labels ||
345
+ serviceLevelObjective.labels.length === 0) {
346
+ return false;
347
+ }
348
+ const ruleLabelIds = rule.serviceLevelObjectiveLabels.map((l) => {
349
+ var _a;
350
+ return ((_a = l.id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
351
+ });
352
+ const labelIds = serviceLevelObjective.labels.map((l) => {
353
+ var _a;
354
+ return ((_a = l.id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
355
+ });
356
+ if (!ruleLabelIds.some((id) => {
357
+ return labelIds.includes(id);
358
+ })) {
359
+ return false;
360
+ }
361
+ }
362
+ if (rule.serviceLevelObjectiveNamePattern &&
363
+ (!serviceLevelObjective.name ||
364
+ !this.testPattern(rule.serviceLevelObjectiveNamePattern, serviceLevelObjective.name, rule))) {
365
+ return false;
366
+ }
367
+ if (rule.serviceLevelObjectiveDescriptionPattern &&
368
+ (!serviceLevelObjective.description ||
369
+ !this.testPattern(rule.serviceLevelObjectiveDescriptionPattern, serviceLevelObjective.description, rule))) {
370
+ return false;
371
+ }
372
+ return true;
373
+ }
374
+ /*
375
+ * Patterns are regexes, with a '*' wildcard fallback - the same two syntaxes
376
+ * the SLO monitor rules take. SloRulePatternValidator rejects anything else
377
+ * on save, so this only warns about a rule written before that check.
378
+ */
379
+ testPattern(pattern, value, rule) {
380
+ if (!RulePatternMatchUtil.isSupportedPattern(pattern)) {
381
+ logger.warn(`Invalid pattern in SLO owner rule ${rule.id}: ${pattern}. It is neither a valid regular expression nor a wildcard pattern, so it will never match.`);
382
+ return false;
383
+ }
384
+ return RulePatternMatchUtil.matches(value, pattern);
385
+ }
386
+ }
387
+ __decorate([
388
+ CaptureSpan(),
389
+ __metadata("design:type", Function),
390
+ __metadata("design:paramtypes", [ServiceLevelObjective]),
391
+ __metadata("design:returntype", Promise)
392
+ ], ServiceLevelObjectiveOwnerRuleEngineServiceClass.prototype, "applyRulesToServiceLevelObjective", null);
393
+ __decorate([
394
+ CaptureSpan(),
395
+ __metadata("design:type", Function),
396
+ __metadata("design:paramtypes", [Object]),
397
+ __metadata("design:returntype", Promise)
398
+ ], ServiceLevelObjectiveOwnerRuleEngineServiceClass.prototype, "applyRulesToExistingResource", null);
399
+ export default new ServiceLevelObjectiveOwnerRuleEngineServiceClass();
400
+ //# sourceMappingURL=ServiceLevelObjectiveOwnerRuleEngineService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceLevelObjectiveOwnerRuleEngineService.js","sourceRoot":"","sources":["../../../../Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import DatabaseService from "./DatabaseService";
11
+ import Model from "../../Models/DatabaseModels/ServiceLevelObjectiveOwnerRule";
12
+ import SloRulePatternValidator from "../Utils/Slo/SloRulePatternValidator";
13
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
14
+ /*
15
+ * No hard-delete retention: a rule is configuration, not an event log, so it
16
+ * stays until somebody deletes it.
17
+ */
18
+ export class Service extends DatabaseService {
19
+ constructor() {
20
+ super(Model);
21
+ }
22
+ /*
23
+ * A pattern that is neither a valid regex nor a wildcard can only ever match
24
+ * nothing, and the rule engine has no way to say so - it just quietly stops
25
+ * assigning owners. Reject it while the user is still looking at the form.
26
+ */
27
+ async onBeforeCreate(createBy) {
28
+ SloRulePatternValidator.validate({
29
+ namePattern: createBy.data.serviceLevelObjectiveNamePattern,
30
+ descriptionPattern: createBy.data.serviceLevelObjectiveDescriptionPattern,
31
+ });
32
+ return { createBy: createBy, carryForward: null };
33
+ }
34
+ async onBeforeUpdate(updateBy) {
35
+ SloRulePatternValidator.validate({
36
+ namePattern: updateBy.data.serviceLevelObjectiveNamePattern,
37
+ descriptionPattern: updateBy.data
38
+ .serviceLevelObjectiveDescriptionPattern,
39
+ });
40
+ return { updateBy: updateBy, carryForward: null };
41
+ }
42
+ }
43
+ __decorate([
44
+ CaptureSpan(),
45
+ __metadata("design:type", Function),
46
+ __metadata("design:paramtypes", [Object]),
47
+ __metadata("design:returntype", Promise)
48
+ ], Service.prototype, "onBeforeCreate", null);
49
+ __decorate([
50
+ CaptureSpan(),
51
+ __metadata("design:type", Function),
52
+ __metadata("design:paramtypes", [Object]),
53
+ __metadata("design:returntype", Promise)
54
+ ], Service.prototype, "onBeforeUpdate", null);
55
+ export default new Service();
56
+ //# sourceMappingURL=ServiceLevelObjectiveOwnerRuleService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceLevelObjectiveOwnerRuleService.js","sourceRoot":"","sources":["../../../../Server/Services/ServiceLevelObjectiveOwnerRuleService.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,MAAM,4DAA4D,CAAC;AAI/E,OAAO,uBAAuB,MAAM,sCAAsC,CAAC;AAC3E,OAAO,WAAW,MAAM,gCAAgC,CAAC;AAEzD;;;GAGG;AACH,MAAM,OAAO,OAAQ,SAAQ,eAAsB;IACjD;QACE,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;IAED;;;;OAIG;IAEsB,AAAN,KAAK,CAAC,cAAc,CACrC,QAAyB;QAEzB,uBAAuB,CAAC,QAAQ,CAAC;YAC/B,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,gCAAgC;YAC3D,kBAAkB,EAAE,QAAQ,CAAC,IAAI,CAAC,uCAAuC;SAC1E,CAAC,CAAC;QAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;IAGwB,AAAN,KAAK,CAAC,cAAc,CACrC,QAAyB;QAEzB,uBAAuB,CAAC,QAAQ,CAAC;YAC/B,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,gCAEd;YACb,kBAAkB,EAAE,QAAQ,CAAC,IAAI;iBAC9B,uCAA6D;SACjE,CAAC,CAAC;QAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;CACF;AAzB0B;IADxB,WAAW,EAAE;;;;6CAUb;AAGwB;IADxB,WAAW,EAAE;;;;6CAab;AAGH,eAAe,IAAI,OAAO,EAAE,CAAC"}
@@ -27,6 +27,8 @@ import DatabaseService from "./DatabaseService";
27
27
  import MonitorStatusService from "./MonitorStatusService";
28
28
  import ProjectService from "./ProjectService";
29
29
  import ServiceLevelObjectiveBurnRateRuleService from "./ServiceLevelObjectiveBurnRateRuleService";
30
+ import ServiceLevelObjectiveLabelRuleEngineService from "./ServiceLevelObjectiveLabelRuleEngineService";
31
+ import ServiceLevelObjectiveOwnerRuleEngineService from "./ServiceLevelObjectiveOwnerRuleEngineService";
30
32
  import ServiceLevelObjectiveMonitorRuleEngineService from "./ServiceLevelObjectiveMonitorRuleEngineService";
31
33
  import ServiceLevelObjectiveMonitorRuleService from "./ServiceLevelObjectiveMonitorRuleService";
32
34
  import ServiceLevelObjectiveOwnerTeamService from "./ServiceLevelObjectiveOwnerTeamService";
@@ -183,6 +185,25 @@ export class Service extends DatabaseService {
183
185
  catch (err) {
184
186
  logger.error(`Error applying the monitor rules for SLO ${(_e = createdItem.id) === null || _e === void 0 ? void 0 : _e.toString()}: ${err}`, { projectId: (_f = createdItem.projectId) === null || _f === void 0 ? void 0 : _f.toString() });
185
187
  }
188
+ /*
189
+ * Label rules first, so the labels they attach are persisted - and on
190
+ * createdItem - before owner rules run: an owner rule can then key on a
191
+ * rule-added label. Fire-and-forget, like every other resource's rules: a
192
+ * rule must never slow down or fail the create.
193
+ */
194
+ if (createdItem.projectId && createdItem.id) {
195
+ Promise.resolve()
196
+ .then(async () => {
197
+ await ServiceLevelObjectiveLabelRuleEngineService.applyRulesToServiceLevelObjective(createdItem);
198
+ })
199
+ .then(async () => {
200
+ await ServiceLevelObjectiveOwnerRuleEngineService.applyRulesToServiceLevelObjective(createdItem);
201
+ })
202
+ .catch((err) => {
203
+ var _a, _b;
204
+ logger.error(`Error applying the label and owner rules for SLO ${(_a = createdItem.id) === null || _a === void 0 ? void 0 : _a.toString()}: ${err}`, { projectId: (_b = createdItem.projectId) === null || _b === void 0 ? void 0 : _b.toString() });
205
+ });
206
+ }
186
207
  /*
187
208
  * Fire-and-forget, like ServiceService's created item: the SLO exists
188
209
  * whether or not its feed item does, and the create request should not