Class: Lono::S3::Uploader

Inherits:
Object
  • Object
show all
Extended by:
Memoist
Includes:
AwsServices
Defined in:
lib/lono/s3/uploader.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from AwsServices

#cfn, #ec2, #iam, #s3, #s3_presigner, #s3_resource, #sts

Methods included from AwsServices::Helper

#rollback_complete?, #testing_update?

Methods included from AwsServices::StackSet

#find_stack_set, #stack_set_exists?

Methods included from AwsServices::Stack

#find_stack, #stack_exists?

Constructor Details

#initialize(path, options = {}) ⇒ Uploader

Returns a new instance of Uploader.



7
8
9
10
# File 'lib/lono/s3/uploader.rb', line 7

def initialize(path, options={})
  @path, @options = path, options
  @checksums = {}
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



6
7
8
# File 'lib/lono/s3/uploader.rb', line 6

def path
  @path
end

Instance Method Details

#https_urlObject



47
48
49
50
# File 'lib/lono/s3/uploader.rb', line 47

def https_url
  key = "#{Lono.env}/#{@path}"
  "https://s3.amazonaws.com/#{s3_bucket}/#{key}"
end

#load_checksums!(prefix) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/lono/s3/uploader.rb', line 63

def load_checksums!(prefix)
  resp = s3.list_objects(bucket: s3_bucket, prefix: prefix)
  resp.contents.each do |object|
    # key does not include the bucket name
    #    full path = s3://my-bucket/s3_folder/files/production/my-template.yml
    #    key = s3_folder/files/production/my-template.yml
    # etag is the checksum as long as the file is not a multi-part file upload
    # it has extra double quotes wrapped around it.
    #    etag = "\"9cb437490cee2cc96101baf326e5ca81\""
    @checksums[object.key] = strip_surrounding_quotes(object.etag)
  end
  @checksums
end

#md5(path) ⇒ Object

used for file_s3_key helper



58
59
60
# File 'lib/lono/s3/uploader.rb', line 58

def md5(path)
  Digest::MD5.file(path).to_s[0..7]
end

#presigned_urlObject



52
53
54
55
# File 'lib/lono/s3/uploader.rb', line 52

def presigned_url
  key = "#{Lono.env}/#{@path}"
  s3_presigner.presigned_url(:get_object, bucket: s3_bucket, key: key)
end

#remote_checksum(key) ⇒ Object

key example: cloudformation/production/files/lifecycle-0719ab81.zip s3 path: s3://boltops-dev/cloudformation/production/files/lifecycle-0719ab81.zip s3_folder: s3://boltops-dev/cloudformation



81
82
83
84
# File 'lib/lono/s3/uploader.rb', line 81

def remote_checksum(key)
  load_checksums!(key)
  @checksums[key]
end

#s3_bucketObject



90
91
92
# File 'lib/lono/s3/uploader.rb', line 90

def s3_bucket
  Lono::S3::Bucket.name
end

#strip_surrounding_quotes(string) ⇒ Object



86
87
88
# File 'lib/lono/s3/uploader.rb', line 86

def strip_surrounding_quotes(string)
  string.sub(/^"/,'').sub(/"$/,'')
end

#uploadObject

Inputs:

path: can be full path or relative path


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
# File 'lib/lono/s3/uploader.rb', line 16

def upload
  return if @options[:noop] || ENV['LONO_TEST'] == '1'

  path = @path.gsub("#{Lono.root}/",'') # remove Lono.root
  key = "#{Lono.env}/#{path}"

  pretty_path = path.sub(/^\.\//, '')
  s3_full_path = "s3://#{s3_bucket}/#{key}"

  local_checksum = Digest::MD5.hexdigest(IO.read(path))
  remote_checksum = remote_checksum(key)
  if local_checksum == remote_checksum
    puts("Not modified: #{pretty_path} to #{s3_full_path}".color(:yellow)) unless @options[:noop]
    return # do not upload unless the checksum has changed
  else
    # Example output:
    # Uploaded: app/files/docker.yml to s3://boltops-dev/s3_folder/templates/development/docker.yml
    # Uploaded: app/files/ecs/private.yml to s3://boltops-dev/s3_folder/templates/development/ecs/private.yml
    message = "Uploading: #{pretty_path} to #{s3_full_path}".color(:green)
    message = "NOOP: #{message}" if @options[:noop]
    puts message
  end

  s3.put_object(
    body: IO.read(path),
    bucket: s3_bucket,
    key: key,
  ) unless @options[:noop]
end