branchable_cdn_assets 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/branchable_cdn_assets.rb +1 -1
- data/lib/branchable_cdn_assets/config.rb +24 -4
- data/lib/branchable_cdn_assets/file_manager.rb +27 -15
- data/lib/branchable_cdn_assets/file_manager/checks.rb +7 -2
- data/lib/branchable_cdn_assets/invalidator.rb +24 -0
- data/lib/branchable_cdn_assets/invalidator/akamai_ccu.rb +63 -0
- data/lib/branchable_cdn_assets/invalidator/akamai_ccu/http.rb +116 -0
- data/lib/branchable_cdn_assets/invalidator/base.rb +45 -0
- data/lib/branchable_cdn_assets/invalidator/cloudfront.rb +25 -0
- data/lib/branchable_cdn_assets/manifest.rb +2 -2
- data/lib/branchable_cdn_assets/version.rb +2 -2
- data/spec/lib/branchable_cdn_assets/config_spec.rb +51 -11
- data/spec/lib/branchable_cdn_assets/file_manager/find_spec.rb +37 -1
- data/spec/lib/branchable_cdn_assets/file_manager_spec.rb +37 -11
- data/spec/lib/branchable_cdn_assets/invalidator/base_spec.rb +91 -0
- data/spec/lib/{cloudfront_spec.rb → branchable_cdn_assets/invalidator/cloudfront_spec.rb} +11 -9
- data/spec/lib/branchable_cdn_assets/invalidator_spec.rb +53 -0
- data/spec/lib/branchable_cdn_assets/manifest_spec.rb +2 -1
- metadata +27 -19
- data/lib/branchable_cdn_assets/cloudfront.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49f567d337137eb1f553b71d39026a2e0db533c4
|
4
|
+
data.tar.gz: a83f8ddb7c0346a5a0f2df8c63b863af7ee8f470
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 037301f07920418a121d73155478f9e5a3418647e49d7cdd3610103f8553f5cbf7f8be9c4e39b20c12dffde15f51983319bf7a44fc2a4bca45db9b39e80d3d10
|
7
|
+
data.tar.gz: 1b96408f5465c10d4bada8e114f2f3d955ebebb96b21a0b80cf2a30254209c83043241bdb621afa4c52b1f28fbc94c5fa6a2c95b1895ba058c7ca2ae3392eab8
|
@@ -14,7 +14,7 @@ require_relative 'branchable_cdn_assets/shell'
|
|
14
14
|
require_relative 'branchable_cdn_assets/file_manager'
|
15
15
|
require_relative 'branchable_cdn_assets/manifest'
|
16
16
|
require_relative 'branchable_cdn_assets/config'
|
17
|
-
require_relative 'branchable_cdn_assets/
|
17
|
+
require_relative 'branchable_cdn_assets/invalidator'
|
18
18
|
|
19
19
|
module BranchableCDNAssets
|
20
20
|
end
|
@@ -6,20 +6,25 @@ module BranchableCDNAssets
|
|
6
6
|
extend EnvironmentAttributeReader::ClassMethods
|
7
7
|
|
8
8
|
attr_reader :raw_data, :branch,
|
9
|
-
:production_branch, :
|
9
|
+
:production_branch, :cdn_dir, :file_filter,
|
10
10
|
:dir_permissions, :file_permissions, :rsync_flags
|
11
|
-
env_attr_reader :host, :root, :url
|
11
|
+
env_attr_reader :host, :root, :url
|
12
12
|
|
13
13
|
def initialize data, branch=Asgit.current_branch
|
14
14
|
@raw_data = normalize_data data
|
15
15
|
@branch = branch
|
16
16
|
|
17
17
|
@production_branch = raw_data.fetch :production_branch, 'master'
|
18
|
-
@cloudfront = raw_data.fetch :cloudfront, {}
|
19
18
|
@cdn_dir = raw_data.fetch :dir, 'cdn'
|
19
|
+
@file_filter = raw_data.fetch :file_filter, nil
|
20
20
|
@dir_permissions = env_attr(:dir_permissions) || 755
|
21
21
|
@file_permissions = env_attr(:file_permissions) || 644
|
22
22
|
@rsync_flags = env_attr(:rsync_flags) || '-aviz'
|
23
|
+
@allow_local = env_attr(:allow_local) || false
|
24
|
+
|
25
|
+
if @file_filter && ( !@file_filter.respond_to?(:arity) || @file_filter.arity != 1 )
|
26
|
+
raise ArgumentError, "file_filter must be a lambda accepting one argument"
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
25
30
|
def env
|
@@ -42,6 +47,21 @@ module BranchableCDNAssets
|
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
50
|
+
def invalidator
|
51
|
+
return @_invalidator if @_invalidator
|
52
|
+
|
53
|
+
invalidator_data = env_attr(:invalidator)
|
54
|
+
return false unless invalidator_data
|
55
|
+
|
56
|
+
invalidator_class = Invalidator.find(invalidator_data.keys.first)
|
57
|
+
if invalidator_class
|
58
|
+
@_invalidator = invalidator_class.new invalidator_data.values.first
|
59
|
+
return @_invalidator
|
60
|
+
else
|
61
|
+
raise ArgumentError, "no invalidators registered for key :#{invalidator_data.keys.first}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
45
65
|
private
|
46
66
|
|
47
67
|
class Remote < Struct.new(:host, :root, :url,
|
@@ -113,4 +133,4 @@ module BranchableCDNAssets
|
|
113
133
|
end
|
114
134
|
|
115
135
|
end
|
116
|
-
end
|
136
|
+
end
|
@@ -10,10 +10,8 @@ module BranchableCDNAssets
|
|
10
10
|
check_before :local_file_conflict, methods: [ :push!, :pull! ]
|
11
11
|
check_before :ready_for_production, methods: [ :move_to_production ]
|
12
12
|
|
13
|
-
attr_reader :config
|
14
|
-
|
15
|
-
attr_reader :branch
|
16
|
-
attr_reader :manifest
|
13
|
+
attr_reader :config, :manifest,
|
14
|
+
:root, :branch
|
17
15
|
|
18
16
|
# handles moving files to/from our various cdn locations
|
19
17
|
def initialize config, branch=nil
|
@@ -62,7 +60,7 @@ module BranchableCDNAssets
|
|
62
60
|
setup_remotes
|
63
61
|
|
64
62
|
push_list = push
|
65
|
-
if config.env.to_sym == :production
|
63
|
+
if config.env.to_sym == :production
|
66
64
|
invalidate( push_list )
|
67
65
|
end
|
68
66
|
|
@@ -108,11 +106,14 @@ module BranchableCDNAssets
|
|
108
106
|
end
|
109
107
|
|
110
108
|
|
111
|
-
def find file
|
112
|
-
|
113
|
-
|
109
|
+
def find file, location=:all
|
110
|
+
if [:all, :local].include?(location) && list(:local).include?(file)
|
111
|
+
return :local
|
112
|
+
elsif [:all, :remote].include?(location) && list(:remote).include?(file)
|
113
|
+
return File.join(config.url, file)
|
114
|
+
end
|
114
115
|
|
115
|
-
|
116
|
+
if config.env != :production && location != :local
|
116
117
|
production_config = Config.new( config.raw_data, config.production_branch )
|
117
118
|
production_manifest = Manifest.new( File.join( root, "#{config.production_branch}.manifest" ) )
|
118
119
|
|
@@ -222,12 +223,17 @@ module BranchableCDNAssets
|
|
222
223
|
end
|
223
224
|
|
224
225
|
def invalidate files
|
225
|
-
|
226
|
-
|
227
|
-
|
226
|
+
if config.invalidator
|
227
|
+
to_invalidate = ( files & list(:local) ).map do |f|
|
228
|
+
if config.invalidator.config.respond_to? :path_prefix
|
229
|
+
File.join( config.invalidator.config.path_prefix, f )
|
230
|
+
else
|
231
|
+
f
|
232
|
+
end
|
233
|
+
end
|
228
234
|
|
229
|
-
|
230
|
-
|
235
|
+
config.invalidator.invalidate_files( to_invalidate )
|
236
|
+
end
|
231
237
|
end
|
232
238
|
|
233
239
|
# create the root dir on remote
|
@@ -353,6 +359,12 @@ module BranchableCDNAssets
|
|
353
359
|
!f.match(/\.manifest$/) && !File.directory?(f)
|
354
360
|
end.map do |f|
|
355
361
|
f.sub( "#{File.join( Dir.pwd, root )}/", "" )
|
362
|
+
end.select do |f|
|
363
|
+
if config.file_filter
|
364
|
+
config.file_filter.call(f)
|
365
|
+
else
|
366
|
+
true
|
367
|
+
end
|
356
368
|
end
|
357
369
|
end
|
358
370
|
|
@@ -361,4 +373,4 @@ module BranchableCDNAssets
|
|
361
373
|
end
|
362
374
|
|
363
375
|
end
|
364
|
-
end
|
376
|
+
end
|
@@ -36,7 +36,12 @@ module BranchableCDNAssets
|
|
36
36
|
abort
|
37
37
|
end
|
38
38
|
|
39
|
-
if !list(:local).empty?
|
39
|
+
if config.allow_local && !(list(:both) - list(:local)).empty?
|
40
|
+
puts "local assets detected that aren't on the cdn\n" +
|
41
|
+
"you should push or remove them to continue\n" +
|
42
|
+
" " + (list(:both) - list(:local)).join("\n ")
|
43
|
+
abort
|
44
|
+
elsif !list(:local).empty?
|
40
45
|
puts "assets detected in the local cdn directory\n" +
|
41
46
|
"remove them by running the `prune` task"
|
42
47
|
abort
|
@@ -45,4 +50,4 @@ module BranchableCDNAssets
|
|
45
50
|
|
46
51
|
end
|
47
52
|
end
|
48
|
-
end
|
53
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module BranchableCDNAssets
|
2
|
+
module Invalidator
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def invalidators
|
6
|
+
@_invalidators ||= {}
|
7
|
+
return @_invalidators
|
8
|
+
end
|
9
|
+
|
10
|
+
def register invalidator_key, invalidator_class
|
11
|
+
invalidators[invalidator_key] = invalidator_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def find invalidator_key
|
15
|
+
invalidators.fetch invalidator_key, false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require_relative 'invalidator/base'
|
23
|
+
require_relative 'invalidator/cloudfront'
|
24
|
+
require_relative 'invalidator/akamai_ccu'
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module BranchableCDNAssets
|
2
|
+
module Invalidator
|
3
|
+
class AkamaiCCU < Base
|
4
|
+
|
5
|
+
PURGE_PATH = '/ccu/v2/queues'.freeze
|
6
|
+
STATUS_PATH = '/ccu/v2/queues'.freeze
|
7
|
+
PURGE_STATUS_PATH = '/ccu/v2/purges'.freeze
|
8
|
+
|
9
|
+
register_as :akamai
|
10
|
+
require_keys [:base_url, :access_token, :client_token, :secret_token]
|
11
|
+
|
12
|
+
set_defaults domain: 'production',
|
13
|
+
queue_name: 'default'
|
14
|
+
|
15
|
+
def invalidate_files files
|
16
|
+
url = File.join( config.base_url, PURGE_PATH, config.queue_name )
|
17
|
+
resp = HTTP.post( { access_token: config.access_token,
|
18
|
+
client_token: config.client_token,
|
19
|
+
secret_token: config.secret_token
|
20
|
+
}.merge( url: url,
|
21
|
+
body: {
|
22
|
+
action: 'invalidate',
|
23
|
+
domain: config.domain,
|
24
|
+
objects: Array(files)
|
25
|
+
}))
|
26
|
+
|
27
|
+
|
28
|
+
if resp.code.to_i == 201
|
29
|
+
puts "Posted invalidation for #{files.count} files:"
|
30
|
+
else
|
31
|
+
puts "Invalidation failed:"
|
32
|
+
end
|
33
|
+
|
34
|
+
JSON.parse(resp.body).each do |k,v|
|
35
|
+
puts "-> #{k}: #{v}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# queue status or purge status
|
40
|
+
def status id=nil
|
41
|
+
if id
|
42
|
+
resp = HTTP.get({ access_token: config.access_token,
|
43
|
+
client_token: config.client_token,
|
44
|
+
secret_token: config.secret_token
|
45
|
+
}.merge( url: File.join( config.base_url, PURGE_STATUS_PATH, id ) ))
|
46
|
+
else
|
47
|
+
resp = HTTP.get({ access_token: config.access_token,
|
48
|
+
client_token: config.client_token,
|
49
|
+
secret_token: config.secret_token
|
50
|
+
}.merge( url: File.join( config.base_url, STATUS_PATH, config.queue_name ) ))
|
51
|
+
end
|
52
|
+
|
53
|
+
puts "Status:"
|
54
|
+
JSON.parse(resp.body).each do |k,v|
|
55
|
+
puts "-> #{k}: #{v}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
require_relative 'akamai_ccu/http'
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
require 'net/http'
|
6
|
+
|
7
|
+
# examples for setting auth headers taken from akamai's edgrid wrapper
|
8
|
+
# https://github.com/akamai-open/AkamaiOPEN-edgegrid-ruby/blob/master/lib/akamai/edgegrid.rb
|
9
|
+
#
|
10
|
+
module BranchableCDNAssets
|
11
|
+
module Invalidator
|
12
|
+
class AkamaiCCU
|
13
|
+
|
14
|
+
class HTTP
|
15
|
+
|
16
|
+
attr_reader :ident, :time, :nonce,
|
17
|
+
:client_token, :access_token, :secret_token
|
18
|
+
|
19
|
+
def self.get opts={}
|
20
|
+
uri = URI.parse opts.fetch(:url)
|
21
|
+
http = Net::HTTP.new uri.host, uri.port
|
22
|
+
http.use_ssl = true
|
23
|
+
|
24
|
+
request = Net::HTTP::Get.new(opts.fetch(:url))
|
25
|
+
signed = self.new(opts).sign(request)
|
26
|
+
|
27
|
+
return http.request signed
|
28
|
+
end
|
29
|
+
|
30
|
+
# opts requires:
|
31
|
+
# action
|
32
|
+
# url
|
33
|
+
# and required keys for HTTP
|
34
|
+
#
|
35
|
+
def self.post opts={}
|
36
|
+
uri = URI.parse opts.fetch(:url)
|
37
|
+
http = Net::HTTP.new uri.host, uri.port
|
38
|
+
http.use_ssl = true
|
39
|
+
|
40
|
+
request = Net::HTTP::Post.new( opts.fetch(:url),
|
41
|
+
'Content-Type' => 'application/json' )
|
42
|
+
|
43
|
+
request.body = opts.fetch(:body).to_json
|
44
|
+
signed = self.new(opts).sign(request)
|
45
|
+
|
46
|
+
return http.request signed
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize opts={}
|
50
|
+
@ident = 'EG1-HMAC-SHA256'
|
51
|
+
@time = Time.now
|
52
|
+
@nonce = SecureRandom.uuid
|
53
|
+
|
54
|
+
@client_token = opts[:client_token]
|
55
|
+
@access_token = opts[:access_token]
|
56
|
+
@secret_token = opts[:secret_token]
|
57
|
+
end
|
58
|
+
|
59
|
+
def formatted_time
|
60
|
+
time.utc.strftime('%Y%m%dT%H:%M:%S+0000')
|
61
|
+
end
|
62
|
+
|
63
|
+
# return a signed http_request
|
64
|
+
def sign http_request
|
65
|
+
unsigned_auth_header = "#{ident} client_token=#{client_token};" +
|
66
|
+
"access_token=#{access_token};" +
|
67
|
+
"timestamp=#{formatted_time};" +
|
68
|
+
"nonce=#{nonce};"
|
69
|
+
|
70
|
+
uri = URI(http_request.path)
|
71
|
+
auth_header = base64_hmac_sha256 [ http_request.method,
|
72
|
+
uri.scheme,
|
73
|
+
http_request.key?('host') ? http_request['host'] : uri.host,
|
74
|
+
uri.request_uri,
|
75
|
+
'',
|
76
|
+
content_hash(http_request),
|
77
|
+
unsigned_auth_header ].join("\t"),
|
78
|
+
base64_hmac_sha256( formatted_time, secret_token )
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
http_request['Authorization'] = "#{unsigned_auth_header}signature=#{auth_header}"
|
83
|
+
|
84
|
+
return http_request
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def content_hash http_request
|
90
|
+
if http_request.method == 'POST' && http_request.body && http_request.body.length > 0
|
91
|
+
if http_request.body.length > 2048
|
92
|
+
body = http_request.body[0..2047]
|
93
|
+
else
|
94
|
+
body = http_request.body
|
95
|
+
end
|
96
|
+
|
97
|
+
return base64_sha256(body)
|
98
|
+
else
|
99
|
+
return ""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def base64_sha256 data
|
104
|
+
Base64.encode64( OpenSSL::Digest::SHA256.new.digest(data) ).strip
|
105
|
+
end
|
106
|
+
|
107
|
+
def base64_hmac_sha256 data, key
|
108
|
+
Base64.encode64( OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, key, data) ).strip
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module BranchableCDNAssets
|
2
|
+
module Invalidator
|
3
|
+
class Base
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def register_as key
|
7
|
+
BranchableCDNAssets::Invalidator.register key, self
|
8
|
+
end
|
9
|
+
|
10
|
+
def require_keys keys
|
11
|
+
@required_keys = Array(keys)
|
12
|
+
end
|
13
|
+
|
14
|
+
def required_keys
|
15
|
+
@required_keys ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_defaults opts={}
|
19
|
+
@defaults = opts
|
20
|
+
end
|
21
|
+
|
22
|
+
def defaults
|
23
|
+
@defaults ||= {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :config
|
28
|
+
|
29
|
+
def initialize config_opts={}
|
30
|
+
config_opts = self.class.defaults.merge config_opts
|
31
|
+
unless (self.class.required_keys - config_opts.keys).empty?
|
32
|
+
raise ArgumentError, "Missing required config keys: [#{(self.class.required_keys - config_opts.keys).join(', ')}]"
|
33
|
+
end
|
34
|
+
|
35
|
+
@config = Struct.new("Config_#{object_id}", *config_opts.keys).new(*config_opts.values)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param files [Array]
|
39
|
+
def invalidate_files files
|
40
|
+
raise NoMethodError, "invalidate_files hasn't been implemented for #{self.class}"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module BranchableCDNAssets
|
2
|
+
module Invalidator
|
3
|
+
class Cloudfront < Base
|
4
|
+
|
5
|
+
register_as :cloudfront
|
6
|
+
require_keys [:distribution_id, :access_key, :secret_key]
|
7
|
+
|
8
|
+
def cdn
|
9
|
+
@cdn ||= ::Fog::CDN.new provider: 'AWS',
|
10
|
+
aws_access_key_id: config.access_key,
|
11
|
+
aws_secret_access_key: config.secret_key
|
12
|
+
end
|
13
|
+
|
14
|
+
# invalidate a batch of files on fog
|
15
|
+
# @param files [Array]
|
16
|
+
def invalidate_files files
|
17
|
+
resp = cdn.post_invalidation( config.distribution_id, Array(files) )
|
18
|
+
resp.body["InvalidationBatch"]["Path"].each do |file|
|
19
|
+
puts "Posted an invalidation for #{file}".colorize( :green )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
module BranchableCDNAssets
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.7.0" unless defined?(BranchableCDNAssets::VERSION)
|
3
|
+
end
|
@@ -11,7 +11,15 @@ describe BranchableCDNAssets::Config do
|
|
11
11
|
production: {
|
12
12
|
host: 'production',
|
13
13
|
url: 'http://production.com',
|
14
|
-
root: '/var/www/production'
|
14
|
+
root: '/var/www/production',
|
15
|
+
invalidator: {
|
16
|
+
cloudfront: {
|
17
|
+
access_key: 'FooBar',
|
18
|
+
secret_key: 'SecretBaz',
|
19
|
+
distribution_id: 'Distro',
|
20
|
+
path_prefix: '/'
|
21
|
+
}
|
22
|
+
}
|
15
23
|
},
|
16
24
|
test: {
|
17
25
|
host: 'test',
|
@@ -28,12 +36,6 @@ describe BranchableCDNAssets::Config do
|
|
28
36
|
url: 'http://default.com',
|
29
37
|
root: '/var/www/default'
|
30
38
|
}
|
31
|
-
},
|
32
|
-
cloudfront: {
|
33
|
-
access_key: 'FooBar',
|
34
|
-
secret_key: 'SecretBaz',
|
35
|
-
distribution: 'Distro',
|
36
|
-
path_prefix: '/'
|
37
39
|
}
|
38
40
|
}
|
39
41
|
end
|
@@ -98,9 +100,26 @@ describe BranchableCDNAssets::Config do
|
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
101
|
-
describe "#
|
102
|
-
|
103
|
-
|
103
|
+
describe "#invalidator" do
|
104
|
+
|
105
|
+
it "returns instance of given invalidator class" do
|
106
|
+
expect( described_class.new( data, 'production' ).invalidator ).to be_a BranchableCDNAssets::Invalidator::Cloudfront
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns false if no invalidator given" do
|
110
|
+
subject_data = data.dup
|
111
|
+
subject_data[:environments][:production].delete(:invalidator)
|
112
|
+
|
113
|
+
expect( described_class.new( subject_data, 'production' ).invalidator ).to be false
|
114
|
+
end
|
115
|
+
|
116
|
+
it "raises error if given an unregistered invalidator" do
|
117
|
+
subject_data = data.dup
|
118
|
+
subject_data[:environments][:production][:invalidator] = { foo: 'bar' }
|
119
|
+
|
120
|
+
expect{
|
121
|
+
described_class.new(subject_data, 'production').invalidator
|
122
|
+
}.to raise_error
|
104
123
|
end
|
105
124
|
end
|
106
125
|
|
@@ -114,6 +133,27 @@ describe BranchableCDNAssets::Config do
|
|
114
133
|
end
|
115
134
|
end
|
116
135
|
|
136
|
+
describe "#file_filter" do
|
137
|
+
it "returns nil if not set" do
|
138
|
+
expect( described_class.new( data ).file_filter ).to eq nil
|
139
|
+
end
|
140
|
+
|
141
|
+
it "raises an argument error if not a proc with one argument" do
|
142
|
+
expect{
|
143
|
+
described_class.new( data.merge(file_filter: "foo") )
|
144
|
+
}.to raise_error ArgumentError
|
145
|
+
|
146
|
+
expect{
|
147
|
+
described_class.new( data.merge(file_filter: lambda { |x,y| } ) )
|
148
|
+
}.to raise_error ArgumentError
|
149
|
+
end
|
150
|
+
|
151
|
+
it "returns the given proc" do
|
152
|
+
filter_proc = lambda { |file_path| file_path }
|
153
|
+
expect( described_class.new( data.merge(file_filter: filter_proc) ).file_filter ).to eq filter_proc
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
117
157
|
describe "#env" do
|
118
158
|
context "when the current branch matches production_branch" do
|
119
159
|
before :each do
|
@@ -159,4 +199,4 @@ describe BranchableCDNAssets::Config do
|
|
159
199
|
end
|
160
200
|
end
|
161
201
|
|
162
|
-
end
|
202
|
+
end
|
@@ -30,6 +30,22 @@ describe BranchableCDNAssets::FileManager do
|
|
30
30
|
it "returns nil if asset is missing" do
|
31
31
|
expect( @manager.find('missing') ).to be_nil
|
32
32
|
end
|
33
|
+
|
34
|
+
it "returns :local if told to look local and file exists" do
|
35
|
+
expect( @manager.find('image_one', :local) ).to eq :local
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns nil if told to look local and file only on remote" do
|
39
|
+
expect( @manager.find('image_remote_one', :local) ).to be_nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns remote file if told to look remote and file exists on both" do
|
43
|
+
expect( @manager.find('image_one', :remote) ).to eq 'http://production.com/image_one'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns nil if told to look remote and file only local" do
|
47
|
+
expect( @manager.find('image_two', :remote) ).to be_nil
|
48
|
+
end
|
33
49
|
end
|
34
50
|
|
35
51
|
context "when on staging branch" do
|
@@ -54,8 +70,28 @@ describe BranchableCDNAssets::FileManager do
|
|
54
70
|
it "returns nil if asset is missing" do
|
55
71
|
expect( @manager.find('missing') ).to be_nil
|
56
72
|
end
|
73
|
+
|
74
|
+
it "returns :local if told to look local and file exists" do
|
75
|
+
expect( @manager.find('image_one', :local) ).to eq :local
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns nil if told to look local and file only on remote" do
|
79
|
+
expect( @manager.find('image_remote_one', :local) ).to be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns remote file if told to look remote and file exists on both" do
|
83
|
+
expect( @manager.find('image_one', :remote) ).to eq 'http://staging.com/staging/image_one'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns production file if told to look remote and file exists only on prod" do
|
87
|
+
expect( @manager.find('image_remote_one', :remote) ).to eq 'http://production.com/image_remote_one'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns nil if told to look remote and file only local" do
|
91
|
+
expect( @manager.find('image_two', :remote) ).to be_nil
|
92
|
+
end
|
57
93
|
end
|
58
94
|
|
59
95
|
end
|
60
96
|
|
61
|
-
end
|
97
|
+
end
|
@@ -5,22 +5,35 @@ describe BranchableCDNAssets::FileManager do
|
|
5
5
|
before :each do
|
6
6
|
@config_data = {
|
7
7
|
env: 'default',
|
8
|
-
branch: 'branch',
|
9
8
|
cdn_dir: 'cdn',
|
10
|
-
host: 'host',
|
11
|
-
root: 'root',
|
12
|
-
manage_cloudfront: true,
|
13
9
|
dir_permissions: 755,
|
14
10
|
file_permissions: 644,
|
15
11
|
rsync_flags: '-aviz',
|
16
12
|
remotes: [
|
17
13
|
BranchableCDNAssets::Config::Remote.new( 'host', 'root', 'url', 755, 644, '-aviz' )
|
18
14
|
],
|
19
|
-
|
20
|
-
|
15
|
+
environments: {
|
16
|
+
staging: {
|
17
|
+
host: 'host',
|
18
|
+
root: 'root',
|
19
|
+
url: 'http://foo.com'
|
20
|
+
},
|
21
|
+
production: {
|
22
|
+
host: 'host',
|
23
|
+
root: 'root',
|
24
|
+
url: 'http://foo.com',
|
25
|
+
invalidator: {
|
26
|
+
cloudfront: {
|
27
|
+
distribution_id: '',
|
28
|
+
access_key: '',
|
29
|
+
secret_key: '',
|
30
|
+
path_prefix: '/prefix'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
21
34
|
}
|
22
35
|
}
|
23
|
-
@config =
|
36
|
+
@config = BranchableCDNAssets::Config.new @config_data, 'master'
|
24
37
|
allow( BranchableCDNAssets::Config ).to receive(:new).and_return( @config )
|
25
38
|
|
26
39
|
@file_list = [
|
@@ -35,8 +48,9 @@ describe BranchableCDNAssets::FileManager do
|
|
35
48
|
@manifest = instance_double("BranchableCDNAssets::Manifest", files: @file_list )
|
36
49
|
allow( BranchableCDNAssets::Manifest ).to receive(:new).and_return( @manifest )
|
37
50
|
|
38
|
-
@cloudfront =
|
39
|
-
allow( BranchableCDNAssets::Cloudfront ).to receive(:new).and_return( @cloudfront )
|
51
|
+
@cloudfront = BranchableCDNAssets::Invalidator::Cloudfront.new(@config_data[:environments][:production][:invalidator][:cloudfront])
|
52
|
+
allow( BranchableCDNAssets::Invalidator::Cloudfront ).to receive(:new).and_return( @cloudfront )
|
53
|
+
allow( @cloudfront ).to receive(:invalidate_files)
|
40
54
|
|
41
55
|
@tempfile = instance_double( "Tempfile",
|
42
56
|
unlink: nil,
|
@@ -89,8 +103,10 @@ describe BranchableCDNAssets::FileManager do
|
|
89
103
|
cdn_dir: 'cdn',
|
90
104
|
host: 'host',
|
91
105
|
root: 'root',
|
92
|
-
|
93
|
-
|
106
|
+
invalidator: {
|
107
|
+
cloudfront: {
|
108
|
+
path_prefix: '/prefix'
|
109
|
+
}
|
94
110
|
}
|
95
111
|
}
|
96
112
|
@config = instance_double( "BranchableCDNAssets::Config", @config_data )
|
@@ -127,6 +143,16 @@ describe BranchableCDNAssets::FileManager do
|
|
127
143
|
expect( described_class.new(@config).list(:local) ).to match_array local_files
|
128
144
|
end
|
129
145
|
|
146
|
+
it "uses the given file_filter to filter files when :local" do
|
147
|
+
file_filter = lambda { |file_path| return !file_path.match('directory') }
|
148
|
+
@config = instance_double( "BranchableCDNAssets::Config",
|
149
|
+
@config_data.merge( file_filter: file_filter,
|
150
|
+
branch: 'master' ) )
|
151
|
+
allow( BranchableCDNAssets::Config ).to receive(:new).and_return( @config )
|
152
|
+
|
153
|
+
expect( described_class.new( @config ).list(:local) ).to match_array local_files - ['directory/dir_file']
|
154
|
+
end
|
155
|
+
|
130
156
|
it "returns both local and remote files when :all" do
|
131
157
|
expect( described_class.new(@config).list() ).to match_array remote_files + local_files
|
132
158
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BranchableCDNAssets::Invalidator::Base do
|
4
|
+
|
5
|
+
after :each do
|
6
|
+
Object.send(:remove_const, :Foo) if defined? Foo
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "::register_as" do
|
10
|
+
it "calls register with given key on BranchableCDNAssets::Invalidator" do
|
11
|
+
class Foo < BranchableCDNAssets::Invalidator::Base; end
|
12
|
+
expect( BranchableCDNAssets::Invalidator ).to receive(:register)
|
13
|
+
.with(:foo, Foo)
|
14
|
+
|
15
|
+
class Foo
|
16
|
+
register_as :foo
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "::require_keys" do
|
22
|
+
it "sets class.required_keys" do
|
23
|
+
class Foo < BranchableCDNAssets::Invalidator::Base
|
24
|
+
require_keys [:foo, :bar]
|
25
|
+
end
|
26
|
+
|
27
|
+
expect( Foo.required_keys ).to match_array [:foo, :bar]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "::set_defaults" do
|
32
|
+
it "sets class.defaults" do
|
33
|
+
class Foo < BranchableCDNAssets::Invalidator::Base
|
34
|
+
set_defaults foo: 'bar'
|
35
|
+
end
|
36
|
+
|
37
|
+
expect( Foo.defaults ).to eq foo: 'bar'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#initialize" do
|
42
|
+
it "takes a hash and converts to config struct" do
|
43
|
+
config = {
|
44
|
+
foo: 'bar',
|
45
|
+
wu: 'tang'
|
46
|
+
}
|
47
|
+
|
48
|
+
subject = described_class.new(config)
|
49
|
+
|
50
|
+
expect( subject.config.foo ).to eq 'bar'
|
51
|
+
expect( subject.config.wu ).to eq 'tang'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "uses defaults for key if key not given" do
|
55
|
+
class Foo < BranchableCDNAssets::Invalidator::Base
|
56
|
+
set_defaults foo: 'bar'
|
57
|
+
end
|
58
|
+
|
59
|
+
subject = Foo.new baz: 'bang'
|
60
|
+
expect( subject.config.foo ).to eq 'bar'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "given value even if default given" do
|
64
|
+
class Foo < BranchableCDNAssets::Invalidator::Base
|
65
|
+
set_defaults foo: 'bar'
|
66
|
+
end
|
67
|
+
|
68
|
+
subject = Foo.new foo: 'bang'
|
69
|
+
expect( subject.config.foo ).to eq 'bang'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "raises ArgumentError if missing required keys" do
|
73
|
+
class Foo < BranchableCDNAssets::Invalidator::Base
|
74
|
+
require_keys [:boom]
|
75
|
+
end
|
76
|
+
|
77
|
+
expect{
|
78
|
+
Foo.new foo: 'bar'
|
79
|
+
}.to raise_error ArgumentError
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#invalidate_files" do
|
84
|
+
it "raises a NoMethodError, it's not implemented" do
|
85
|
+
expect{
|
86
|
+
described_class.new.invalidate_files('foo')
|
87
|
+
}.to raise_error NoMethodError
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe BranchableCDNAssets::Cloudfront do
|
3
|
+
describe BranchableCDNAssets::Invalidator::Cloudfront do
|
4
4
|
|
5
|
-
let(:
|
5
|
+
let(:config) do
|
6
6
|
{
|
7
7
|
distribution_id: 'dist_id',
|
8
8
|
access_key: 'access_key',
|
@@ -13,19 +13,22 @@ describe BranchableCDNAssets::Cloudfront do
|
|
13
13
|
describe "#initialize" do
|
14
14
|
|
15
15
|
before :each do
|
16
|
-
@subject = described_class.new(
|
16
|
+
@subject = described_class.new(config)
|
17
17
|
end
|
18
18
|
|
19
19
|
it "sets #distribution_id" do
|
20
|
-
expect( @subject.distribution_id ).to eq 'dist_id'
|
20
|
+
expect( @subject.config.distribution_id ).to eq 'dist_id'
|
21
21
|
end
|
22
22
|
it "sets #access_key" do
|
23
|
-
expect( @subject.access_key ).to eq 'access_key'
|
23
|
+
expect( @subject.config.access_key ).to eq 'access_key'
|
24
24
|
end
|
25
25
|
it "sets #secret_key" do
|
26
|
-
expect( @subject.secret_key ).to eq 'secret_key'
|
26
|
+
expect( @subject.config.secret_key ).to eq 'secret_key'
|
27
27
|
end
|
28
28
|
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#cdn" do
|
29
32
|
it "sets #cdn with a Fog instance" do
|
30
33
|
fog = double("Fog::CDN")
|
31
34
|
expect( Fog::CDN ).to receive(:new).with(
|
@@ -33,9 +36,8 @@ describe BranchableCDNAssets::Cloudfront do
|
|
33
36
|
aws_access_key_id: 'access_key',
|
34
37
|
aws_secret_access_key: 'secret_key'
|
35
38
|
).and_return(fog)
|
36
|
-
expect( described_class.new(
|
39
|
+
expect( described_class.new(config).cdn ).to eq fog
|
37
40
|
end
|
38
|
-
|
39
41
|
end
|
40
42
|
|
41
43
|
describe "#invalidate_files" do
|
@@ -51,7 +53,7 @@ describe BranchableCDNAssets::Cloudfront do
|
|
51
53
|
aws_access_key_id: 'access_key',
|
52
54
|
aws_secret_access_key: 'secret_key'
|
53
55
|
).and_return(@fog)
|
54
|
-
@subject = described_class.new(
|
56
|
+
@subject = described_class.new(config)
|
55
57
|
end
|
56
58
|
|
57
59
|
it "calls cloudfront to invalidate given files" do
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BranchableCDNAssets::Invalidator do
|
4
|
+
|
5
|
+
def clean_invalidators
|
6
|
+
described_class.instance_variable_set :@_invalidators, nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def clean_foo_class
|
10
|
+
Object.send(:remove_const, :Foo) if defined? Foo
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
clean_invalidators
|
15
|
+
end
|
16
|
+
|
17
|
+
after :each do
|
18
|
+
clean_foo_class
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "::invalidators" do
|
22
|
+
it "returns empty hash if no invalidators are registered" do
|
23
|
+
expect( described_class.invalidators ).to eq({})
|
24
|
+
end
|
25
|
+
it "returns hash of registered invalidators" do
|
26
|
+
class Foo < BranchableCDNAssets::Invalidator::Base
|
27
|
+
register_as :foo
|
28
|
+
end
|
29
|
+
expect( described_class.invalidators ).to eq({foo: Foo})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "::register" do
|
34
|
+
it "adds invalidator to invalidators hash" do
|
35
|
+
class Foo; end
|
36
|
+
described_class.register :foo, Foo
|
37
|
+
expect( described_class.invalidators ).to eq({foo: Foo})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "::find" do
|
42
|
+
it "returns invalidator class if one is registered" do
|
43
|
+
class Foo; end
|
44
|
+
described_class.register :foo, Foo
|
45
|
+
|
46
|
+
expect( described_class.find(:foo) ).to eq Foo
|
47
|
+
end
|
48
|
+
it "returns false if invalidator isn't registered" do
|
49
|
+
expect( described_class.find(:bar) ).to eq false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -108,6 +108,7 @@ describe BranchableCDNAssets::Manifest do
|
|
108
108
|
manifest = BranchableCDNAssets::Manifest.new('foo')
|
109
109
|
|
110
110
|
expect( File ).not_to receive(:open)
|
111
|
+
allow( File ).to receive(:exist?).with('foo').and_return(true)
|
111
112
|
expect( File ).to receive(:delete).with('foo')
|
112
113
|
|
113
114
|
manifest.update_source_file!
|
@@ -135,4 +136,4 @@ describe BranchableCDNAssets::Manifest do
|
|
135
136
|
end
|
136
137
|
|
137
138
|
|
138
|
-
end
|
139
|
+
end
|
metadata
CHANGED
@@ -1,86 +1,86 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: branchable_cdn_assets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Sloan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '10.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '10.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: colorize
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0.6'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: asgit
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0.1'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: here_or_there
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0.1'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: fog
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.18'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.18'
|
83
|
-
description:
|
83
|
+
description: " Helpers for syncing and finding assets accross multiple remotes "
|
84
84
|
email: marketing-dev@mailchimp.com
|
85
85
|
executables: []
|
86
86
|
extensions: []
|
@@ -88,12 +88,16 @@ extra_rdoc_files: []
|
|
88
88
|
files:
|
89
89
|
- lib/branchable_cdn_assets.rb
|
90
90
|
- lib/branchable_cdn_assets/check_before.rb
|
91
|
-
- lib/branchable_cdn_assets/cloudfront.rb
|
92
91
|
- lib/branchable_cdn_assets/config.rb
|
93
92
|
- lib/branchable_cdn_assets/config/environment_attribute_reader.rb
|
94
93
|
- lib/branchable_cdn_assets/file_manager.rb
|
95
94
|
- lib/branchable_cdn_assets/file_manager/checks.rb
|
96
95
|
- lib/branchable_cdn_assets/file_manager/permissions.rb
|
96
|
+
- lib/branchable_cdn_assets/invalidator.rb
|
97
|
+
- lib/branchable_cdn_assets/invalidator/akamai_ccu.rb
|
98
|
+
- lib/branchable_cdn_assets/invalidator/akamai_ccu/http.rb
|
99
|
+
- lib/branchable_cdn_assets/invalidator/base.rb
|
100
|
+
- lib/branchable_cdn_assets/invalidator/cloudfront.rb
|
97
101
|
- lib/branchable_cdn_assets/manifest.rb
|
98
102
|
- lib/branchable_cdn_assets/rake_tasks.rb
|
99
103
|
- lib/branchable_cdn_assets/shell.rb
|
@@ -103,10 +107,12 @@ files:
|
|
103
107
|
- spec/lib/branchable_cdn_assets/config_spec.rb
|
104
108
|
- spec/lib/branchable_cdn_assets/file_manager/find_spec.rb
|
105
109
|
- spec/lib/branchable_cdn_assets/file_manager_spec.rb
|
110
|
+
- spec/lib/branchable_cdn_assets/invalidator/base_spec.rb
|
111
|
+
- spec/lib/branchable_cdn_assets/invalidator/cloudfront_spec.rb
|
112
|
+
- spec/lib/branchable_cdn_assets/invalidator_spec.rb
|
106
113
|
- spec/lib/branchable_cdn_assets/manifest_spec.rb
|
107
114
|
- spec/lib/branchable_cdn_assets/rake_tasks_spec.rb
|
108
115
|
- spec/lib/branchable_cdn_assets_spec.rb
|
109
|
-
- spec/lib/cloudfront_spec.rb
|
110
116
|
- spec/spec_helper.rb
|
111
117
|
- spec/support/given.rb
|
112
118
|
- spec/support/hash.rb
|
@@ -120,17 +126,17 @@ require_paths:
|
|
120
126
|
- lib
|
121
127
|
required_ruby_version: !ruby/object:Gem::Requirement
|
122
128
|
requirements:
|
123
|
-
- -
|
129
|
+
- - ">="
|
124
130
|
- !ruby/object:Gem::Version
|
125
131
|
version: 1.9.3
|
126
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
133
|
requirements:
|
128
|
-
- -
|
134
|
+
- - ">="
|
129
135
|
- !ruby/object:Gem::Version
|
130
136
|
version: '0'
|
131
137
|
requirements: []
|
132
138
|
rubyforge_project:
|
133
|
-
rubygems_version: 2.4.5
|
139
|
+
rubygems_version: 2.4.5.1
|
134
140
|
signing_key:
|
135
141
|
specification_version: 4
|
136
142
|
summary: Helpers for syncing and finding assets accross multiple remotes
|
@@ -140,10 +146,12 @@ test_files:
|
|
140
146
|
- spec/lib/branchable_cdn_assets/config_spec.rb
|
141
147
|
- spec/lib/branchable_cdn_assets/file_manager/find_spec.rb
|
142
148
|
- spec/lib/branchable_cdn_assets/file_manager_spec.rb
|
149
|
+
- spec/lib/branchable_cdn_assets/invalidator/base_spec.rb
|
150
|
+
- spec/lib/branchable_cdn_assets/invalidator/cloudfront_spec.rb
|
151
|
+
- spec/lib/branchable_cdn_assets/invalidator_spec.rb
|
143
152
|
- spec/lib/branchable_cdn_assets/manifest_spec.rb
|
144
153
|
- spec/lib/branchable_cdn_assets/rake_tasks_spec.rb
|
145
154
|
- spec/lib/branchable_cdn_assets_spec.rb
|
146
|
-
- spec/lib/cloudfront_spec.rb
|
147
155
|
- spec/spec_helper.rb
|
148
156
|
- spec/support/given.rb
|
149
157
|
- spec/support/hash.rb
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module BranchableCDNAssets
|
2
|
-
class Cloudfront
|
3
|
-
|
4
|
-
attr_reader :access_key, :secret_key, :distribution_id,
|
5
|
-
:cdn
|
6
|
-
|
7
|
-
# handles communication with cloudfront
|
8
|
-
def initialize keys
|
9
|
-
@distribution_id = keys.fetch :distribution_id
|
10
|
-
@access_key = keys.fetch :access_key
|
11
|
-
@secret_key = keys.fetch :secret_key
|
12
|
-
|
13
|
-
@cdn = ::Fog::CDN.new provider: 'AWS',
|
14
|
-
aws_access_key_id: access_key,
|
15
|
-
aws_secret_access_key: secret_key
|
16
|
-
end
|
17
|
-
|
18
|
-
# invalidate a batch of files on fog
|
19
|
-
# @param files [Array]
|
20
|
-
def invalidate_files files
|
21
|
-
resp = cdn.post_invalidation( distribution_id, Array(files) )
|
22
|
-
resp.body["InvalidationBatch"]["Path"].each do |file|
|
23
|
-
puts "Posted an invalidation for #{file}".colorize( :green )
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|