branchable_cdn_assets 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|