diff --git a/ee/app/models/license.rb b/ee/app/models/license.rb index 0104ea9becd661f3b56bec8f7c723fceab2626e4..c072c6144ea19f2e92e5ec7dc3e314c7806a9054 100644 --- a/ee/app/models/license.rb +++ b/ee/app/models/license.rb @@ -95,6 +95,7 @@ class License < ActiveRecord::Base tracing insights web_ide_terminal + incident_management ] EEU_FEATURES.freeze diff --git a/ee/app/services/projects/prometheus/alerts/notify_service.rb b/ee/app/services/projects/prometheus/alerts/notify_service.rb index bb2ba6cdbbdd8fe0de0623246e5d4a4519067a77..81b979e6ef2da2416475f13978c959fd42d1a226 100644 --- a/ee/app/services/projects/prometheus/alerts/notify_service.rb +++ b/ee/app/services/projects/prometheus/alerts/notify_service.rb @@ -8,7 +8,7 @@ def execute(token) return false unless valid_version? return false unless valid_alert_manager_token?(token) - send_alert_email(project, firings) if firings.any? + send_alert_email if send_email? persist_events(project, params) true @@ -16,6 +16,23 @@ def execute(token) private + def has_incident_management_license? + project.feature_available?(:incident_management) + end + + def incident_management_feature_enabled? + Feature.enabled?(:incident_management) + end + + def send_email? + return firings.any? unless incident_management_feature_enabled? && + has_incident_management_license? + + setting = project.incident_management_setting || project.build_incident_management_setting + + setting.send_email && firings.any? + end + def firings @firings ||= alerts_by_status('firing') end @@ -89,7 +106,7 @@ def compare_token(expected, actual) ActiveSupport::SecurityUtils.variable_size_secure_compare(expected, actual) end - def send_alert_email(projects, firing_alerts) + def send_alert_email notification_service .async .prometheus_alerts_fired(project, firings) diff --git a/ee/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/ee/spec/services/projects/prometheus/alerts/notify_service_spec.rb index 82d08308938f72e2787018e00a0df5b9e88edbb6..29b48135c57f107420e9bfe5df50a8a4d883d0f5 100644 --- a/ee/spec/services/projects/prometheus/alerts/notify_service_spec.rb +++ b/ee/spec/services/projects/prometheus/alerts/notify_service_spec.rb @@ -9,9 +9,13 @@ let(:token_input) { 'token' } let(:subject) { service.execute(token_input) } - shared_examples 'notifies alerts' do + before do + # We use `set(:project)` so we make sure to clear caches + project.clear_memoization(:licensed_feature_available) + end + + shared_examples 'sends notification email' do let(:notification_service) { spy } - let(:create_events_service) { spy } it 'sends a notification for firing alerts only' do expect(NotificationService) @@ -23,6 +27,10 @@ expect(subject).to eq(true) end + end + + shared_examples 'persists events' do + let(:create_events_service) { spy } it 'persists events' do expect(Projects::Prometheus::Alerts::CreateEventsService) @@ -36,6 +44,11 @@ end end + shared_examples 'notifies alerts' do + it_behaves_like 'sends notification email' + it_behaves_like 'persists events' + end + shared_examples 'no notifications' do let(:notification_service) { spy } let(:create_events_service) { spy } @@ -73,6 +86,8 @@ with_them do before do + stub_feature_flags(incident_management: false) + cluster = create(:cluster, :provided_by_user, projects: [project], enabled: cluster_enabled) @@ -112,6 +127,8 @@ end before do + stub_feature_flags(incident_management: false) + stub_licensed_features(multiple_clusters: true) create(:clusters_applications_prometheus, :installed, @@ -152,6 +169,8 @@ let(:alert_manager_token) { token_input } before do + stub_feature_flags(incident_management: false) + create(:prometheus_service, project: project) if alerting_setting @@ -171,6 +190,66 @@ end end end + + context 'incident_management feature flag disabled' do + before do + create(:prometheus_service, project: project) + create(:project_alerting_setting, project: project, token: token) + create(:project_incident_management_setting, send_email: true, project: project) + + stub_feature_flags(incident_management: false) + end + + it_behaves_like 'notifies alerts' + end + + context 'no incident_management license' do + before do + create(:prometheus_service, project: project) + create(:project_alerting_setting, project: project, token: token) + create(:project_incident_management_setting, send_email: true, project: project) + + stub_licensed_features(incident_management: false) + end + + it_behaves_like 'notifies alerts' + end + + context 'with incident_management license' do + before do + create(:prometheus_service, project: project) + create(:project_alerting_setting, project: project, token: token) + + stub_licensed_features(incident_management: true) + end + + context 'when incident_management_setting does not exist' do + it_behaves_like 'notifies alerts' + end + + context 'when incident_management_setting.send_email is true' do + before do + create(:project_incident_management_setting, send_email: true, project: project) + end + + it_behaves_like 'notifies alerts' + end + + context 'incident_management_setting.send_email is false' do + before do + create(:project_incident_management_setting, send_email: false, project: project) + end + + it_behaves_like 'persists events' + + it 'does not send notification' do + expect(project.feature_available?(:incident_management)).to eq(true) + expect(NotificationService).not_to receive(:new) + + expect(subject).to eq(true) + end + end + end end context 'with invalid payload' do