Class: Lono::Template::Upload
- Inherits:
-
Object
- Object
- Lono::Template::Upload
- Includes:
- AwsServices
- Defined in:
- lib/lono/template/upload.rb
Instance Method Summary collapse
-
#ensure_s3_setup! ⇒ Object
nice warning if the s3 path not found.
-
#initialize(options = {}) ⇒ Upload
constructor
A new instance of Upload.
-
#load_checksums! ⇒ Object
Read existing files on s3 to grab their md5 checksum.
-
#remote_checksum(path) ⇒ Object
path = ./output/docker.yml s3_path = s3://boltops-stag/cloudformation-templates/stag/docker.yml.
- #run ⇒ Object
-
#s3_bucket ⇒ Object
Example: s3_bucket(‘s3://mybucket/templates/storage/path’) => mybucket.
- #s3_https_url(template_path) ⇒ Object
-
#s3_path ⇒ Object
Example: s3_bucket(‘s3://mybucket/templates/storage/path’) => templates/storage/path.
- #say(message) ⇒ Object
- #strip_surrounding_quotes(string) ⇒ Object
- #upload(path) ⇒ Object
Methods included from AwsServices
Constructor Details
#initialize(options = {}) ⇒ Upload
Returns a new instance of Upload.
9 10 11 12 |
# File 'lib/lono/template/upload.rb', line 9 def initialize(={}) @options = @checksums = {} end |
Instance Method Details
#ensure_s3_setup! ⇒ Object
nice warning if the s3 path not found
116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/lono/template/upload.rb', line 116 def ensure_s3_setup! return if @options[:noop] settings = Lono::Settings.new if settings.s3_path @s3_full_path = settings.s3_path else say "Unable to upload templates to s3 because you have not configured the s3.path option in lono settings.yml.".colorize(:red) say "Please configure settings.yml with s3.path. Refer to http://lono.cloud/docs/settings/ for more help.".colorize(:red) exit 1 end end |
#load_checksums! ⇒ Object
Read existing files on s3 to grab their md5 checksum. We do this so we can see if we should avoid re-uploading the s3 child template entirely. If we upload a new child template that does not change AWS CloudFormation is not smart enough to know that it not has changed. I think all AWS CloudFormation does is check if the file’s timestamp.
Thought this would result in better AWS Change Set info but AWS still reports child stacks being changed even though they should not be reported. Leaving this s3 checksum in for now.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/lono/template/upload.rb', line 35 def load_checksums! return if @options[:noop] prefix = "#{s3_path}/#{Lono.env}" # s3://s3-bucket-and-path-from-settings/prod 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/cloudformation-templates/prod/my-template.yml # key = cloudformation-templates/prod/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 |
#remote_checksum(path) ⇒ Object
path = ./output/docker.yml s3_path = s3://boltops-stag/cloudformation-templates/stag/docker.yml
87 88 89 90 91 92 93 |
# File 'lib/lono/template/upload.rb', line 87 def remote_checksum(path) # first convert the local path to the path format that is stored in @checksums keys # ./output/docker.yml => cloudformation-templates/stag/docker.yml pretty_path = path.sub(/^\.\//, '') key = "#{s3_path}/#{Lono.env}/#{pretty_path.sub(/^output\//,'')}" @checksums[key] end |
#run ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/lono/template/upload.rb', line 14 def run ensure_s3_setup! load_checksums! paths = Dir.glob("#{Lono.root}/output/**/*") paths.reject { |p| p =~ %r{output/params} }. select { |p| File.file?(p) }.each do |path| upload(path) end say "Templates uploaded to s3." end |
#s3_bucket ⇒ Object
Example:
s3_bucket('s3://mybucket/templates/storage/path') => mybucket
103 104 105 106 |
# File 'lib/lono/template/upload.rb', line 103 def s3_bucket return '' if @options[:noop] # to get spec passing @s3_full_path.sub('s3://','').split('/').first end |
#s3_https_url(template_path) ⇒ Object
96 97 98 99 |
# File 'lib/lono/template/upload.rb', line 96 def s3_https_url(template_path) ensure_s3_setup! "https://s3.amazonaws.com/#{s3_bucket}/#{s3_path}/#{Lono.env}/#{template_path}" end |
#s3_path ⇒ Object
Example:
s3_bucket('s3://mybucket/templates/storage/path') => templates/storage/path
110 111 112 113 |
# File 'lib/lono/template/upload.rb', line 110 def s3_path return '' if @options[:noop] # to get spec passing @s3_full_path.sub('s3://','').split('/')[1..-1].join('/') end |
#say(message) ⇒ Object
129 130 131 |
# File 'lib/lono/template/upload.rb', line 129 def say() puts unless @options[:quiet] end |
#strip_surrounding_quotes(string) ⇒ Object
52 53 54 |
# File 'lib/lono/template/upload.rb', line 52 def strip_surrounding_quotes(string) string.sub(/^"/,'').sub(/"$/,'') end |
#upload(path) ⇒ Object
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 |
# File 'lib/lono/template/upload.rb', line 56 def upload(path) pretty_path = path.sub(/^\.\//, '') key = "#{s3_path}/#{Lono.env}/#{pretty_path.sub(/^output\//,'')}" s3_full_path = "s3://#{s3_bucket}/#{key}" local_checksum = Digest::MD5.hexdigest(IO.read(path)) remote_checksum = remote_checksum(path) if local_checksum == remote_checksum say("Not modified: #{pretty_path} to #{s3_full_path}".colorize(:yellow)) unless @options[:noop] return # do not upload unless the checksum has changed end resp = s3.put_object( body: IO.read(path), bucket: s3_bucket, key: key, storage_class: "REDUCED_REDUNDANCY" ) unless @options[:noop] # Example output: # Uploaded: output/docker.yml to s3://boltops-stag/cloudformation-templates/stag/docker.yml # Uploaded: output/ecs/private.yml to s3://boltops-stag/cloudformation-templates/stag/ecs/private.yml = "Uploaded: #{pretty_path} to #{s3_full_path}".colorize(:green) = "NOOP: #{}" if @options[:noop] say end |