Class: Blufin::AWS

Inherits:
Object
  • Object
show all
Defined in:
lib/core/aws.rb

Constant Summary collapse

FILE_AWS_CONFIG =
File.expand_path('~/.aws/config')
FILE_AWS_CREDENTIALS =
File.expand_path('~/.aws/credentials')
S3_EXCLUDE =
"--exclude '.DS_Store' --exclude '*/.DS_Store' --exclude '*.icloud' --exclude '*/*.icloud'"

Class Method Summary collapse

Class Method Details

.download_s3_data(bucket_name, bucket_path, file: nil, profile: nil, region: nil, use_cache: true) ⇒ Object

Pulls a file from S3 and saves it to the /tmp folder. To avoid making multiple calls, caching is turned on by default.

Raises:

  • (RuntimeError)


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
# File 'lib/core/aws.rb', line 51

def self.download_s3_data(bucket_name, bucket_path, file: nil, profile: nil, region: nil, use_cache: true)
    raise RuntimeError, 'profile cannot be nil.' if profile.nil?
    raise RuntimeError, 'region cannot be nil.' if region.nil?
    bucket_path     = Blufin::Strings::remove_surrounding_slashes(bucket_path).strip
    bucket_path_tmp = bucket_path.length > 0 ? "-#{bucket_path.gsub('/', '-')}" : ''
    bucket_path_s3  = bucket_path.length > 0 ? "/#{bucket_path}" : ''
    unless file.nil?
        bucket_path_tmp = "#{bucket_path_tmp}-#{file}"
        bucket_path_s3  = "#{bucket_path_s3}/#{file}"
    end
    tmp_location = "/tmp/awx-s3-cache-#{bucket_name}#{bucket_path_tmp}"
    # If path/file exists and we're using cached values, simply return.
    if file.nil?
        return tmp_location if Blufin::Files::path_exists(tmp_location) && use_cache && Blufin::Files::get_files_in_dir(tmp_location).any?
    else
        return tmp_location if Blufin::Files::file_exists(tmp_location) && use_cache
    end
    # Get profile name.
    profile_name = profile.nil? ? App::AWSProfile::get_profile_name : " --profile #{profile}"
    begin
        # Clear out all (possibly stale) files.
        puts
        raise RuntimeError unless Blufin::Terminal::execute_proc("Wiping temp-data: #{Blufin::Terminal::format_directory(tmp_location)}", Proc.new {
            system("rm -rf #{tmp_location}") if file.nil? && Blufin::Files::path_exists(tmp_location)
            system("rm #{tmp_location}") if !file.nil? && Blufin::Files::file_exists(tmp_location)
            Blufin::Files::create_directory(tmp_location) if file.nil?
            true
        }, verbose: true)
        raise RuntimeError unless Blufin::Terminal::execute("aws s3 cp s3://#{bucket_name}#{bucket_path_s3} #{tmp_location}#{file.nil? ? ' --recursive' : ''} --region #{region}#{profile_name}", verbose: true)[0]
        tmp_location
    rescue
        system("rm -rf #{tmp_location}") if file.nil?
        system("rm #{tmp_location}") unless file.nil?
        Blufin::Terminal::error("Unable to download from S3 bucket: #{Blufin::Terminal::format_highlight("s3://#{bucket_name}#{bucket_path_s3}")}", "Either the bucket doesn't exist, you don't have permissions or something else is wrong.", true, false)
    end

end

.get_aws_credentials(profile) ⇒ Object

Checks if AWS credentials exist. Does nothing if on EC2.



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
# File 'lib/core/aws.rb', line 91

def self.get_aws_credentials(profile)
    credentials = nil
    errors      = []
    if Blufin::Files::file_exists(FILE_AWS_CREDENTIALS)
        credentials        = Blufin::AWSCredentials.new
        config             = Blufin::Files::file_exists(FILE_AWS_CONFIG) ? ParseConfig.new(FILE_AWS_CONFIG) : nil
        credentials_parsed = ParseConfig.new(FILE_AWS_CREDENTIALS)
        unless credentials_parsed.params[profile].nil?
            # Currently not used/required (but here just in case).
            unless config.nil? || config.params[profile].nil?
                credentials.region = config.params[profile]['region'] unless config.params[profile]['region'].nil?
                credentials.output = config.params[profile]['output'] unless config.params[profile]['output'].nil?

            end
            credentials.aws_key    = credentials_parsed.params[profile]['aws_access_key_id'] unless credentials_parsed.params[profile]['aws_access_key_id'].nil?
            credentials.aws_secret = credentials_parsed.params[profile]['aws_secret_access_key'] unless credentials_parsed.params[profile]['aws_secret_access_key'].nil?
        end
        errors << "aws-cli error. Cannot find #{profile}: #{Blufin::Terminal::format_invalid('aws_access_key_id')} in: #{Blufin::Terminal::format_directory(FILE_AWS_CREDENTIALS)}" if credentials.aws_key.nil?
        errors << "aws-cli error. Cannot find #{profile}: #{Blufin::Terminal::format_invalid('aws_secret_access_key')} in: #{Blufin::Terminal::format_directory(FILE_AWS_CREDENTIALS)}" if credentials.aws_secret.nil?
    else
        # Returns 'yes' if running on EC2 instance, 'no' if not.
        unless `#{Blufin::Base::get_base_path}/#{Blufin::Base::OPT_PATH}/shell/ec2-check`.to_s.gsub("\n", '') =~ /yes/i
            errors << "aws-cli error. Cannot find file: #{Blufin::Terminal::format_invalid(FILE_AWS_CREDENTIALS)}"
        end
    end
    return credentials, errors
end

.is_ec2Object

Checks if script is running on an EC2 instance. Not sure if this is 100% reliable, but it’s about as good as it gets I think.

Returns:

  • bool



13
14
15
16
17
# File 'lib/core/aws.rb', line 13

def self.is_ec2
    res = `#{Blufin::Base::get_base_path}#{Blufin::Base::OPT_PATH}/shell/ec2-check`.to_s
    res = Blufin::Strings::strip_newline(res)
    res.downcase.strip == 'yes'
end

.upload_s3_data(bucket_name, bucket_path, file_or_path, profile: nil, region: nil, is_file: false, dryrun: false) ⇒ Object

Uploads a file (or path) to S3. If path, will upload recursively (which is mandatory with s3 sync command).

Raises:

  • (RuntimeError)


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
# File 'lib/core/aws.rb', line 21

def self.upload_s3_data(bucket_name, bucket_path, file_or_path, profile: nil, region: nil, is_file: false, dryrun: false)
    raise RuntimeError, 'profile cannot be nil.' if profile.nil?
    raise RuntimeError, 'region cannot be nil.' if region.nil?
    raise RuntimeError, "File or path not found: #{file_or_path}" unless Blufin::Files::file_exists(file_or_path)
    file_or_path   = File.expand_path(file_or_path)
    bucket_path    = Blufin::Strings::remove_surrounding_slashes(bucket_path).strip
    bucket_path_s3 = bucket_path.length > 0 ? "/#{bucket_path}" : ''
    s3_url         = "s3://#{bucket_name}#{bucket_path_s3}"
    begin
        if is_file
            cmd = "aws s3 cp #{file_or_path} #{s3_url} --region #{region}#{App::AWS::get_profile_for_cli}"
        else
            cmd = "aws s3 sync #{file_or_path} #{s3_url} --delete --region #{region}#{App::AWS::get_profile_for_cli}"
        end
        if dryrun
            cmd = "#{cmd} --dryrun"
            Blufin::Terminal::info('Performing Dry Run:', Blufin::Terminal::format_command(cmd))
            system("#{cmd} #{S3_EXCLUDE} --exclude '*.blank*'")
        else
            raise RuntimeError unless Blufin::Terminal::execute("#{cmd} #{S3_EXCLUDE} --exclude '*.blank*'", verbose: true, text: cmd)[0]
        end
        s3_url
    rescue
        Blufin::Terminal::error("Unable to download from S3 bucket: #{Blufin::Terminal::format_highlight(s3_url)}", "Either the bucket doesn't exist, you don't have permissions or something else is wrong.", true, false)
    end
end