gitlab-org--gitlab-foss/app/services/namespaces/check_storage_size_service.rb

95 lines
2.8 KiB
Ruby

# 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