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 +4 -4
- data/HISTORY.md +4 -2
- data/bin/fastly_create_domain +3 -3
- data/lib/fastly/base.rb +48 -45
- data/lib/fastly/client.rb +140 -125
- data/lib/fastly/gem_version.rb +1 -1
- data/lib/fastly/service.rb +4 -3
- data/test/api_key_test.rb +0 -2
- data/test/missing_api_key_test.rb +28 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0270d26d5f2da61fe372839853d8710120d239bb
|
4
|
+
data.tar.gz: a5354c14c11c76a1a0ec5e4a129f7a90a0cd6fe2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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`
|
data/bin/fastly_create_domain
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/bin/env ruby
|
2
2
|
|
3
3
|
##
|
4
|
-
#
|
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)
|
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'
|
data/lib/fastly/base.rb
CHANGED
@@ -11,51 +11,54 @@ class Fastly
|
|
11
11
|
@keys.push(key)
|
12
12
|
end
|
13
13
|
self.fetcher = fetcher
|
14
|
-
|
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
|
data/lib/fastly/client.rb
CHANGED
@@ -6,168 +6,183 @@ require 'pp'
|
|
6
6
|
require 'uri'
|
7
7
|
|
8
8
|
class Fastly
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
46
|
-
|
47
|
-
end
|
43
|
+
@require_key = true
|
44
|
+
end
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
46
|
+
def require_key?
|
47
|
+
!!@require_key
|
48
|
+
end
|
53
49
|
|
54
|
-
|
50
|
+
def authed?
|
51
|
+
!api_key.nil? || fully_authed?
|
52
|
+
end
|
55
53
|
|
56
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
77
|
+
def post(path, params={})
|
78
|
+
post_and_put(:post, path, params)
|
79
|
+
end
|
84
80
|
|
85
|
-
|
81
|
+
def put(path, params={})
|
82
|
+
post_and_put(:put, path, params)
|
83
|
+
end
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
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
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
115
|
-
|
116
|
-
|
129
|
+
# :nodoc: all
|
130
|
+
class Curl
|
131
|
+
attr_accessor :host, :port, :protocol
|
117
132
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
133
|
+
def initialize(host, port=443)
|
134
|
+
self.host = host
|
135
|
+
self.port = port
|
136
|
+
self.protocol = 'https'
|
137
|
+
end
|
123
138
|
|
124
|
-
|
125
|
-
|
126
|
-
|
139
|
+
def get(path, headers={})
|
140
|
+
CurbFu.get({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
|
141
|
+
end
|
127
142
|
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
151
|
+
def delete(path, headers={})
|
152
|
+
CurbFu.delete({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
|
153
|
+
end
|
139
154
|
|
140
|
-
|
141
|
-
|
142
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
164
|
+
def success?
|
165
|
+
return Net::HTTPSuccess === self
|
166
|
+
end
|
152
167
|
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
171
|
-
|
172
|
-
|
185
|
+
def [](key)
|
186
|
+
get_fields(key).last
|
187
|
+
end
|
173
188
|
end
|
data/lib/fastly/gem_version.rb
CHANGED
data/lib/fastly/service.rb
CHANGED
@@ -59,13 +59,14 @@ class Fastly
|
|
59
59
|
|
60
60
|
# Purge all assets from this service.
|
61
61
|
def purge_all
|
62
|
-
|
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
|
-
|
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.
|
data/test/api_key_test.rb
CHANGED
@@ -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.
|
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-
|
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.
|
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
|