summaryrefslogtreecommitdiff
path: root/app/services/namespaces/check_storage_size_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/namespaces/check_storage_size_service.rb')
-rw-r--r--app/services/namespaces/check_storage_size_service.rb94
1 files changed, 94 insertions, 0 deletions
diff --git a/app/services/namespaces/check_storage_size_service.rb b/app/services/namespaces/check_storage_size_service.rb
new file mode 100644
index 00000000000..b3cf17681ee
--- /dev/null
+++ b/app/services/namespaces/check_storage_size_service.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+module Namespaces
+ class CheckStorageSizeService
+ include ActiveSupport::NumberHelper
+ include Gitlab::Allowable
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(namespace, user)
+ @root_namespace = namespace.root_ancestor
+ @root_storage_size = Namespace::RootStorageSize.new(root_namespace)
+ @user = user
+ end
+
+ def execute
+ return ServiceResponse.success unless Feature.enabled?(:namespace_storage_limit, root_namespace)
+ return ServiceResponse.success if alert_level == :none
+
+ if root_storage_size.above_size_limit?
+ ServiceResponse.error(message: above_size_limit_message, payload: payload)
+ else
+ ServiceResponse.success(payload: payload)
+ end
+ end
+
+ private
+
+ attr_reader :root_namespace, :root_storage_size, :user
+
+ USAGE_THRESHOLDS = {
+ none: 0.0,
+ info: 0.5,
+ warning: 0.75,
+ alert: 0.95,
+ error: 1.0
+ }.freeze
+
+ def payload
+ return {} unless can?(user, :admin_namespace, root_namespace)
+
+ {
+ explanation_message: explanation_message,
+ usage_message: usage_message,
+ alert_level: alert_level
+ }
+ end
+
+ def explanation_message
+ root_storage_size.above_size_limit? ? above_size_limit_message : below_size_limit_message
+ end
+
+ def usage_message
+ s_("You reached %{usage_in_percent} of %{namespace_name}'s capacity (%{used_storage} of %{storage_limit})" % current_usage_params)
+ end
+
+ def alert_level
+ strong_memoize(:alert_level) do
+ usage_ratio = root_storage_size.usage_ratio
+ current_level = USAGE_THRESHOLDS.each_key.first
+
+ USAGE_THRESHOLDS.each do |level, threshold|
+ current_level = level if usage_ratio >= threshold
+ end
+
+ current_level
+ end
+ end
+
+ def below_size_limit_message
+ s_("If you reach 100%% storage capacity, you will not be able to: %{base_message}" % { base_message: base_message } )
+ end
+
+ def above_size_limit_message
+ s_("%{namespace_name} is now read-only. You cannot: %{base_message}" % { namespace_name: root_namespace.name, base_message: base_message })
+ end
+
+ def base_message
+ s_("push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines.")
+ end
+
+ def current_usage_params
+ {
+ usage_in_percent: number_to_percentage(root_storage_size.usage_ratio * 100, precision: 0),
+ namespace_name: root_namespace.name,
+ used_storage: formatted(root_storage_size.current_size),
+ storage_limit: formatted(root_storage_size.limit)
+ }
+ end
+
+ def formatted(number)
+ number_to_human_size(number, delimiter: ',', precision: 2)
+ end
+ end
+end