* Add Redis and Sidekiq * Rename PreviewGenerationMonitor * Update production.rb require master key * Initialize AWS at application start * Add fallbacks for credentials * Add logging * Create railway.toml
98 lines
2.8 KiB
Ruby
98 lines
2.8 KiB
Ruby
class AwsService
|
|
attr_reader :s3_client, :bucket
|
|
|
|
class ConfigurationError < StandardError; end
|
|
|
|
def initialize
|
|
Rails.logger.info "Environment: #{Rails.env}"
|
|
|
|
# Try different methods of getting credentials
|
|
creds = get_credentials
|
|
Rails.logger.info "Credentials source: #{creds[:source]}"
|
|
|
|
@s3_client = Aws::S3::Client.new(
|
|
region: creds[:region],
|
|
access_key_id: creds[:access_key_id],
|
|
secret_access_key: creds[:secret_access_key]
|
|
)
|
|
@bucket = creds[:bucket_name]
|
|
rescue KeyError => e
|
|
raise ConfigurationError, "Missing AWS credential: #{e.message}"
|
|
end
|
|
|
|
def upload_stream(io, key)
|
|
@s3_client.put_object(
|
|
bucket: @bucket,
|
|
key: key,
|
|
body: io
|
|
)
|
|
end
|
|
|
|
def file_exists?(key)
|
|
@s3_client.head_object(
|
|
bucket: @bucket,
|
|
key: key
|
|
)
|
|
true
|
|
rescue Aws::S3::Errors::NotFound
|
|
false
|
|
end
|
|
|
|
private
|
|
|
|
def get_credentials
|
|
# Try Rails credentials first
|
|
rails_creds = Rails.application.credentials.dig(:aws)
|
|
if rails_creds&.dig(:access_key_id)
|
|
Rails.logger.info "Using Rails credentials"
|
|
return rails_creds.merge(source: 'rails_credentials')
|
|
end
|
|
|
|
# Try string keys
|
|
rails_creds = Rails.application.credentials.dig('aws')
|
|
if rails_creds&.dig('access_key_id')
|
|
Rails.logger.info "Using Rails credentials (string keys)"
|
|
return {
|
|
region: rails_creds['region'],
|
|
access_key_id: rails_creds['access_key_id'],
|
|
secret_access_key: rails_creds['secret_access_key'],
|
|
bucket_name: rails_creds['bucket_name'],
|
|
source: 'rails_credentials_string'
|
|
}
|
|
end
|
|
|
|
# Try environment variables
|
|
if ENV['AWS_ACCESS_KEY_ID']
|
|
Rails.logger.info "Using environment variables"
|
|
return {
|
|
region: ENV['AWS_REGION'],
|
|
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
|
|
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
|
|
bucket_name: ENV['AWS_BUCKET_NAME'],
|
|
source: 'environment'
|
|
}
|
|
end
|
|
|
|
# Try alternate environment variable names
|
|
if ENV['RAILS_AWS_ACCESS_KEY_ID']
|
|
Rails.logger.info "Using Rails-prefixed environment variables"
|
|
return {
|
|
region: ENV['RAILS_AWS_REGION'],
|
|
access_key_id: ENV['RAILS_AWS_ACCESS_KEY_ID'],
|
|
secret_access_key: ENV['RAILS_AWS_SECRET_ACCESS_KEY'],
|
|
bucket_name: ENV['RAILS_AWS_BUCKET_NAME'],
|
|
source: 'rails_environment'
|
|
}
|
|
end
|
|
|
|
validate_credentials = ->(creds, source) {
|
|
missing = []
|
|
%i[region access_key_id secret_access_key bucket_name].each do |key|
|
|
missing << key unless creds[key].present?
|
|
end
|
|
raise ConfigurationError, "Missing AWS credentials from #{source}: #{missing.join(', ')}" if missing.any?
|
|
}
|
|
|
|
raise ConfigurationError, "No AWS credentials found in any location"
|
|
end
|
|
end
|