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
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
commit6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch)
treedc4d20fe6064752c0bd323187252c77e0a89144b /app/uploaders
parent9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff)
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'app/uploaders')
-rw-r--r--app/uploaders/object_storage/cdn.rb46
-rw-r--r--app/uploaders/object_storage/cdn/google_cdn.rb71
-rw-r--r--app/uploaders/object_storage/cdn/google_ip_cache.rb60
-rw-r--r--app/uploaders/packages/package_file_uploader.rb4
4 files changed, 178 insertions, 3 deletions
diff --git a/app/uploaders/object_storage/cdn.rb b/app/uploaders/object_storage/cdn.rb
new file mode 100644
index 00000000000..0711ab0bd28
--- /dev/null
+++ b/app/uploaders/object_storage/cdn.rb
@@ -0,0 +1,46 @@
+# rubocop:disable Naming/FileName
+# frozen_string_literal: true
+
+require_relative 'cdn/google_cdn'
+
+module ObjectStorage
+ module CDN
+ module Concern
+ extend ActiveSupport::Concern
+
+ include Gitlab::Utils::StrongMemoize
+
+ def use_cdn?(request_ip)
+ return false unless cdn_options.is_a?(Hash) && cdn_options['provider']
+ return false unless cdn_provider
+
+ cdn_provider.use_cdn?(request_ip)
+ end
+
+ def cdn_signed_url
+ cdn_provider&.signed_url(path)
+ end
+
+ private
+
+ def cdn_provider
+ strong_memoize(:cdn_provider) do
+ provider = cdn_options['provider']&.downcase
+
+ next unless provider
+ next GoogleCDN.new(cdn_options) if provider == 'google'
+
+ raise "Unknown CDN provider: #{provider}"
+ end
+ end
+
+ def cdn_options
+ return {} unless options.object_store.key?('cdn')
+
+ options.object_store.cdn
+ end
+ end
+ end
+end
+
+# rubocop:enable Naming/FileName
diff --git a/app/uploaders/object_storage/cdn/google_cdn.rb b/app/uploaders/object_storage/cdn/google_cdn.rb
new file mode 100644
index 00000000000..ea7683f131c
--- /dev/null
+++ b/app/uploaders/object_storage/cdn/google_cdn.rb
@@ -0,0 +1,71 @@
+# rubocop:disable Naming/FileName
+# frozen_string_literal: true
+
+module ObjectStorage
+ module CDN
+ class GoogleCDN
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :options
+
+ def initialize(options)
+ @options = HashWithIndifferentAccess.new(options.to_h)
+
+ GoogleIpCache.async_refresh unless GoogleIpCache.ready?
+ end
+
+ def use_cdn?(request_ip)
+ return false unless config_valid?
+
+ ip = IPAddr.new(request_ip)
+
+ return false if ip.private?
+
+ !GoogleIpCache.google_ip?(request_ip)
+ end
+
+ def signed_url(path, expiry: 10.minutes)
+ expiration = (Time.current + expiry).utc.to_i
+
+ uri = Addressable::URI.parse(cdn_url)
+ uri.path = path
+ uri.query = "Expires=#{expiration}&KeyName=#{key_name}"
+
+ signature = OpenSSL::HMAC.digest('SHA1', decoded_key, uri.to_s)
+ encoded_signature = Base64.urlsafe_encode64(signature)
+
+ uri.query += "&Signature=#{encoded_signature}"
+ uri.to_s
+ end
+
+ private
+
+ def config_valid?
+ [key_name, decoded_key, cdn_url].all?(&:present?)
+ end
+
+ def key_name
+ strong_memoize(:key_name) do
+ options['key_name']
+ end
+ end
+
+ def decoded_key
+ strong_memoize(:decoded_key) do
+ Base64.urlsafe_decode64(options['key']) if options['key']
+ rescue ArgumentError
+ Gitlab::ErrorTracking.log_exception(ArgumentError.new("Google CDN key is not base64-encoded"))
+ nil
+ end
+ end
+
+ def cdn_url
+ strong_memoize(:cdn_url) do
+ options['url']
+ end
+ end
+ end
+ end
+end
+
+# rubocop:enable Naming/FileName
diff --git a/app/uploaders/object_storage/cdn/google_ip_cache.rb b/app/uploaders/object_storage/cdn/google_ip_cache.rb
new file mode 100644
index 00000000000..35ec7ce0c6e
--- /dev/null
+++ b/app/uploaders/object_storage/cdn/google_ip_cache.rb
@@ -0,0 +1,60 @@
+# rubocop:disable Naming/FileName
+# frozen_string_literal: true
+
+module ObjectStorage
+ module CDN
+ class GoogleIpCache
+ GOOGLE_CDN_LIST_KEY = 'google_cdn_ip_list'
+ CACHE_EXPIRATION_TIME = 1.day
+
+ class << self
+ def update!(subnets)
+ caches.each { |cache| cache.write(GOOGLE_CDN_LIST_KEY, subnets) }
+ end
+
+ def ready?
+ caches.any? { |cache| cache.exist?(GOOGLE_CDN_LIST_KEY) }
+ end
+
+ def google_ip?(request_ip)
+ google_ip_ranges = cached_value(GOOGLE_CDN_LIST_KEY)
+
+ return false unless google_ip_ranges
+
+ google_ip_ranges.any? { |range| range.include?(request_ip) }
+ end
+
+ def async_refresh
+ ::GoogleCloud::FetchGoogleIpListWorker.perform_async
+ end
+
+ private
+
+ def caches
+ [l1_cache, l2_cache]
+ end
+
+ def l1_cache
+ Gitlab::ProcessMemoryCache.cache_backend
+ end
+
+ def l2_cache
+ Rails.cache
+ end
+
+ def cached_value(key)
+ l1_cache.fetch(key) do
+ result = l2_cache.fetch(key)
+
+ # Don't populate the L1 cache if we can't find the entry
+ break unless result
+
+ result
+ end
+ end
+ end
+ end
+ end
+end
+
+# rubocop:enable Naming/FileName
diff --git a/app/uploaders/packages/package_file_uploader.rb b/app/uploaders/packages/package_file_uploader.rb
index 4b6dbe5b358..9c0a88c9bf8 100644
--- a/app/uploaders/packages/package_file_uploader.rb
+++ b/app/uploaders/packages/package_file_uploader.rb
@@ -22,8 +22,6 @@ class Packages::PackageFileUploader < GitlabUploader
def dynamic_segment
raise ObjectNotReadyError, "Package model not ready" unless model.id
- package_segment = model.package.debian? ? 'debian' : model.package.id
-
- Gitlab::HashedPath.new('packages', package_segment, 'files', model.id, root_hash: model.package.project_id)
+ Gitlab::HashedPath.new('packages', model.package_id, 'files', model.id, root_hash: model.package.project_id)
end
end