discourse/lib/s3_helper.rb

101 lines
2.6 KiB
Ruby

require "aws-sdk"
class S3Helper
class SettingMissing < StandardError; end
attr_reader :s3_bucket_name
def initialize(s3_upload_bucket, tombstone_prefix = '', options = {})
@s3_options = default_s3_options.merge(options)
@s3_bucket_name, @s3_bucket_folder_path = begin
raise Discourse::InvalidParameters.new("s3_bucket") if s3_upload_bucket.blank?
s3_upload_bucket.downcase.split("/".freeze, 2)
end
@tombstone_prefix =
if @s3_bucket_folder_path
File.join(@s3_bucket_folder_path, tombstone_prefix)
else
tombstone_prefix
end
check_missing_options
end
def upload(file, path, options = {})
path = get_path_for_s3_upload(path)
obj = s3_bucket.object(path)
obj.upload_file(file, options)
path
end
def remove(s3_filename, copy_to_tombstone = false)
bucket = s3_bucket
# copy the file in tombstone
if copy_to_tombstone && @tombstone_prefix.present?
bucket
.object(File.join(@tombstone_prefix, s3_filename))
.copy_from(copy_source: File.join(@s3_bucket_name, get_path_for_s3_upload(s3_filename)))
end
# delete the file
bucket.object(get_path_for_s3_upload(s3_filename)).delete
rescue Aws::S3::Errors::NoSuchKey
end
def update_tombstone_lifecycle(grace_period)
return if @tombstone_prefix.blank?
# cf. http://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html
s3_resource.client.put_bucket_lifecycle(bucket: @s3_bucket_name,
lifecycle_configuration: {
rules: [
{
id: "purge-tombstone",
status: "Enabled",
expiration: { days: grace_period },
prefix: @tombstone_prefix
}
]
})
end
private
def get_path_for_s3_upload(path)
path = File.join(@s3_bucket_folder_path, path) if @s3_bucket_folder_path
path
end
def default_s3_options
opts = { region: SiteSetting.s3_region }
unless SiteSetting.s3_use_iam_profile
opts[:access_key_id] = SiteSetting.s3_access_key_id
opts[:secret_access_key] = SiteSetting.s3_secret_access_key
end
opts
end
def s3_resource
Aws::S3::Resource.new(@s3_options)
end
def s3_bucket
bucket = s3_resource.bucket(@s3_bucket_name)
bucket.create unless bucket.exists?
bucket
end
def check_missing_options
unless SiteSetting.s3_use_iam_profile
raise SettingMissing.new("access_key_id") if @s3_options[:access_key_id].blank?
raise SettingMissing.new("secret_access_key") if @s3_options[:secret_access_key].blank?
end
end
end