fastly 1.1.3 → 1.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ef98fd25ca8d8bc9e1b8a59c3f9871bf55297c3
4
- data.tar.gz: ca25acfcc5fc2530bb4fe0b3684444de0cc2060b
3
+ metadata.gz: 0270d26d5f2da61fe372839853d8710120d239bb
4
+ data.tar.gz: a5354c14c11c76a1a0ec5e4a129f7a90a0cd6fe2
5
5
  SHA512:
6
- metadata.gz: 342af0046a3402e92d87d2c0dfabf93ffba77674ffe817e21f11ff66f65c0ec14f8b3f02278359865b3898394fe2c8016f6b12297adc1c64d8da8a1d10b2821a
7
- data.tar.gz: b9a5b946c3525e4bfe6f6ccf7a186136a5349c5bd9f87d633f3309873a850061397a8b19f3525dcadec20b9f0cf4d1738dd48a9d38860fc578b3feb92e10d3a1
6
+ metadata.gz: 85ec2dddf754bdc0f3f8f574877641195bd6c19ede0782a8008ca785a7530b4a4bf56ca2d10aa3449b21b294f30183dbfcbbd3fbc7c858bfd4bfc2cf27356d65
7
+ data.tar.gz: d2d3c5ede4170d3592266be5865f6165e75c6ba71204999859fa53107a9f21ac8b820622143db28320f052f411d1e5e17c0c1426ca9f214ce4a5428c9ed1c39f
data/HISTORY.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # HEAD
2
2
 
3
+ # 2014-09-29 v1.1.4
4
+ * Require API for purge by key
3
5
 
4
- # 2014-07-25 v1.1.3
6
+ #### 2014-07-25 v1.1.3
5
7
  * Add test:unit rake task
6
8
  * Add Rubocop and some rubocop cleanup
7
9
  * Clarify gem name in documentation
8
10
  * Fix a bug in the `Fastly.get_options` method
9
11
  * Add `bin/fastly_create_domain` script to easily create domain
10
12
 
11
- #### 2014-06-12 v1.1.2
13
+ 2014-06-12 v1.1.2
12
14
  * Replace `String#underscore` with `Fastly::Util.class_to_path` method.
13
15
  * Add first true unit test
14
16
  * Add `test_helper.rb`
@@ -1,10 +1,10 @@
1
1
  #!/bin/env ruby
2
2
 
3
3
  ##
4
- # fastly_upload_vcl - upload raw VCL files to Fastly
4
+ # fastly_create_domain - ruby script to quickly create a fastly domain
5
5
  #
6
6
  # Author:: Fastly Inc <support@fastly.com>
7
- # Copyright:: Copyright (c) 2011 Fastly Inc
7
+ # Copyright:: Copyright (c) 2014 Fastly Inc
8
8
  # License:: Distributes under the same terms as Ruby
9
9
  #
10
10
  # = USAGE
@@ -19,7 +19,7 @@
19
19
  #
20
20
  # Alternatively you can pass in any of those options on the command line
21
21
  #
22
- # fastly_create_domain --api_key=<key> <service id> <domain name>
22
+ # $ ruby fastly_create_domain --api_key=<key> <service id> <domain name>
23
23
 
24
24
  require 'rubygems'
25
25
  require 'fastly'
@@ -11,51 +11,54 @@ class Fastly
11
11
  @keys.push(key)
12
12
  end
13
13
  self.fetcher = fetcher
14
- end
15
-
16
- # Save this object
17
- def save!
18
- fetcher.update(self.class, self)
19
- end
20
-
21
- # Delete this object
22
- def delete!
23
- fetcher.delete(self.class, self)
24
- end
25
-
26
- ##
27
- # :nodoc:
28
- def as_hash
29
- ret = {}
30
- @keys.each do |key|
31
- ret[key] = self.send("#{key}") unless key =~ /^_/;
32
- end
33
- ret
34
- end
35
-
36
- def self.path
37
- Util.class_to_path(self)
38
- end
39
-
40
- def self.get_path(id)
41
- "/#{path}/#{id}"
42
- end
43
-
44
- def self.post_path(opts={})
45
- "/#{path}"
46
- end
47
-
48
- def self.list_path(opts={})
49
- post_path(opts)
50
- end
51
-
52
- def self.put_path(obj)
53
- get_path(obj.id)
54
- end
55
-
56
- def self.delete_path(obj)
57
- put_path(obj)
58
- end
14
+ end
59
15
 
16
+ # Save this object
17
+ def save!
18
+ fetcher.update(self.class, self)
19
+ end
20
+
21
+ # Delete this object
22
+ def delete!
23
+ fetcher.delete(self.class, self)
24
+ end
25
+
26
+ ##
27
+ # :nodoc:
28
+ def as_hash
29
+ ret = {}
30
+ @keys.each do |key|
31
+ ret[key] = self.send("#{key}") unless key =~ /^_/;
32
+ end
33
+ ret
34
+ end
35
+
36
+ def require_api_key!
37
+ fetcher.client.require_key!
38
+ end
39
+
40
+ def self.path
41
+ Util.class_to_path(self)
42
+ end
43
+
44
+ def self.get_path(id)
45
+ "/#{path}/#{id}"
46
+ end
47
+
48
+ def self.post_path(opts={})
49
+ "/#{path}"
50
+ end
51
+
52
+ def self.list_path(opts={})
53
+ post_path(opts)
54
+ end
55
+
56
+ def self.put_path(obj)
57
+ get_path(obj.id)
58
+ end
59
+
60
+ def self.delete_path(obj)
61
+ put_path(obj)
62
+ end
60
63
  end
61
64
  end
@@ -6,168 +6,183 @@ require 'pp'
6
6
  require 'uri'
7
7
 
8
8
  class Fastly
9
- # The UserAgent to communicate with the API
10
- class Client #:nodoc: all
11
- begin
12
- require 'curb-fu'
13
- CURB_FU=true
14
- rescue LoadError
15
- CURB_FU=false
16
- end
9
+ # The UserAgent to communicate with the API
10
+ class Client #:nodoc: all
11
+ begin
12
+ require 'curb-fu'
13
+ CURB_FU=true
14
+ rescue LoadError
15
+ CURB_FU=false
16
+ end
17
17
 
18
- attr_accessor :http, :api_key, :user, :password, :cookie, :customer
19
-
20
- def initialize(opts)
21
- [:api_key, :user, :password].each do |key|
22
- self.send("#{key}=", opts[key]) if opts.has_key?(key)
23
- end
24
- base = opts[:base_url] || "https://api.fastly.com"
25
- customer = opts[:customer]
26
- uri = URI.parse(base)
27
- scheme = uri.scheme
28
- host = uri.host
29
- curb = opts.has_key?(:use_curb) ? !!opts[:use_curb] && CURB_FU : CURB_FU
30
- port = opts.has_key?(:base_port) ? opts[:base_port] : (scheme == "https") ? 443 : 80
31
- self.http = curb ? Fastly::Client::Curl.new(host, port) : Net::HTTP.new(host, port)
32
- self.http.use_ssl = (scheme == "https")
33
- return self unless fully_authed?
34
-
35
- # If we're fully authed (i.e username and password ) then we need to log in
36
- resp = self.http.post('/login', make_params(:user => user, :password => password))
37
- raise Fastly::Unauthorized unless resp.success?
38
- self.cookie = resp['set-cookie']
39
- content = JSON.parse(resp.body)
40
- #return self, content['user'], content['content']
41
- self
42
- end
18
+ attr_accessor :http, :api_key, :user, :password, :cookie, :customer
19
+
20
+ def initialize(opts)
21
+ [:api_key, :user, :password].each do |key|
22
+ self.send("#{key}=", opts[key]) if opts.has_key?(key)
23
+ end
24
+ base = opts[:base_url] || "https://api.fastly.com"
25
+ uri = URI.parse(base)
26
+ scheme = uri.scheme
27
+ host = uri.host
28
+ curb = opts.has_key?(:use_curb) ? !!opts[:use_curb] && CURB_FU : CURB_FU
29
+ port = opts.has_key?(:base_port) ? opts[:base_port] : (scheme == "https") ? 443 : 80
30
+ self.http = curb ? Fastly::Client::Curl.new(host, port) : Net::HTTP.new(host, port)
31
+ self.http.use_ssl = (scheme == "https")
32
+ return self unless fully_authed?
33
+
34
+ # If we're fully authed (i.e username and password ) then we need to log in
35
+ resp = self.http.post('/login', make_params(:user => user, :password => password))
36
+ raise Fastly::Unauthorized unless resp.success?
37
+ self.cookie = resp['set-cookie']
38
+ end
43
39
 
40
+ def require_key!
41
+ raise Fastly::AuthRequired.new("This request requires an API key") if api_key.nil?
44
42
 
45
- def authed?
46
- !api_key.nil? || fully_authed?
47
- end
43
+ @require_key = true
44
+ end
48
45
 
49
- # Some methods require full username and password rather than just auth token
50
- def fully_authed?
51
- !(user.nil? || password.nil?)
52
- end
46
+ def require_key?
47
+ !!@require_key
48
+ end
53
49
 
54
- def set_customer(id)
50
+ def authed?
51
+ !api_key.nil? || fully_authed?
52
+ end
55
53
 
56
- end
54
+ # Some methods require full username and password rather than just auth token
55
+ def fully_authed?
56
+ !(user.nil? || password.nil?)
57
+ end
57
58
 
58
- def get(path, params={})
59
- path += "?"+make_params(params) unless params.empty?
60
- resp = self.http.get(path, headers)
61
- return nil if 404 == resp.status
62
- raise Fastly::Error, resp.message unless resp.success?
63
- JSON.parse(resp.body)
64
- end
59
+ def set_customer(id)
65
60
 
66
- def get_stats(path, params={})
67
- content = get(path, params)
68
- raise Fastly::Error, content["message"] unless content["status"] == 'success'
69
- content["data"]
70
- end
61
+ end
71
62
 
72
- def post(path, params={})
73
- post_and_put(:post, path, params)
74
- end
63
+ def get(path, params={})
64
+ path += "?"+make_params(params) unless params.empty?
65
+ resp = self.http.get(path, headers)
66
+ return nil if 404 == resp.status
67
+ raise Fastly::Error, resp.message unless resp.success?
68
+ JSON.parse(resp.body)
69
+ end
75
70
 
76
- def put(path, params={})
77
- post_and_put(:put, path, params)
78
- end
71
+ def get_stats(path, params={})
72
+ content = get(path, params)
73
+ raise Fastly::Error, content["message"] unless content["status"] == 'success'
74
+ content["data"]
75
+ end
79
76
 
80
- def delete(path)
81
- resp = self.http.delete(path, headers)
82
- return resp.success?
83
- end
77
+ def post(path, params={})
78
+ post_and_put(:post, path, params)
79
+ end
84
80
 
85
- private
81
+ def put(path, params={})
82
+ post_and_put(:put, path, params)
83
+ end
86
84
 
87
- def post_and_put(method, path, params={})
88
- query = make_params(params)
89
- resp = self.http.send(method, path, query, headers.merge( 'Content-Type' => "application/x-www-form-urlencoded"))
90
- raise Fastly::Error, resp.message unless resp.success?
91
- JSON.parse(resp.body)
92
- end
85
+ def delete(path)
86
+ resp = self.http.delete(path, headers)
87
+ return resp.success?
88
+ end
93
89
 
94
- def headers
95
- headers = fully_authed? ? { 'Cookie' => cookie } : { 'X-Fastly-Key' => api_key }
96
- headers.merge( 'Fastly-Explicit-Customer' => customer ) if customer
97
- headers.merge( 'Content-Accept' => 'application/json')
98
- end
90
+ private
99
91
 
100
- def make_params(params)
101
- params.map { |key,val|
102
- next if val.nil?
103
- unless val.is_a?(Hash)
104
- "#{CGI.escape(key.to_s)}=#{CGI.escape(val.to_s)}"
92
+ def post_and_put(method, path, params={})
93
+ query = make_params(params)
94
+ resp = self.http.send(method, path, query, headers.merge( 'Content-Type' => "application/x-www-form-urlencoded"))
95
+ raise Fastly::Error, resp.message unless resp.success?
96
+ JSON.parse(resp.body)
97
+ end
98
+
99
+ def headers
100
+ headers = if require_key?
101
+ api_key_header
105
102
  else
106
- val.map { |sub_key, sub_val|
107
- new_key = "#{key}[#{sub_key}]"
108
- "#{CGI.escape(new_key)}=#{CGI.escape(sub_val.to_s)}"
109
- }
103
+ fully_authed? ? { 'Cookie' => cookie } : api_key_header
110
104
  end
111
- }.flatten.delete_if { |v| v.nil? }.join("&")
105
+ headers.merge!('Fastly-Explicit-Customer' => customer) if customer
106
+ headers.merge!('Content-Accept' => 'application/json')
107
+ ensure
108
+ @require_key = nil
109
+ end
110
+
111
+ def api_key_header
112
+ { 'X-Fastly-Key' => api_key }
113
+ end
114
+
115
+ def make_params(params)
116
+ params.map { |key,val|
117
+ next if val.nil?
118
+ unless val.is_a?(Hash)
119
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(val.to_s)}"
120
+ else
121
+ val.map { |sub_key, sub_val|
122
+ new_key = "#{key}[#{sub_key}]"
123
+ "#{CGI.escape(new_key)}=#{CGI.escape(sub_val.to_s)}"
124
+ }
112
125
  end
126
+ }.flatten.delete_if { |v| v.nil? }.join("&")
127
+ end
113
128
 
114
- # :nodoc: all
115
- class Curl
116
- attr_accessor :host, :port, :protocol
129
+ # :nodoc: all
130
+ class Curl
131
+ attr_accessor :host, :port, :protocol
117
132
 
118
- def initialize(host, port=443)
119
- self.host = host
120
- self.port = port
121
- self.protocol = 'https'
122
- end
133
+ def initialize(host, port=443)
134
+ self.host = host
135
+ self.port = port
136
+ self.protocol = 'https'
137
+ end
123
138
 
124
- def get(path, headers={})
125
- CurbFu.get({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
126
- end
139
+ def get(path, headers={})
140
+ CurbFu.get({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
141
+ end
127
142
 
128
- def post(path, params, headers={})
129
- CurbFu.post({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol }, params)
130
- end
143
+ def post(path, params, headers={})
144
+ CurbFu.post({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol }, params)
145
+ end
131
146
 
132
- def put(path, params, headers={})
133
- CurbFu.put({ :host => host, :port => port, :path => path, :headers => headers, :params => params, :protocol => protocol }, params)
134
- end
147
+ def put(path, params, headers={})
148
+ CurbFu.put({ :host => host, :port => port, :path => path, :headers => headers, :params => params, :protocol => protocol }, params)
149
+ end
135
150
 
136
- def delete(path, headers={})
137
- CurbFu.delete({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
138
- end
151
+ def delete(path, headers={})
152
+ CurbFu.delete({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
153
+ end
139
154
 
140
- def use_ssl=(ssl)
141
- self.protocol = ssl ? 'https' : 'http'
142
- end
143
- end
155
+ def use_ssl=(ssl)
156
+ self.protocol = ssl ? 'https' : 'http'
157
+ end
144
158
  end
159
+ end
145
160
  end
146
161
 
147
162
  # :nodoc: all
148
163
  class Net::HTTPResponse
149
- def success?
150
- return Net::HTTPSuccess === self
151
- end
164
+ def success?
165
+ return Net::HTTPSuccess === self
166
+ end
152
167
 
153
- def status
154
- return self.code.to_i
155
- end
168
+ def status
169
+ return self.code.to_i
170
+ end
156
171
  end
157
172
 
158
173
 
159
174
 
160
175
  # :nodoc: all
161
176
  class CurbFu::Response::Base
162
- def get_fields(key)
163
- if ( match = @headers.find{|k,v| k.downcase == key.downcase} )
164
- [match.last].flatten
165
- else
166
- []
167
- end
177
+ def get_fields(key)
178
+ if ( match = @headers.find{|k,v| k.downcase == key.downcase} )
179
+ [match.last].flatten
180
+ else
181
+ []
168
182
  end
183
+ end
169
184
 
170
- def [](key)
171
- get_fields(key).last
172
- end
185
+ def [](key)
186
+ get_fields(key).last
187
+ end
173
188
  end
@@ -1,4 +1,4 @@
1
1
  class Fastly
2
2
  # The current version of the library
3
- VERSION = "1.1.3"
3
+ VERSION = "1.1.4"
4
4
  end
@@ -59,13 +59,14 @@ class Fastly
59
59
 
60
60
  # Purge all assets from this service.
61
61
  def purge_all
62
- res = fetcher.client.post(Fastly::Service.get_path(self.id)+"/purge_all")
62
+ fetcher.client.post(Fastly::Service.get_path(self.id)+"/purge_all")
63
63
  end
64
64
 
65
-
66
65
  # Purge anything with the specific key from the given service.
67
66
  def purge_by_key(key)
68
- res = fetcher.client.post(Fastly::Service.get_path(self.id)+"/purge/#{key}")
67
+ require_api_key!
68
+
69
+ fetcher.client.post(Fastly::Service.get_path(self.id)+"/purge/#{key}")
69
70
  end
70
71
 
71
72
  # Set all the versions that this service has had.
@@ -26,7 +26,6 @@ class ApiKeyTest < Fastly::TestCase
26
26
  assert_equal @opts[:customer], customer['name']
27
27
  end
28
28
 
29
-
30
29
  def test_current_user_and_customer
31
30
  current_user = current_customer = nil
32
31
  assert_raise(Fastly::FullAuthRequired) {
@@ -39,7 +38,6 @@ class ApiKeyTest < Fastly::TestCase
39
38
  assert_equal @opts[:customer], customer.name
40
39
  end
41
40
 
42
-
43
41
  def test_purging
44
42
  #assert @fastly.purge('foo')
45
43
  # TODO Won't work until we get fixtures in Heavenly
@@ -0,0 +1,28 @@
1
+ require 'helper'
2
+
3
+ class MissingApiKeyTest < Fastly::TestCase
4
+ include CommonTests
5
+
6
+ def setup
7
+ # missing API key
8
+ @opts = login_opts(:full)
9
+ begin
10
+ @client = Fastly::Client.new(@opts)
11
+ @fastly = Fastly.new(@opts)
12
+ rescue Exception => e
13
+ pp e
14
+ exit(-1)
15
+ end
16
+ end
17
+
18
+ def test_purging
19
+ service_name = "fastly-test-service-#{get_rand}"
20
+ service = @fastly.create_service(:name => service_name)
21
+
22
+ assert_raises Fastly::AuthRequired do
23
+ service.purge_by_key('somekey')
24
+ end
25
+ ensure
26
+ @fastly.delete_service(service)
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fastly Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-25 00:00:00.000000000 Z
11
+ date: 2014-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curb
@@ -92,6 +92,7 @@ files:
92
92
  - test/fastly/util_test.rb
93
93
  - test/full_login_test.rb
94
94
  - test/helper.rb
95
+ - test/missing_api_key_test.rb
95
96
  - test/stats_test.rb
96
97
  - test/test_helper.rb
97
98
  homepage: http://github.com/fastly/fastly-ruby
@@ -114,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
115
  version: '0'
115
116
  requirements: []
116
117
  rubyforge_project:
117
- rubygems_version: 2.2.1
118
+ rubygems_version: 2.0.14
118
119
  signing_key:
119
120
  specification_version: 4
120
121
  summary: Client library for the Fastly acceleration system
@@ -125,5 +126,6 @@ test_files:
125
126
  - test/fastly/util_test.rb
126
127
  - test/full_login_test.rb
127
128
  - test/helper.rb
129
+ - test/missing_api_key_test.rb
128
130
  - test/stats_test.rb
129
131
  - test/test_helper.rb