require 'aws-sdk-s3' require 'dotenv/load' module Eco module API module Common module Session class S3Uploader attr_reader :prefix def initialize (enviro:) raise "Required Environment object (enviro:). Given: #{enviro}" if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment) @enviro = enviro @prefix = fetch_prefix @timestamp = Time.now.iso8601 end def upload(filename, content) if obj = new_s3_object(filename) log_upload(obj) do obj.put(body: content) end end return full_path(obj) end def upload_file(path) File.open(path, "rb") do |f| upload(File.basename(path), f) end end def upload_directory(path) path = File.expand_path(path) prefix = File.expand_path(File.join(path, "..")) Dir.glob(File.join(path, "**/*")).sort.map do |file| next unless File.file?(file) # Skip directories key = file.sub(prefix,"").gsub(/\\/,"/").sub(/^\/+/,"") File.open(file, "rb") do |f| upload(key, f) end end.compact end private def full_path(obj) return "s3://#{bucket.name}/#{obj.key}" if obj end def bucket begin @bucket ||= Aws::S3::Resource.new( access_key_id: fetch_access_key_id, secret_access_key: fetch_secret_access_key, region: fetch_region ).bucket(fetch_bucket) rescue Exception => e logger.error("Trying to upload to S3 with wrong configuration: #{e}") end @bucket end def session_path ["scripts", @prefix, @timestamp].join("/") end def new_s3_object(filename) file_path = [session_path, filename].join("/") bucket&.object(file_path) end def log_upload(obj) yield logger.debug("Uploaded #{full_path(obj)}") end def logger @enviro&.logger || ::Logger.new(IO::NULL) end def config @enviro.config || {} end def fetch_bucket config.s3storage.bucket_name end def fetch_prefix config.s3storage.prefix end def fetch_access_key_id config.s3storage.access_key_id || ENV['AWS_ACCESS_KEY_ID'] end def fetch_secret_access_key config.s3storage.secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'] end def fetch_region config.s3storage.region || ENV['AWS_REGION'] end end end end end end