fastly-deploy 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee84ea69e9948befc15426b5f396918203466efe
4
+ data.tar.gz: 084e583ee631b036b43e04cca10f17ef55cbd3fa
5
+ SHA512:
6
+ metadata.gz: 0ed50d1aea45387acf64757076d8231b8aeb764dfb2c60842aff5f9164a454625cf91fbe869f03ad791ab9c133943a3560ff1053d0424e668ec361cde76623db
7
+ data.tar.gz: 5af1a824f78b66e81f59c386dc10ada73b4a6da527333e97363e0dd048461f9db8fa49afa070dbd0e08ddcce7e4c6a140a291a2596bc4a1cabf232eea759aeab
data/bin/deploy.rb ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/methods'
4
+ require_relative '../lib/detect_includes'
5
+ require 'optparse'
6
+
7
+ def deploy(argv)
8
+ options = {}
9
+ optparse = OptionParser.new do |opts|
10
+ opts.banner = "Usage: deploy.rb [options]"
11
+ opts.on("-k", "--api-key API_KEY", "Fastly API Key") do |api_key|
12
+ options[:api_key] = api_key
13
+ end
14
+ opts.on("-s", "--service-id SERVICE_ID", "Service ID") do |service_id|
15
+ options[:service_id] = service_id
16
+ end
17
+ opts.on("-v", "--vcl-path FILE", "VCL Path") do |vcl_path|
18
+ options[:vcl_path] = vcl_path
19
+ end
20
+ opts.on("-i", "--vcl-includes INCLUDES_DIR", "Includes Directory") do |includes_dir|
21
+ options[:includes_dir] = includes_dir
22
+ end
23
+ options[:purge_all] = false
24
+ opts.on("-p", "--purge-all", "Purge All") do |purge_all|
25
+ options[:purge_all] = true
26
+ end
27
+ opts.on('-h', '--help', 'Display this screen') do
28
+ puts opts
29
+ exit
30
+ end
31
+ end
32
+ optparse.parse! argv
33
+
34
+ if options[:api_key].nil? ||
35
+ options[:service_id].nil? ||
36
+ options[:vcl_path].nil? then
37
+ puts optparse
38
+ exit 1
39
+ end
40
+
41
+ includes = get_includes options[:vcl_path], options[:includes_dir]
42
+ puts includes
43
+
44
+ deploy_vcl options[:api_key],
45
+ options[:service_id],
46
+ options[:vcl_path],
47
+ options[:purge_all],
48
+ includes
49
+ return options[:api_key]
50
+ end
51
+
52
+ # This is only run when run as a script. The FILE bit stops it
53
+ # from being run during the tests
54
+ if __FILE__ == $0
55
+ deploy ARGV
56
+ end
@@ -0,0 +1,23 @@
1
+ def get_includes(main_vcl_path, includes_dir)
2
+ includes_found = []
3
+ get_includes_for_vcl main_vcl_path, includes_dir, includes_found
4
+ return includes_found
5
+ end
6
+
7
+ def get_includes_for_vcl(vcl_path, includes_dir, includes_found)
8
+ direct_includes = get_includes_directly_in_vcl vcl_path, includes_dir
9
+ direct_includes_not_already_found = direct_includes - includes_found
10
+
11
+ direct_includes_not_already_found.map do |include_vcl|
12
+ includes_found.push include_vcl
13
+ get_includes_for_vcl include_vcl, includes_dir, includes_found
14
+ end
15
+ end
16
+
17
+ def get_includes_directly_in_vcl(vcl_path, includes_dir)
18
+ # Using '$' for line ending is os dependent and fails w/windows line endings on linux
19
+ include_pattern = /^include "(.*)";?[\r\n]+/
20
+ return File.readlines(vcl_path).select { |line| include_pattern.match(line) }
21
+ .map{ |line| include_pattern.match(line)[1] }
22
+ .map{ |vcl_file_name| File.join(includes_dir, vcl_file_name + ".vcl")}
23
+ end
data/lib/methods.rb ADDED
@@ -0,0 +1,129 @@
1
+ require 'fastly'
2
+ require 'net/http'
3
+ require 'colorize'
4
+
5
+ def deploy_vcl(api_key, service_id, vcl_path, purge_all, include_files)
6
+
7
+ login_opts = { :api_key => api_key }
8
+ fastly = Fastly.new(login_opts)
9
+ service = fastly.get_service(service_id)
10
+
11
+ active_version = service.versions.find{|ver| ver.active?}
12
+ puts "Active Version: #{active_version.number}"
13
+ domain = fastly.list_domains(:service_id => service.id,
14
+ :version => active_version.number).first
15
+ puts "Domain Name: #{domain.name}"
16
+
17
+ new_version = active_version.clone
18
+ puts "New Version: #{new_version.number}"
19
+
20
+ fastly.list_vcls(:service_id => service.id,
21
+ :version => new_version.number)
22
+ .each { |vcl| vcl.delete! }
23
+
24
+ can_verify_deployment = upload_main_vcl new_version, vcl_path, service_id
25
+
26
+ if include_files != nil
27
+ include_files.each do | include_file |
28
+ upload_include_vcl new_version, include_file, service_id
29
+ end
30
+ end
31
+
32
+ puts "Validating..."
33
+
34
+ validate(new_version)
35
+
36
+ puts "Activating..."
37
+ new_version.activate!
38
+
39
+ if can_verify_deployment then
40
+ print "Waiting for changes to take effect."
41
+ attempts = 1
42
+ deployed_vcl_version_number = 0
43
+
44
+ while attempts < 150 && deployed_vcl_version_number != new_version.number.to_s do
45
+ sleep 2
46
+ url = URI.parse("http://#{domain.name}.global.prod.fastly.net/vcl_version")
47
+ req = Net::HTTP::Get.new(url.to_s)
48
+ res = Net::HTTP.start(url.host, url.port) {|http|
49
+ http.request(req)
50
+ }
51
+ deployed_vcl_version_number = res.body
52
+ print "."
53
+ attempts += 1
54
+ end
55
+ puts "done."
56
+
57
+ if deployed_vcl_version_number != new_version.number.to_s then
58
+ STDERR.puts "Verify failed. /vcl_version returned [#{deployed_vcl_version_number}].".red
59
+ exit 1
60
+ end
61
+ end
62
+
63
+ if purge_all then
64
+ puts "Purging all..."
65
+ service.purge_all
66
+ end
67
+ puts "Deployment complete.".green
68
+ end
69
+
70
+ def upload_main_vcl(version, vcl_path, service_id)
71
+ vcl_name = File.basename(vcl_path, ".vcl")
72
+ can_verify_deployment = upload_vcl version, vcl_path, vcl_name, service_id
73
+ version.vcl(vcl_name).set_main!
74
+ return can_verify_deployment
75
+ end
76
+
77
+ def upload_include_vcl(version, vcl_path, service_id)
78
+ vcl_name = File.basename(vcl_path, ".vcl")
79
+ upload_vcl version, vcl_path, vcl_name, service_id
80
+ end
81
+
82
+ def upload_vcl(version, vcl_path, name, service_id)
83
+ vcl_contents_from_file = File.read(vcl_path)
84
+ vcl_contents_with_service_id_injection = inject_service_id vcl_contents_from_file, service_id
85
+ vcl_contents_with_deploy_injection = inject_deploy_verify_code(vcl_contents_with_service_id_injection, version.number)
86
+
87
+ puts "Uploading #{name}"
88
+ version.upload_vcl name, vcl_contents_with_deploy_injection
89
+
90
+ return vcl_contents_with_deploy_injection != vcl_contents_with_service_id_injection
91
+ end
92
+
93
+ def inject_deploy_verify_code(vcl, version_num)
94
+ deploy_recv_vcl = <<-END
95
+ # --------- DEPLOY VERIFY CHECK START ---------
96
+ if (req.url == "/vcl_version") {
97
+ error 902;
98
+ }
99
+ # --------- DEPLOY VERIFY CHECK END ---------
100
+ END
101
+
102
+ deploy_error_vcl = <<-END
103
+ # --------- DEPLOY VERIFY CHECK START ---------
104
+ if (obj.status == 902) {
105
+ set obj.status = 200;
106
+ set obj.response = "OK";
107
+ synthetic "#{version_num}";
108
+ return(deliver);
109
+ }
110
+ # --------- DEPLOY VERIFY CHECK END ---------
111
+ END
112
+
113
+ vcl.gsub(/#7D_DEPLOY recv/, deploy_recv_vcl)
114
+ .gsub(/#7D_DEPLOY error/, deploy_error_vcl)
115
+ end
116
+
117
+ def inject_service_id(vcl_contents, service_id)
118
+ vcl_contents.gsub(/#7D_FASTLY_SERVICE_ID/, service_id)
119
+ end
120
+
121
+ def validate(version)
122
+ path = version.class.get_path(version.service_id, version.number)
123
+ response = version.fetcher.client.get("#{path}/validate")
124
+ status = response["status"]
125
+ if status!= "ok"
126
+ raise response["msg"]
127
+ end
128
+ end
129
+
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastly-deploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - 7digital
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Automated deploys for Fastly vcl configs
14
+ email: developers@7digital.com
15
+ executables:
16
+ - deploy.rb
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/deploy.rb
21
+ - lib/detect_includes.rb
22
+ - lib/methods.rb
23
+ homepage: https://github.com/7digital/fastly-deploy
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.5.0
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Automated deploys for Fastly vcl configs
47
+ test_files: []