1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# frozen_string_literal: true
module ObjectStorage
class Config
include Gitlab::Utils::StrongMemoize
AWS_PROVIDER = 'AWS'
AZURE_PROVIDER = 'AzureRM'
GOOGLE_PROVIDER = 'Google'
attr_reader :options
def initialize(options)
@options = options.to_hash.deep_symbolize_keys
end
def load_provider
if aws?
require 'fog/aws'
elsif google?
require 'fog/google'
elsif azure?
require 'fog/azurerm'
end
end
def credentials
@credentials ||= options[:connection] || {}
end
def storage_options
@storage_options ||= options[:storage_options] || {}
end
def enabled?
options[:enabled]
end
def bucket
options[:remote_directory]
end
def consolidated_settings?
options.fetch(:consolidated_settings, false)
end
# AWS-specific options
def aws?
provider == AWS_PROVIDER
end
def use_iam_profile?
Gitlab::Utils.to_boolean(credentials[:use_iam_profile], default: false)
end
def use_path_style?
Gitlab::Utils.to_boolean(credentials[:path_style], default: false)
end
def server_side_encryption
storage_options[:server_side_encryption]
end
def server_side_encryption_kms_key_id
storage_options[:server_side_encryption_kms_key_id]
end
def provider
credentials[:provider].to_s
end
# This method converts fog-aws parameters to an endpoint for the
# Workhorse S3 client.
def s3_endpoint
strong_memoize(:s3_endpoint) do
# We could omit this line and let the following code handle this, but
# this will ensure that working configurations that use `endpoint`
# will continue to work.
next credentials[:endpoint] if credentials[:endpoint].present?
generate_s3_endpoint_from_credentials
end
end
def generate_s3_endpoint_from_credentials
# fog-aws has special handling of the host, region, scheme, etc:
# https://github.com/fog/fog-aws/blob/c7a11ba377a76d147861d0e921eb1e245bc11b6c/lib/fog/aws/storage.rb#L440-L449
# Rather than reimplement this, we derive it from a sample GET URL.
url = fog_connection.get_object_url(bucket, "tmp", nil)
uri = ::Addressable::URI.parse(url)
return unless uri&.scheme && uri&.host
endpoint = "#{uri.scheme}://#{uri.host}"
endpoint += ":#{uri.port}" if uri.port
endpoint
rescue ::URI::InvalidComponentError, ::Addressable::URI::InvalidURIError => e
Gitlab::ErrorTracking.track_exception(e)
nil
end
# End AWS-specific options
# Begin Azure-specific options
def azure_storage_domain
credentials[:azure_storage_domain]
end
# End Azure-specific options
def google?
provider == GOOGLE_PROVIDER
end
def azure?
provider == AZURE_PROVIDER
end
def fog_attributes
@fog_attributes ||= begin
return {} unless enabled? && aws?
return {} unless server_side_encryption.present?
aws_server_side_encryption_headers.compact
end
end
def fog_connection
@connection ||= ::Fog::Storage.new(credentials)
end
private
# This returns a Hash of HTTP encryption headers to send along to S3.
#
# They can also be passed in as Fog::AWS::Storage::File attributes, since there
# are aliases defined for them:
# https://github.com/fog/fog-aws/blob/ab288f29a0974d64fd8290db41080e5578be9651/lib/fog/aws/models/storage/file.rb#L24-L25
def aws_server_side_encryption_headers
{
'x-amz-server-side-encryption' => server_side_encryption,
'x-amz-server-side-encryption-aws-kms-key-id' => server_side_encryption_kms_key_id
}
end
end
end
|