Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-25 21:08:10 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-25 21:08:10 +0300
commit5d75b2b9a9d11c20667895e6aa68ea4e76658c5d (patch)
tree2aa529b0a153c805f5f4ecb357321a4e4f4c59cb /app
parent6f2065c468b05658125b746169c56764a8ccddb1 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/models/concerns/bulk_insert_safe.rb35
-rw-r--r--app/services/projects/import_export/export_service.rb2
-rw-r--r--app/services/projects/prometheus/alerts/notify_service.rb124
3 files changed, 151 insertions, 10 deletions
diff --git a/app/models/concerns/bulk_insert_safe.rb b/app/models/concerns/bulk_insert_safe.rb
index a61db2dc148..f1a2d566e97 100644
--- a/app/models/concerns/bulk_insert_safe.rb
+++ b/app/models/concerns/bulk_insert_safe.rb
@@ -68,6 +68,9 @@ module BulkInsertSafe
# @param [Boolean] validate Whether validations should run on [items]
# @param [Integer] batch_size How many items should at most be inserted at once
# @param [Boolean] skip_duplicates Marks duplicates as allowed, and skips inserting them
+ # @param [Symbol] returns Pass :ids to return an array with the primary key values
+ # for all inserted records or nil to omit the underlying
+ # RETURNING SQL clause entirely.
# @param [Proc] handle_attributes Block that will receive each item attribute hash
# prior to insertion for further processing
#
@@ -78,10 +81,11 @@ module BulkInsertSafe
#
# @return true if operation succeeded, throws otherwise.
#
- def bulk_insert!(items, validate: true, skip_duplicates: false, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
+ def bulk_insert!(items, validate: true, skip_duplicates: false, returns: nil, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
_bulk_insert_all!(items,
validate: validate,
on_duplicate: skip_duplicates ? :skip : :raise,
+ returns: returns,
unique_by: nil,
batch_size: batch_size,
&handle_attributes)
@@ -94,6 +98,9 @@ module BulkInsertSafe
# @param [Boolean] validate Whether validations should run on [items]
# @param [Integer] batch_size How many items should at most be inserted at once
# @param [Symbol/Array] unique_by Defines index or columns to use to consider item duplicate
+ # @param [Symbol] returns Pass :ids to return an array with the primary key values
+ # for all inserted or updated records or nil to omit the
+ # underlying RETURNING SQL clause entirely.
# @param [Proc] handle_attributes Block that will receive each item attribute hash
# prior to insertion for further processing
#
@@ -109,10 +116,11 @@ module BulkInsertSafe
#
# @return true if operation succeeded, throws otherwise.
#
- def bulk_upsert!(items, unique_by:, validate: true, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
+ def bulk_upsert!(items, unique_by:, returns: nil, validate: true, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
_bulk_insert_all!(items,
validate: validate,
on_duplicate: :update,
+ returns: returns,
unique_by: unique_by,
batch_size: batch_size,
&handle_attributes)
@@ -120,21 +128,30 @@ module BulkInsertSafe
private
- def _bulk_insert_all!(items, on_duplicate:, unique_by:, validate:, batch_size:, &handle_attributes)
- return true if items.empty?
+ def _bulk_insert_all!(items, on_duplicate:, returns:, unique_by:, validate:, batch_size:, &handle_attributes)
+ return [] if items.empty?
+
+ returning =
+ case returns
+ when :ids
+ [primary_key]
+ when nil
+ false
+ else
+ raise ArgumentError, "returns needs to be :ids or nil"
+ end
transaction do
- items.each_slice(batch_size) do |item_batch|
+ items.each_slice(batch_size).flat_map do |item_batch|
attributes = _bulk_insert_item_attributes(
item_batch, validate, &handle_attributes)
ActiveRecord::InsertAll
- .new(self, attributes, on_duplicate: on_duplicate, unique_by: unique_by)
- .execute
+ .new(self, attributes, on_duplicate: on_duplicate, returning: returning, unique_by: unique_by)
+ .execute
+ .pluck(primary_key)
end
end
-
- true
end
def _bulk_insert_item_attributes(items, validate_items)
diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb
index f4214410226..fa098e7417c 100644
--- a/app/services/projects/import_export/export_service.rb
+++ b/app/services/projects/import_export/export_service.rb
@@ -58,7 +58,7 @@ module Projects
end
def tree_saver_class
- if ::Feature.enabled?(:streaming_serializer, project)
+ if ::Feature.enabled?(:streaming_serializer, project, default_enabled: true)
Gitlab::ImportExport::Project::TreeSaver
else
# Once we remove :streaming_serializer feature flag, Project::LegacyTreeSaver should be removed as well
diff --git a/app/services/projects/prometheus/alerts/notify_service.rb b/app/services/projects/prometheus/alerts/notify_service.rb
new file mode 100644
index 00000000000..89791aecabb
--- /dev/null
+++ b/app/services/projects/prometheus/alerts/notify_service.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+module Projects
+ module Prometheus
+ module Alerts
+ class NotifyService < BaseService
+ include Gitlab::Utils::StrongMemoize
+ include IncidentManagement::Settings
+
+ def execute(token)
+ return false unless valid_payload_size?
+ return false unless valid_version?
+ return false unless valid_alert_manager_token?(token)
+
+ persist_events
+ send_alert_email if send_email?
+ process_incident_issues if process_issues?
+
+ true
+ end
+
+ private
+
+ def valid_payload_size?
+ Gitlab::Utils::DeepSize.new(params).valid?
+ end
+
+ def send_email?
+ incident_management_setting.send_email && firings.any?
+ end
+
+ def firings
+ @firings ||= alerts_by_status('firing')
+ end
+
+ def alerts_by_status(status)
+ alerts.select { |alert| alert['status'] == status }
+ end
+
+ def alerts
+ params['alerts']
+ end
+
+ def valid_version?
+ params['version'] == '4'
+ end
+
+ def valid_alert_manager_token?(token)
+ valid_for_manual?(token) || valid_for_managed?(token)
+ end
+
+ def valid_for_manual?(token)
+ prometheus = project.find_or_initialize_service('prometheus')
+ return false unless prometheus.manual_configuration?
+
+ if setting = project.alerting_setting
+ compare_token(token, setting.token)
+ else
+ token.nil?
+ end
+ end
+
+ def valid_for_managed?(token)
+ prometheus_application = available_prometheus_application(project)
+ return false unless prometheus_application
+
+ if token
+ compare_token(token, prometheus_application.alert_manager_token)
+ else
+ prometheus_application.alert_manager_token.nil?
+ end
+ end
+
+ def available_prometheus_application(project)
+ alert_id = gitlab_alert_id
+ return unless alert_id
+
+ alert = find_alert(project, alert_id)
+ return unless alert
+
+ cluster = alert.environment.deployment_platform&.cluster
+ return unless cluster&.enabled?
+ return unless cluster.application_prometheus_available?
+
+ cluster.application_prometheus
+ end
+
+ def find_alert(project, metric)
+ Projects::Prometheus::AlertsFinder
+ .new(project: project, metric: metric)
+ .execute
+ .first
+ end
+
+ def gitlab_alert_id
+ alerts&.first&.dig('labels', 'gitlab_alert_id')
+ end
+
+ def compare_token(expected, actual)
+ return unless expected && actual
+
+ ActiveSupport::SecurityUtils.secure_compare(expected, actual)
+ end
+
+ def send_alert_email
+ notification_service
+ .async
+ .prometheus_alerts_fired(project, firings)
+ end
+
+ def process_incident_issues
+ alerts.each do |alert|
+ IncidentManagement::ProcessPrometheusAlertWorker
+ .perform_async(project.id, alert.to_h)
+ end
+ end
+
+ def persist_events
+ CreateEventsService.new(project, nil, params).execute
+ end
+ end
+ end
+ end
+end