@oneuptime/common 12.0.1 → 12.0.3
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.
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
- package/Models/DatabaseModels/Host.ts +12 -4
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
- package/Models/DatabaseModels/KubernetesResource.ts +8 -7
- package/Models/DatabaseModels/LogDropFilter.ts +9 -20
- package/Models/DatabaseModels/PodmanResource.ts +6 -6
- package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
- package/Models/DatabaseModels/StatusPage.ts +95 -0
- package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
- package/Models/DatabaseModels/StatusPageResource.ts +73 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
- package/Server/API/BaseAPI.ts +13 -2
- package/Server/API/DashboardAPI.ts +39 -0
- package/Server/API/TeamMemberAPI.ts +85 -0
- package/Server/EnvironmentConfig.ts +31 -1
- package/Server/Infrastructure/GlobalCache.ts +115 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/ProjectAuthorization.ts +66 -4
- package/Server/Services/AlertStateTimelineService.ts +20 -0
- package/Server/Services/BillingService.ts +600 -51
- package/Server/Services/CephClusterService.ts +27 -45
- package/Server/Services/CephResourceService.ts +43 -4
- package/Server/Services/CloudResourceService.ts +24 -42
- package/Server/Services/DatabaseService.ts +198 -6
- package/Server/Services/DockerHostService.ts +20 -38
- package/Server/Services/DockerResourceService.ts +62 -8
- package/Server/Services/DockerSwarmClusterService.ts +28 -46
- package/Server/Services/DockerSwarmResourceService.ts +53 -4
- package/Server/Services/HostService.ts +47 -57
- package/Server/Services/IncidentStateTimelineService.ts +20 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTDeviceService.ts +1 -17
- package/Server/Services/IoTFleetService.ts +20 -38
- package/Server/Services/KubernetesClusterService.ts +18 -36
- package/Server/Services/KubernetesContainerService.ts +50 -9
- package/Server/Services/KubernetesResourceService.ts +53 -7
- package/Server/Services/LabelService.ts +153 -1
- package/Server/Services/MetricTypeService.ts +84 -0
- package/Server/Services/MonitorService.ts +146 -14
- package/Server/Services/MonitorStatusTimelineService.ts +29 -0
- package/Server/Services/MonitorTemplateService.ts +65 -0
- package/Server/Services/PodmanHostService.ts +20 -38
- package/Server/Services/PodmanResourceService.ts +62 -8
- package/Server/Services/ProjectService.ts +165 -35
- package/Server/Services/ProxmoxClusterService.ts +24 -42
- package/Server/Services/ProxmoxResourceService.ts +43 -4
- package/Server/Services/RumApplicationService.ts +20 -38
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
- package/Server/Services/ServerlessFunctionService.ts +25 -43
- package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
- package/Server/Services/ServiceService.ts +299 -73
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
- package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
- package/Server/Services/StatusPageService.ts +95 -36
- package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
- package/Server/Services/StatusPageSubscriberService.ts +3 -0
- package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
- package/Server/Services/TelemetryEntityService.ts +1 -0
- package/Server/Types/Database/JSONColumnQuery.ts +621 -0
- package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
- package/Server/Types/Database/QueryHelper.ts +17 -32
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
- package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
- package/Server/Utils/Monitor/MonitorResource.ts +63 -36
- package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
- package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
- package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
- package/Server/Utils/SingleFlight.ts +83 -0
- package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
- package/Server/Utils/Telemetry/Telemetry.ts +351 -122
- package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
- package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
- package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
- package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
- package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +226 -0
- package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
- package/Tests/Server/Services/BillingService.test.ts +78 -3
- package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
- package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
- package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +658 -0
- package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
- package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
- package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
- package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
- package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
- package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +636 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
- package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
- package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
- package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
- package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
- package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
- package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
- package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
- package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
- package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
- package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
- package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
- package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
- package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
- package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
- package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
- package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
- package/Tests/Types/Decimal.test.ts +37 -0
- package/Tests/Types/Events/Recurring.test.ts +157 -0
- package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
- package/Tests/Types/Port.test.ts +38 -0
- package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
- package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
- package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
- package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
- package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
- package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
- package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
- package/Types/CustomField/CustomFieldDefinition.ts +24 -0
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
- package/Types/Dashboard/DashboardTemplates.ts +397 -0
- package/Types/Database/BigIntColumnTransformer.ts +74 -0
- package/Types/Database/DatabaseProperty.ts +26 -0
- package/Types/Database/NumericColumnValue.ts +128 -0
- package/Types/Date.ts +112 -0
- package/Types/Decimal.ts +16 -4
- package/Types/Events/Recurring.ts +99 -1
- package/Types/Permission.ts +48 -0
- package/Types/Port.ts +16 -4
- package/Types/StatusPage/StatusPageReport.ts +11 -0
- package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
- package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
- package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
- package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
- package/UI/Utils/TeamMembersByUser.ts +302 -0
- package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/StatusPage/ReportPeriod.ts +236 -0
- package/Utils/Telemetry/HostIpAddresses.ts +98 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +12 -4
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
- package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
- package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
- package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +11 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +39 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +57 -2
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +27 -1
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +91 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +466 -36
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +26 -39
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/CephResourceService.js +28 -3
- package/build/dist/Server/Services/CephResourceService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceService.js +23 -36
- package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +155 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +19 -32
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerResourceService.js +34 -4
- package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -40
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
- package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +58 -64
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceService.js +1 -8
- package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetService.js +19 -32
- package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +17 -30
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
- package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
- package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +127 -0
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/MetricTypeService.js +74 -0
- package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +128 -9
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +19 -32
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/PodmanResourceService.js +34 -4
- package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +135 -21
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +23 -36
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationService.js +19 -32
- package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionService.js +24 -37
- package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +236 -61
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageService.js +69 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
- package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
- package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
- package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
- package/build/dist/Server/Utils/SingleFlight.js +76 -0
- package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
- package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
- package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
- package/build/dist/Types/Database/DatabaseProperty.js +25 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/NumericColumnValue.js +97 -0
- package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
- package/build/dist/Types/Date.js +68 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Decimal.js +14 -3
- package/build/dist/Types/Decimal.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +63 -0
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Port.js +15 -5
- package/build/dist/Types/Port.js.map +1 -1
- package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
- package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
- package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
- package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/StatusPage/ReportPeriod.js +131 -0
- package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
- package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
- package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/tsconfig.json +12 -1
|
@@ -0,0 +1,401 @@
|
|
|
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 StatusPageMonitorRuleEngineService from "./StatusPageMonitorRuleEngineService";
|
|
12
|
+
import StatusPageGroupService from "./StatusPageGroupService";
|
|
13
|
+
import StatusPageResourceService from "./StatusPageResourceService";
|
|
14
|
+
import StatusPageService from "./StatusPageService";
|
|
15
|
+
import Model from "../../Models/DatabaseModels/StatusPageMonitorRule";
|
|
16
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
17
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
18
|
+
import ObjectID from "../../Types/ObjectID";
|
|
19
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
20
|
+
import ProjectScopedReferenceValidator, { resolveReferenceId, } from "../Utils/Database/ProjectScopedReferenceValidator";
|
|
21
|
+
import StatusPageMonitorRulePatternValidator from "../Utils/StatusPage/MonitorRulePatternValidator";
|
|
22
|
+
import logger from "../Utils/Logger";
|
|
23
|
+
export class Service extends DatabaseService {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(Model);
|
|
26
|
+
}
|
|
27
|
+
async onBeforeCreate(createBy) {
|
|
28
|
+
if (!createBy.data.statusPageId) {
|
|
29
|
+
throw new BadDataException("Status Page ID is required to create a status page monitor rule.");
|
|
30
|
+
}
|
|
31
|
+
this.assertHasMatchCriteria({
|
|
32
|
+
monitorLabelCount: (createBy.data.monitorLabels || []).length,
|
|
33
|
+
monitorNamePattern: createBy.data.monitorNamePattern,
|
|
34
|
+
monitorDescriptionPattern: createBy.data.monitorDescriptionPattern,
|
|
35
|
+
});
|
|
36
|
+
StatusPageMonitorRulePatternValidator.validate({
|
|
37
|
+
namePattern: createBy.data.monitorNamePattern,
|
|
38
|
+
descriptionPattern: createBy.data.monitorDescriptionPattern,
|
|
39
|
+
});
|
|
40
|
+
await this.assertReferencesAreInScope({
|
|
41
|
+
projectId: createBy.props.tenantId || createBy.data.projectId,
|
|
42
|
+
statusPageId: resolveReferenceId(createBy.data.statusPageId || createBy.data.statusPage),
|
|
43
|
+
statusPageGroupId: resolveReferenceId(createBy.data.statusPageGroupId || createBy.data.statusPageGroup),
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
createBy: createBy,
|
|
47
|
+
carryForward: null,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async onCreateSuccess(_onCreate, createdItem) {
|
|
51
|
+
/*
|
|
52
|
+
* Backfill: a rule the user just wrote should populate the page with the
|
|
53
|
+
* monitors that already match, not only with ones created after it.
|
|
54
|
+
*/
|
|
55
|
+
if (createdItem.id) {
|
|
56
|
+
await this.syncQuietly(createdItem.id);
|
|
57
|
+
}
|
|
58
|
+
return createdItem;
|
|
59
|
+
}
|
|
60
|
+
async onBeforeUpdate(updateBy) {
|
|
61
|
+
StatusPageMonitorRulePatternValidator.validate({
|
|
62
|
+
namePattern: updateBy.data.monitorNamePattern,
|
|
63
|
+
descriptionPattern: updateBy.data.monitorDescriptionPattern,
|
|
64
|
+
});
|
|
65
|
+
/*
|
|
66
|
+
* An edit can empty a rule out just as easily as a create can, and the
|
|
67
|
+
* result is the same useless rule. The merged view is what matters, so
|
|
68
|
+
* fields the edit does not mention are read back off the stored row -
|
|
69
|
+
* clearing only the labels on a rule that also has a name pattern is
|
|
70
|
+
* perfectly fine, and must not be refused.
|
|
71
|
+
*/
|
|
72
|
+
await this.assertUpdateKeepsMatchCriteria(updateBy);
|
|
73
|
+
/*
|
|
74
|
+
* Re-pointing a rule at a different group is an ordinary edit, so the same
|
|
75
|
+
* scope checks the create path makes apply here. statusPageId is
|
|
76
|
+
* create-only in the column ACL, so only the group can move.
|
|
77
|
+
*/
|
|
78
|
+
const nextGroupId = resolveReferenceId(updateBy.data["statusPageGroupId"] ||
|
|
79
|
+
updateBy.data["statusPageGroup"]);
|
|
80
|
+
if (nextGroupId) {
|
|
81
|
+
for (const rule of await this.findRulesForQuery(updateBy)) {
|
|
82
|
+
await this.assertReferencesAreInScope({
|
|
83
|
+
projectId: updateBy.props.tenantId || rule.projectId,
|
|
84
|
+
statusPageId: rule.statusPageId,
|
|
85
|
+
statusPageGroupId: nextGroupId,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { updateBy, carryForward: null };
|
|
90
|
+
}
|
|
91
|
+
async onUpdateSuccess(onUpdate, updatedItemIds) {
|
|
92
|
+
/*
|
|
93
|
+
* Every editable field on this model changes what the rule matches or how
|
|
94
|
+
* the resources it owns are rendered, so any edit re-runs the rule. The
|
|
95
|
+
* sync is idempotent, so re-running it after a no-op edit costs a read.
|
|
96
|
+
*/
|
|
97
|
+
for (const id of updatedItemIds) {
|
|
98
|
+
await this.syncQuietly(id);
|
|
99
|
+
}
|
|
100
|
+
return onUpdate;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Deleting a rule undoes it: the resources it added go too, and the monitors
|
|
104
|
+
* it was publishing are offered to the rules that survive.
|
|
105
|
+
*
|
|
106
|
+
* Every destructive step lives here rather than in onBeforeDelete, because
|
|
107
|
+
* DatabaseService applies checkDeleteQueryPermission *after* onBeforeDelete.
|
|
108
|
+
* A hook there sees the caller's raw, un-tenant-scoped query, so a
|
|
109
|
+
* root-privileged write from it would let a caller destroy another project's
|
|
110
|
+
* status page resources by naming that project's rule id, with the
|
|
111
|
+
* permission check only rejecting the (already moot) rule delete afterwards.
|
|
112
|
+
* `itemIdsBeforeDelete` is the permission-checked set, so acting on it is
|
|
113
|
+
* safe.
|
|
114
|
+
*
|
|
115
|
+
* By this point the StatusPageResource -> StatusPageMonitorRule foreign key
|
|
116
|
+
* has usually already cascaded the resources away, which makes the removal
|
|
117
|
+
* pass belt-and-braces rather than the primary mechanism. It is kept so the
|
|
118
|
+
* behaviour does not depend on the cascade staying as it is — and it is also
|
|
119
|
+
* why the monitor ids come from carryForward: after the cascade there is
|
|
120
|
+
* nothing left to read them off.
|
|
121
|
+
*/
|
|
122
|
+
async onDeleteSuccess(onDelete, itemIdsBeforeDelete) {
|
|
123
|
+
var _a;
|
|
124
|
+
const monitorIdsByRuleId = ((_a = onDelete.carryForward) === null || _a === void 0 ? void 0 : _a.monitorIdsByRuleId) || {};
|
|
125
|
+
for (const statusPageMonitorRuleId of itemIdsBeforeDelete) {
|
|
126
|
+
try {
|
|
127
|
+
await StatusPageMonitorRuleEngineService.removeResourcesAddedByRule({
|
|
128
|
+
statusPageMonitorRuleId: statusPageMonitorRuleId,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
logger.error(`Error removing resources added by status page monitor rule ${statusPageMonitorRuleId.toString()}: ${error}`, {
|
|
133
|
+
statusPageMonitorRuleId: statusPageMonitorRuleId.toString(),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/*
|
|
137
|
+
* Deleting a rule must behave like disabling one. Disabling routes
|
|
138
|
+
* through syncResourcesForRule, which hands each released monitor to the
|
|
139
|
+
* other rules on the page; without this, deleting would instead drop a
|
|
140
|
+
* monitor that a sibling rule still claims — the same rule, switched off
|
|
141
|
+
* two different ways, giving two different pages.
|
|
142
|
+
*/
|
|
143
|
+
for (const monitorId of monitorIdsByRuleId[statusPageMonitorRuleId.toString()] || []) {
|
|
144
|
+
try {
|
|
145
|
+
await StatusPageMonitorRuleEngineService.syncRulesForMonitor({
|
|
146
|
+
monitorId: new ObjectID(monitorId),
|
|
147
|
+
projectId: onDelete.deleteBy.props.tenantId,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
logger.error(`Error re-homing monitor ${monitorId} after status page monitor rule ${statusPageMonitorRuleId.toString()} was deleted: ${error}`, { monitorId: monitorId });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return onDelete;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Notes down which monitors each doomed rule is publishing, so
|
|
159
|
+
* onDeleteSuccess can offer them to the rules that survive.
|
|
160
|
+
*
|
|
161
|
+
* This has to happen before the delete because the StatusPageResource ->
|
|
162
|
+
* StatusPageMonitorRule foreign key is ON DELETE CASCADE: by the time the
|
|
163
|
+
* rule row is gone, so are the resources that named the monitors.
|
|
164
|
+
*
|
|
165
|
+
* It is READ ONLY, and reads through the caller's own props rather than as
|
|
166
|
+
* root. onBeforeDelete runs before checkDeleteQueryPermission, so anything
|
|
167
|
+
* here sees the caller's raw query — a root-privileged write from this hook
|
|
168
|
+
* would let a caller destroy another project's status page resources by
|
|
169
|
+
* naming that project's rule id.
|
|
170
|
+
*/
|
|
171
|
+
async onBeforeDelete(deleteBy) {
|
|
172
|
+
const monitorIdsByRuleId = {};
|
|
173
|
+
try {
|
|
174
|
+
const rules = await this.findBy({
|
|
175
|
+
query: deleteBy.query,
|
|
176
|
+
select: {
|
|
177
|
+
_id: true,
|
|
178
|
+
},
|
|
179
|
+
limit: LIMIT_PER_PROJECT,
|
|
180
|
+
skip: 0,
|
|
181
|
+
props: deleteBy.props,
|
|
182
|
+
});
|
|
183
|
+
for (const rule of rules) {
|
|
184
|
+
if (!rule.id) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const resources = await StatusPageResourceService.findBy({
|
|
188
|
+
query: {
|
|
189
|
+
statusPageMonitorRuleId: rule.id,
|
|
190
|
+
},
|
|
191
|
+
select: {
|
|
192
|
+
monitorId: true,
|
|
193
|
+
},
|
|
194
|
+
limit: LIMIT_PER_PROJECT,
|
|
195
|
+
skip: 0,
|
|
196
|
+
props: {
|
|
197
|
+
isRoot: true,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
monitorIdsByRuleId[rule.id.toString()] = resources
|
|
201
|
+
.map((resource) => {
|
|
202
|
+
var _a;
|
|
203
|
+
return ((_a = resource.monitorId) === null || _a === void 0 ? void 0 : _a.toString()) || "";
|
|
204
|
+
})
|
|
205
|
+
.filter((monitorId) => {
|
|
206
|
+
return monitorId !== "";
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
/*
|
|
212
|
+
* Best effort. Failing to note the monitors down must not block the
|
|
213
|
+
* delete; the worst case is that a sibling rule re-adopts them on its
|
|
214
|
+
* next run instead of immediately.
|
|
215
|
+
*/
|
|
216
|
+
logger.error(`Error collecting monitors published by status page monitor rules before delete: ${error}`);
|
|
217
|
+
}
|
|
218
|
+
return { deleteBy, carryForward: { monitorIdsByRuleId } };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* A rule points at a status page, and optionally at a group on that page.
|
|
222
|
+
* Neither is checked by the framework, and both decide what ends up on a
|
|
223
|
+
* PUBLIC page, so both are checked here:
|
|
224
|
+
*
|
|
225
|
+
* - a status page from another project would let one tenant publish its
|
|
226
|
+
* monitors on another tenant's status page;
|
|
227
|
+
* - a group belonging to a different status page would produce resources
|
|
228
|
+
* that render nowhere, because the page only draws groups that are its
|
|
229
|
+
* own — a rule that silently adds invisible monitors.
|
|
230
|
+
*/
|
|
231
|
+
async assertReferencesAreInScope(data) {
|
|
232
|
+
var _a;
|
|
233
|
+
await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
|
|
234
|
+
projectId: data.projectId,
|
|
235
|
+
subject: "status page monitor rule",
|
|
236
|
+
references: [
|
|
237
|
+
{
|
|
238
|
+
modelName: "Status Page",
|
|
239
|
+
id: data.statusPageId,
|
|
240
|
+
service: StatusPageService,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
modelName: "Status Page Group",
|
|
244
|
+
id: data.statusPageGroupId,
|
|
245
|
+
service: StatusPageGroupService,
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
});
|
|
249
|
+
if (!data.statusPageGroupId || !data.statusPageId) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const group = await StatusPageGroupService.findOneById({
|
|
253
|
+
id: new ObjectID(data.statusPageGroupId.toString()),
|
|
254
|
+
select: {
|
|
255
|
+
_id: true,
|
|
256
|
+
statusPageId: true,
|
|
257
|
+
},
|
|
258
|
+
props: {
|
|
259
|
+
isRoot: true,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
/*
|
|
263
|
+
* A group id that matches no row at all is left to the foreign key to
|
|
264
|
+
* report, the same call the project-scope validator above makes.
|
|
265
|
+
*/
|
|
266
|
+
if (!group) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (((_a = group.statusPageId) === null || _a === void 0 ? void 0 : _a.toString()) !== data.statusPageId.toString()) {
|
|
270
|
+
throw new BadDataException("The group this rule adds monitors to belongs to a different status page. Pick a group on the status page the rule is for.");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* A rule with no criteria would claim every monitor in the project. An empty
|
|
275
|
+
* form is much more likely to be an unfinished one, and the cost of guessing
|
|
276
|
+
* wrong is a private monitor on a public page — so say so instead.
|
|
277
|
+
*/
|
|
278
|
+
assertHasMatchCriteria(data) {
|
|
279
|
+
if (data.monitorLabelCount === 0 &&
|
|
280
|
+
!data.monitorNamePattern &&
|
|
281
|
+
!data.monitorDescriptionPattern) {
|
|
282
|
+
throw new BadDataException("A status page monitor rule needs at least one match criterion: monitor labels, a monitor name pattern, or a monitor description pattern. Use .* as the name pattern to match every monitor.");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The rules an update actually touches, read for validation.
|
|
287
|
+
*
|
|
288
|
+
* onBeforeUpdate runs before DatabaseService applies the update query's
|
|
289
|
+
* permission check, so the query here is still the caller's raw one. The
|
|
290
|
+
* tenant is pinned onto it when the caller has one, so a validation read can
|
|
291
|
+
* never reach across projects and answer questions about another tenant's
|
|
292
|
+
* rules. Genuinely root callers (the engines, migrations) have no tenantId
|
|
293
|
+
* and are trusted.
|
|
294
|
+
*/
|
|
295
|
+
async findRulesForQuery(updateBy) {
|
|
296
|
+
const query = Object.assign({}, updateBy.query);
|
|
297
|
+
if (updateBy.props.tenantId) {
|
|
298
|
+
query["projectId"] = updateBy.props.tenantId;
|
|
299
|
+
}
|
|
300
|
+
return await this.findBy({
|
|
301
|
+
query: query,
|
|
302
|
+
select: {
|
|
303
|
+
_id: true,
|
|
304
|
+
projectId: true,
|
|
305
|
+
statusPageId: true,
|
|
306
|
+
monitorLabels: {
|
|
307
|
+
_id: true,
|
|
308
|
+
},
|
|
309
|
+
monitorNamePattern: true,
|
|
310
|
+
monitorDescriptionPattern: true,
|
|
311
|
+
},
|
|
312
|
+
limit: LIMIT_PER_PROJECT,
|
|
313
|
+
skip: 0,
|
|
314
|
+
props: {
|
|
315
|
+
isRoot: true,
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* The create-time criteria check, applied to what the rule will look like
|
|
321
|
+
* after this edit. Every rule the edit touches has to survive it.
|
|
322
|
+
*/
|
|
323
|
+
async assertUpdateKeepsMatchCriteria(updateBy) {
|
|
324
|
+
const touchesCriteria = updateBy.data.monitorLabels !== undefined ||
|
|
325
|
+
updateBy.data.monitorNamePattern !== undefined ||
|
|
326
|
+
updateBy.data.monitorDescriptionPattern !== undefined;
|
|
327
|
+
if (!touchesCriteria) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const rules = await this.findRulesForQuery(updateBy);
|
|
331
|
+
const nextLabels = updateBy.data
|
|
332
|
+
.monitorLabels;
|
|
333
|
+
for (const rule of rules) {
|
|
334
|
+
this.assertHasMatchCriteria({
|
|
335
|
+
monitorLabelCount: (nextLabels === undefined
|
|
336
|
+
? rule.monitorLabels || []
|
|
337
|
+
: nextLabels).length,
|
|
338
|
+
monitorNamePattern: updateBy.data.monitorNamePattern === undefined
|
|
339
|
+
? rule.monitorNamePattern
|
|
340
|
+
: updateBy.data.monitorNamePattern,
|
|
341
|
+
monitorDescriptionPattern: updateBy.data.monitorDescriptionPattern === undefined
|
|
342
|
+
? rule.monitorDescriptionPattern
|
|
343
|
+
: updateBy.data.monitorDescriptionPattern,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Rule CRUD must not fail because the sync did. The rule is already saved
|
|
349
|
+
* and the next monitor change (or the next edit) re-runs it.
|
|
350
|
+
*/
|
|
351
|
+
async syncQuietly(statusPageMonitorRuleId) {
|
|
352
|
+
try {
|
|
353
|
+
await StatusPageMonitorRuleEngineService.syncResourcesForRule({
|
|
354
|
+
statusPageMonitorRuleId: statusPageMonitorRuleId,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
logger.error(`Error syncing status page monitor rule ${statusPageMonitorRuleId.toString()}: ${error}`, {
|
|
359
|
+
statusPageMonitorRuleId: statusPageMonitorRuleId.toString(),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
__decorate([
|
|
365
|
+
CaptureSpan(),
|
|
366
|
+
__metadata("design:type", Function),
|
|
367
|
+
__metadata("design:paramtypes", [Object]),
|
|
368
|
+
__metadata("design:returntype", Promise)
|
|
369
|
+
], Service.prototype, "onBeforeCreate", null);
|
|
370
|
+
__decorate([
|
|
371
|
+
CaptureSpan(),
|
|
372
|
+
__metadata("design:type", Function),
|
|
373
|
+
__metadata("design:paramtypes", [Object, Model]),
|
|
374
|
+
__metadata("design:returntype", Promise)
|
|
375
|
+
], Service.prototype, "onCreateSuccess", null);
|
|
376
|
+
__decorate([
|
|
377
|
+
CaptureSpan(),
|
|
378
|
+
__metadata("design:type", Function),
|
|
379
|
+
__metadata("design:paramtypes", [Object]),
|
|
380
|
+
__metadata("design:returntype", Promise)
|
|
381
|
+
], Service.prototype, "onBeforeUpdate", null);
|
|
382
|
+
__decorate([
|
|
383
|
+
CaptureSpan(),
|
|
384
|
+
__metadata("design:type", Function),
|
|
385
|
+
__metadata("design:paramtypes", [Object, Array]),
|
|
386
|
+
__metadata("design:returntype", Promise)
|
|
387
|
+
], Service.prototype, "onUpdateSuccess", null);
|
|
388
|
+
__decorate([
|
|
389
|
+
CaptureSpan(),
|
|
390
|
+
__metadata("design:type", Function),
|
|
391
|
+
__metadata("design:paramtypes", [Object, Array]),
|
|
392
|
+
__metadata("design:returntype", Promise)
|
|
393
|
+
], Service.prototype, "onDeleteSuccess", null);
|
|
394
|
+
__decorate([
|
|
395
|
+
CaptureSpan(),
|
|
396
|
+
__metadata("design:type", Function),
|
|
397
|
+
__metadata("design:paramtypes", [Object]),
|
|
398
|
+
__metadata("design:returntype", Promise)
|
|
399
|
+
], Service.prototype, "onBeforeDelete", null);
|
|
400
|
+
export default new Service();
|
|
401
|
+
//# sourceMappingURL=StatusPageMonitorRuleService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusPageMonitorRuleService.js","sourceRoot":"","sources":["../../../../Server/Services/StatusPageMonitorRuleService.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,6 +61,7 @@ import { MASTER_PASSWORD_COOKIE_IDENTIFIER, MASTER_PASSWORD_REQUIRED_MESSAGE, }
|
|
|
61
61
|
import StatusPageGroupService from "./StatusPageGroupService";
|
|
62
62
|
import StatusPageGroupTreeUtil from "../../Utils/StatusPage/GroupTree";
|
|
63
63
|
import StatusPageReportTreeUtil from "../../Utils/StatusPage/Report";
|
|
64
|
+
import StatusPageReportPeriodUtil from "../../Utils/StatusPage/ReportPeriod";
|
|
64
65
|
export class Service extends DatabaseService {
|
|
65
66
|
constructor() {
|
|
66
67
|
super(StatusPage);
|
|
@@ -720,6 +721,7 @@ export class Service extends DatabaseService {
|
|
|
720
721
|
}
|
|
721
722
|
if (updateBy.data.reportStartDateTime ||
|
|
722
723
|
updateBy.data.reportRecurringInterval ||
|
|
724
|
+
updateBy.data.reportTimezone ||
|
|
723
725
|
updateBy.data.sendNextReportBy) {
|
|
724
726
|
const statusPages = await this.findBy({
|
|
725
727
|
query: updateBy.query,
|
|
@@ -727,6 +729,7 @@ export class Service extends DatabaseService {
|
|
|
727
729
|
_id: true,
|
|
728
730
|
reportStartDateTime: true,
|
|
729
731
|
reportRecurringInterval: true,
|
|
732
|
+
reportTimezone: true,
|
|
730
733
|
},
|
|
731
734
|
props: {
|
|
732
735
|
isRoot: true,
|
|
@@ -735,13 +738,26 @@ export class Service extends DatabaseService {
|
|
|
735
738
|
limit: LIMIT_PER_PROJECT,
|
|
736
739
|
});
|
|
737
740
|
for (const statusPage of statusPages) {
|
|
738
|
-
const
|
|
741
|
+
const reportStartDate = updateBy.data.reportStartDateTime ||
|
|
739
742
|
statusPage.reportStartDateTime;
|
|
740
743
|
const reportRecurringInterval = Recurring.fromJSON(updateBy.data.reportRecurringInterval ||
|
|
741
744
|
statusPage.reportRecurringInterval);
|
|
742
|
-
if (
|
|
743
|
-
|
|
744
|
-
|
|
745
|
+
if (reportStartDate && reportRecurringInterval) {
|
|
746
|
+
/*
|
|
747
|
+
* Calendar-correct rather than Recurring.getNextDate's fixed
|
|
748
|
+
* millisecond approximation, which walks a monthly schedule anchored
|
|
749
|
+
* on the 1st backwards to the 31st, then the 30th, and eventually
|
|
750
|
+
* skips a month. Resolved in the report timezone so "the 1st at
|
|
751
|
+
* 09:00" survives a DST transition.
|
|
752
|
+
*/
|
|
753
|
+
updateBy.data.sendNextReportBy = Recurring.getNextDateAfter({
|
|
754
|
+
startDate: reportStartDate,
|
|
755
|
+
recurring: reportRecurringInterval,
|
|
756
|
+
afterDate: OneUptimeDate.getCurrentDate(),
|
|
757
|
+
timezone: updateBy.data.reportTimezone ||
|
|
758
|
+
statusPage.reportTimezone ||
|
|
759
|
+
StatusPageReportPeriodUtil.DEFAULT_TIMEZONE,
|
|
760
|
+
});
|
|
745
761
|
}
|
|
746
762
|
}
|
|
747
763
|
}
|
|
@@ -750,6 +766,20 @@ export class Service extends DatabaseService {
|
|
|
750
766
|
updateBy: updateBy,
|
|
751
767
|
};
|
|
752
768
|
}
|
|
769
|
+
/*
|
|
770
|
+
* The window the next report off this status page will cover. Static because
|
|
771
|
+
* the settings screen resolves the very same window from the very same
|
|
772
|
+
* columns to show the user what they are about to schedule.
|
|
773
|
+
*/
|
|
774
|
+
static getReportPeriodForStatusPage(statusPage, sentAt) {
|
|
775
|
+
return StatusPageReportPeriodUtil.getReportPeriod({
|
|
776
|
+
periodType: statusPage.reportPeriodType,
|
|
777
|
+
reportRecurringInterval: statusPage.reportRecurringInterval,
|
|
778
|
+
reportDataInDays: statusPage.reportDataInDays,
|
|
779
|
+
timezone: statusPage.reportTimezone,
|
|
780
|
+
sentAt: sentAt,
|
|
781
|
+
});
|
|
782
|
+
}
|
|
753
783
|
async sendEmailReport(data) {
|
|
754
784
|
var _a, _b, _c, _d;
|
|
755
785
|
const host = await DatabaseConfig.getHost();
|
|
@@ -769,7 +799,7 @@ export class Service extends DatabaseService {
|
|
|
769
799
|
const statusPageIdString = ((_a = statuspage.id) === null || _a === void 0 ? void 0 : _a.toString()) || ((_b = statuspage._id) === null || _b === void 0 ? void 0 : _b.toString()) || null;
|
|
770
800
|
const report = await this.getReportByStatusPage({
|
|
771
801
|
statusPageId: statuspage.id,
|
|
772
|
-
|
|
802
|
+
reportPeriod: Service.getReportPeriodForStatusPage(statuspage),
|
|
773
803
|
});
|
|
774
804
|
/*
|
|
775
805
|
* Look up a custom report email template for this status page (if any).
|
|
@@ -888,38 +918,42 @@ export class Service extends DatabaseService {
|
|
|
888
918
|
const statusPageResources = await this.getStatusPageResources({
|
|
889
919
|
statusPageId: data.statusPageId,
|
|
890
920
|
});
|
|
891
|
-
const
|
|
892
|
-
const endDate =
|
|
893
|
-
const startDate = OneUptimeDate.getSomeDaysAgo(numberOfDays);
|
|
894
|
-
const startAndEndDate = `${numberOfDays} days (${OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(startDate, true)} - ${OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(endDate, true)})`;
|
|
921
|
+
const startDate = data.reportPeriod.startDate;
|
|
922
|
+
const endDate = data.reportPeriod.endDate;
|
|
895
923
|
/*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
*
|
|
900
|
-
* instead of the window - so the reported percentage drifted upwards
|
|
924
|
+
* This window is what every uptime number below has to be measured against.
|
|
925
|
+
* It used to be computed only to fetch the timeline and was then discarded,
|
|
926
|
+
* which let an event that started before the window contribute its whole
|
|
927
|
+
* duration to the downtime total, and made the denominator "first event ->
|
|
928
|
+
* now" instead of the window - so the reported percentage drifted upwards
|
|
929
|
+
* every day.
|
|
901
930
|
*/
|
|
902
931
|
const reportWindow = {
|
|
903
932
|
startDate: startDate,
|
|
904
933
|
endDate: endDate,
|
|
905
934
|
};
|
|
935
|
+
const periodStrings = {
|
|
936
|
+
reportDates: data.reportPeriod.reportDates,
|
|
937
|
+
reportPeriodName: data.reportPeriod.periodName,
|
|
938
|
+
reportStartDate: OneUptimeDate.getDateAsCustomFormattedStringInTimezone({
|
|
939
|
+
date: startDate,
|
|
940
|
+
format: "MMM D, YYYY",
|
|
941
|
+
timezone: data.reportPeriod.timezone,
|
|
942
|
+
}),
|
|
943
|
+
reportEndDate: OneUptimeDate.getDateAsCustomFormattedStringInTimezone({
|
|
944
|
+
date: endDate,
|
|
945
|
+
format: "MMM D, YYYY",
|
|
946
|
+
timezone: data.reportPeriod.timezone,
|
|
947
|
+
}),
|
|
948
|
+
reportTimezone: data.reportPeriod.timezone,
|
|
949
|
+
};
|
|
906
950
|
if (statusPageResources.length === 0) {
|
|
907
|
-
return {
|
|
908
|
-
reportDates: startAndEndDate,
|
|
909
|
-
totalResources: 0,
|
|
910
|
-
totalIncidents: 0,
|
|
911
|
-
averageUptimePercent: "0%",
|
|
912
|
-
totalDowntimeInHoursAndMinutes: "0",
|
|
913
|
-
resources: [],
|
|
914
|
-
groups: [],
|
|
915
|
-
ungroupedResources: [],
|
|
916
|
-
rows: [],
|
|
917
|
-
hasGroups: false,
|
|
918
|
-
};
|
|
951
|
+
return Object.assign(Object.assign({}, periodStrings), { totalResources: 0, totalIncidents: 0, averageUptimePercent: "0%", totalDowntimeInHoursAndMinutes: "0", resources: [], groups: [], ungroupedResources: [], rows: [], hasGroups: false });
|
|
919
952
|
}
|
|
920
953
|
const incidentCount = await this.getIncidentCountOnStatusPage({
|
|
921
954
|
statusPageId: data.statusPageId,
|
|
922
|
-
|
|
955
|
+
startDate: startDate,
|
|
956
|
+
endDate: endDate,
|
|
923
957
|
});
|
|
924
958
|
const monitors = await this.getMonitorIdsOnStatusPage({
|
|
925
959
|
statusPageId: data.statusPageId,
|
|
@@ -959,7 +993,8 @@ export class Service extends DatabaseService {
|
|
|
959
993
|
resourceName: resource.displayName || "",
|
|
960
994
|
totalIncidentCount: await this.getIncidentCountByMonitorIds({
|
|
961
995
|
monitorIds: monitorIdsForThisResource,
|
|
962
|
-
|
|
996
|
+
startDate: startDate,
|
|
997
|
+
endDate: endDate,
|
|
963
998
|
}),
|
|
964
999
|
uptimePercent: uptimePercent,
|
|
965
1000
|
uptimePercentAsString: `${uptimePercent}%`,
|
|
@@ -989,25 +1024,13 @@ export class Service extends DatabaseService {
|
|
|
989
1024
|
timeline: timeline,
|
|
990
1025
|
downtimeMonitorStatuses: statusPage.downtimeMonitorStatuses || [],
|
|
991
1026
|
reportWindow: reportWindow,
|
|
992
|
-
historyDays: data.historyDays,
|
|
993
1027
|
});
|
|
994
1028
|
const structure = StatusPageReportTreeUtil.build({
|
|
995
1029
|
entries: entries,
|
|
996
1030
|
statusPageGroups: statusPageGroups,
|
|
997
1031
|
groupMetricsByGroupId: groupMetricsByGroupId,
|
|
998
1032
|
});
|
|
999
|
-
return {
|
|
1000
|
-
reportDates: startAndEndDate,
|
|
1001
|
-
totalResources: statusPageResources.length,
|
|
1002
|
-
totalIncidents: incidentCount,
|
|
1003
|
-
averageUptimePercent: avgUptimePercentString,
|
|
1004
|
-
resources: structure.resources,
|
|
1005
|
-
groups: structure.groups,
|
|
1006
|
-
ungroupedResources: structure.resourcesWithoutGroup,
|
|
1007
|
-
rows: structure.rows,
|
|
1008
|
-
hasGroups: structure.groups.length > 0,
|
|
1009
|
-
totalDowntimeInHoursAndMinutes: OneUptimeDate.convertMinutesToDaysHoursAndMinutes(Math.ceil(totalDowntimeInSeconds.totalDowntimeInSeconds / 60)),
|
|
1010
|
-
};
|
|
1033
|
+
return Object.assign(Object.assign({}, periodStrings), { totalResources: statusPageResources.length, totalIncidents: incidentCount, averageUptimePercent: avgUptimePercentString, resources: structure.resources, groups: structure.groups, ungroupedResources: structure.resourcesWithoutGroup, rows: structure.rows, hasGroups: structure.groups.length > 0, totalDowntimeInHoursAndMinutes: OneUptimeDate.convertMinutesToDaysHoursAndMinutes(Math.ceil(totalDowntimeInSeconds.totalDowntimeInSeconds / 60)) });
|
|
1011
1034
|
}
|
|
1012
1035
|
/*
|
|
1013
1036
|
* Uptime, downtime and incidents for each group, measured over the group and
|
|
@@ -1077,7 +1100,8 @@ export class Service extends DatabaseService {
|
|
|
1077
1100
|
monitorIds.length > 0
|
|
1078
1101
|
? await this.getIncidentCountByMonitorIds({
|
|
1079
1102
|
monitorIds: monitorIds,
|
|
1080
|
-
|
|
1103
|
+
startDate: data.reportWindow.startDate,
|
|
1104
|
+
endDate: data.reportWindow.endDate,
|
|
1081
1105
|
})
|
|
1082
1106
|
: 0;
|
|
1083
1107
|
incidentCountByMonitorSet[monitorSetKey] = totalIncidentCount;
|
|
@@ -1113,12 +1137,10 @@ export class Service extends DatabaseService {
|
|
|
1113
1137
|
});
|
|
1114
1138
|
}
|
|
1115
1139
|
async getIncidentCountByMonitorIds(data) {
|
|
1116
|
-
const today = OneUptimeDate.getCurrentDate();
|
|
1117
|
-
const historyDays = OneUptimeDate.getSomeDaysAgo(data.historyDays || 14);
|
|
1118
1140
|
const incidentCount = await IncidentService.countBy({
|
|
1119
1141
|
query: {
|
|
1120
1142
|
monitors: data.monitorIds,
|
|
1121
|
-
createdAt: QueryHelper.inBetween(
|
|
1143
|
+
createdAt: QueryHelper.inBetween(data.startDate, data.endDate),
|
|
1122
1144
|
},
|
|
1123
1145
|
props: {
|
|
1124
1146
|
isRoot: true,
|
|
@@ -1132,7 +1154,8 @@ export class Service extends DatabaseService {
|
|
|
1132
1154
|
});
|
|
1133
1155
|
return this.getIncidentCountByMonitorIds({
|
|
1134
1156
|
monitorIds: monitorsOnStatusPage.monitorsOnStatusPage,
|
|
1135
|
-
|
|
1157
|
+
startDate: data.startDate,
|
|
1158
|
+
endDate: data.endDate,
|
|
1136
1159
|
});
|
|
1137
1160
|
}
|
|
1138
1161
|
async getMonitorIdsOnStatusPage(data) {
|