fastly 1.1.5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f311beb83bf3886557b6da399d17d49682ec4ffb
4
- data.tar.gz: f47f3014d3b66738f9938e3b84e5ab4d46b9a8d5
3
+ metadata.gz: 98cf194db3451a553915a60698cccafb1551cd17
4
+ data.tar.gz: 0cc9c5cf4265b30629c84ba203df8288a37408e0
5
5
  SHA512:
6
- metadata.gz: be5c1f769e551f2bbf7a16bab3508a14191c42cee4f9e7a95075c4be14f9e76aee9d1294e14b4d0bfa13f4bad7de9cb2f130bb6670a6e37ebee7217649dc0f4f
7
- data.tar.gz: 9b8c4b14104b4d3148e2c9679a92db0a8e5f59fd2e0e4fbf21ddebb908f37ddd2fe8e4746974333074a665046cb8cda70eca279b5789cee1fb37d89b4959d008
6
+ metadata.gz: 8b5fe7fff0fc9283303bd7ccbc22c2d9c7ba91942d77fc2d2955dac37ab657ab2a55548e58da3e4ce16d2f8bc8a7c37ebb6b954b73fc5555d692052e69345ba6
7
+ data.tar.gz: 8ae29620a8c2dd856f245c45035b30e56c15cdff6bc4d700c4603fde9459ee5c40f5e2d11a6fbc2e1592ed6081127eac127b7a1bfd062269870a699ff8ff8603
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ pkg/*
5
5
  run_test.sh
6
6
  doc/*
7
7
  .*.sw?
8
+ .env
data/Gemfile CHANGED
@@ -8,4 +8,5 @@ group :development, :test do
8
8
  gem 'minitest', '~> 5.3.4'
9
9
  gem 'pry'
10
10
  gem 'rubocop'
11
+ gem 'webmock'
11
12
  end
data/HISTORY.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # HEAD
2
2
 
3
+ ## 2015-02-05 v1.2.0
4
+ * remove curb-fu. Net::HTTP is used instead - https://github.com/fastly/fastly-ruby/pull/44
5
+ * better client error handling - https://github.com/fastly/fastly-ruby/pull/48
6
+
3
7
  ## 2014-12-15 v1.1.5
4
8
  * major refactor and reorganization of code (merged branch https://github.com/fastly/fastly-ruby/pull/31)
5
9
  * bump curb dep to 0.8.6 for ruby 2.1 support (see https://github.com/fastly/fastly-ruby/issues/43)
@@ -16,7 +16,4 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- test/*`.split("\n")
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
18
  s.require_paths = ['lib']
19
-
20
- s.add_dependency 'curb', '~> 0.8.6'
21
- s.add_dependency 'curb-fu', '~> 0.6.2'
22
19
  end
@@ -5,10 +5,8 @@
5
5
  # A client library for interacting with the Fastly web acceleration service
6
6
  require 'fastly/gem_version'
7
7
  require 'fastly/util'
8
- require 'ext/curb_fu/response/base'
9
8
  require 'fastly/fetcher'
10
9
  require 'fastly/client'
11
-
12
10
  require 'fastly/base'
13
11
  require 'fastly/belongs_to_service_and_version'
14
12
  require 'fastly/backend'
@@ -1,7 +1,6 @@
1
1
  require 'json'
2
2
  require 'cgi'
3
- require 'uri'
4
- require 'fastly/client/curl'
3
+ require 'net/http' # also requires uri
5
4
 
6
5
  class Fastly
7
6
  # The UserAgent to communicate with the API
@@ -16,26 +15,24 @@ class Fastly
16
15
 
17
16
  base = opts.fetch(:base_url, 'https://api.fastly.com')
18
17
  uri = URI.parse(base)
19
-
20
- @http = Curl.new(uri)
18
+ @http = Net::HTTP.start(uri.host, uri.port, use_ssl: true)
21
19
 
22
20
  return self unless fully_authed?
23
21
 
24
- # If we're fully authed (i.e username and password ) then we need to log in
22
+ # If full auth creds (user/pass) then log in and set a cookie
25
23
  resp = http.post('/login', make_params(user: user, password: password))
26
24
 
27
- if resp.success?
25
+ if resp.kind_of?(Net::HTTPSuccess)
28
26
  @cookie = resp['Set-Cookie']
29
27
  else
30
- fail Unauthorized
28
+ fail Unauthorized, "Invalid auth credentials. Check username/password."
31
29
  end
32
30
 
33
31
  self
34
32
  end
35
33
 
36
34
  def require_key!
37
- raise Fastly::AuthRequired.new("This request requires an API key") if api_key.nil?
38
-
35
+ raise Fastly::KeyAuthRequired.new("This request requires an API key") if api_key.nil?
39
36
  @require_key = true
40
37
  end
41
38
 
@@ -55,18 +52,18 @@ class Fastly
55
52
  def get(path, params = {})
56
53
  path += "?#{make_params(params)}" unless params.empty?
57
54
  resp = http.get(path, headers)
58
- return nil if 404 == resp.status
59
- fail Error, resp.message unless resp.success?
55
+ fail Error, resp.body unless resp.kind_of?(Net::HTTPSuccess)
60
56
  JSON.parse(resp.body)
61
57
  end
62
58
 
63
59
  def get_stats(path, params = {})
64
- content = get(path, params)
60
+ resp = get(path, params)
65
61
 
66
- case content['status']
67
- when 'success' then content['data']
62
+ # return meta data, not just the actual stats data
63
+ if resp['status'] == 'success'
64
+ resp
68
65
  else
69
- fail Error, content['message']
66
+ fail Error, resp['msg']
70
67
  end
71
68
  end
72
69
 
@@ -80,7 +77,7 @@ class Fastly
80
77
 
81
78
  def delete(path)
82
79
  resp = http.delete(path, headers)
83
- resp.success?
80
+ resp.kind_of?(Net::HTTPSuccess)
84
81
  end
85
82
 
86
83
  private
@@ -88,13 +85,7 @@ class Fastly
88
85
  def post_and_put(method, path, params = {})
89
86
  query = make_params(params)
90
87
  resp = http.send(method, path, query, headers.merge('Content-Type' => 'application/x-www-form-urlencoded'))
91
-
92
- if resp.success?
93
- JSON.parse(resp.body)
94
- else
95
- fail Error, resp.message
96
- end
97
-
88
+ fail Error, resp.body unless resp.kind_of?(Net::HTTPSuccess)
98
89
  JSON.parse(resp.body)
99
90
  end
100
91
 
@@ -2,6 +2,8 @@ class Fastly
2
2
  # :nodoc:
3
3
  class AuthRequired < RuntimeError; end
4
4
  # :nodoc:
5
+ class KeyAuthRequired < AuthRequired; end
6
+ # :nodoc:
5
7
  class FullAuthRequired < AuthRequired; end
6
8
  # :nodoc:
7
9
  class Error < RuntimeError; end
@@ -1,4 +1,4 @@
1
1
  # The current version of the library
2
2
  class Fastly
3
- VERSION = "1.1.5"
3
+ VERSION = "1.2.0"
4
4
  end
@@ -1,3 +1,5 @@
1
+ require 'date'
2
+
1
3
  # Invoice object
2
4
  class Fastly
3
5
  # An invoice for a time period
@@ -0,0 +1,112 @@
1
+ require 'test_helper'
2
+
3
+ describe Fastly::Client do
4
+ let(:user) { "test@example.com" }
5
+ let(:password) { "notasecret" }
6
+ let(:api_key) { "notasecreteither" }
7
+
8
+ describe 'initialize' do
9
+ it 'raises ArgumentError when no options provided' do
10
+ assert_raises(ArgumentError) {
11
+ Fastly::Client.new()
12
+ }
13
+ end
14
+
15
+ it 'does not log in if user/pass are not provided' do
16
+ client = Fastly::Client.new(api_key: api_key)
17
+
18
+ assert_equal api_key, client.api_key
19
+ assert_equal nil, client.user
20
+ assert_equal nil, client.password
21
+ end
22
+
23
+ it 'raises Unauthorized if user/pass provided but are invalid' do
24
+ stub_request(:any, /api.fastly.com/).to_return(status: 400)
25
+
26
+ e = assert_raises(Fastly::Unauthorized) {
27
+ Fastly::Client.new(user: user, password: pass)
28
+ }
29
+ assert_equal "Invalid auth credentials. Check username/password.", e.message
30
+ end
31
+
32
+ it 'initializes an http client' do
33
+ client = Fastly::Client.new(api_key: api_key)
34
+
35
+ assert_equal Net::HTTP, client.http.class
36
+ assert_equal 443, client.http.port
37
+ assert_equal 'api.fastly.com', client.http.address
38
+ assert client.http.use_ssl?
39
+ end
40
+
41
+ it 'sets a cookie when auth with valid user/pass' do
42
+ stub_request(:any, /api.fastly.com/).
43
+ to_return(body: JSON.generate(i: "dont care"), status: 200, headers: { 'Set-Cookie' => 'tasty!' })
44
+
45
+ client = Fastly::Client.new(user: user, password: pass)
46
+ assert_equal "tasty!", client.cookie
47
+ end
48
+ end
49
+
50
+ describe 'get' do
51
+ let(:client) { Fastly::Client.new(api_key: api_key) }
52
+
53
+ it 'accepts a path and returns a parsed json hash' do
54
+ stub_request(:any, /api.fastly.com/).
55
+ to_return(body: JSON.generate(i: "dont care"), status: 200)
56
+
57
+ resp = client.get('/service/blah')
58
+ assert_equal resp.class, Hash
59
+ assert_includes resp, "i"
60
+ end
61
+
62
+ it 'raises Fastly::Error on unsuccessful GETs' do
63
+ stub_request(:any, /api.fastly.com/).to_return(status: 400)
64
+
65
+ assert_raises(Fastly::Error) {
66
+ client.get('/service/blah')
67
+ }
68
+ end
69
+ end
70
+
71
+ describe 'post' do
72
+ let(:client) { Fastly::Client.new(api_key: api_key) }
73
+
74
+ it 'raises Fastly::Error on unsuccessful POST' do
75
+ stub_request(:any, /api.fastly.com/).to_return(status: 400)
76
+
77
+ assert_raises(Fastly::Error) {
78
+ client.post('/service/blah')
79
+ }
80
+ end
81
+
82
+ it 'can make a successful POST' do
83
+ stub_request(:any, /api.fastly.com/).
84
+ to_return(body: JSON.generate(i: "dont care"), status: 200)
85
+
86
+ resp = client.post('/service/blah')
87
+ assert_equal resp.class, Hash
88
+ assert_includes resp, "i"
89
+ end
90
+ end
91
+
92
+ describe 'get_stats' do
93
+ let(:client) { Fastly::Client.new(api_key: api_key) }
94
+
95
+ it 'raises Fastly::Error when unsuccessful get' do
96
+ stub_request(:any, /api.fastly.com/).to_return(status: 400)
97
+
98
+ assert_raises(Fastly::Error) {
99
+ client.get_stats('/stats')
100
+ }
101
+ end
102
+
103
+ it 'can make a successful stats GET' do
104
+ stub_request(:any, /api.fastly.com/).
105
+ to_return(body: JSON.generate(i: "dont care", status: 'success', data: {}), status: 200)
106
+
107
+ resp = client.get_stats('/stats')
108
+ assert_equal resp.class, Hash
109
+
110
+ end
111
+ end
112
+ end
@@ -83,7 +83,9 @@ class Fastly
83
83
  it 'should allow us to delete a user' do
84
84
  user_id = user.id
85
85
  assert_equal true, fastly.delete_user(user)
86
- assert_equal nil, fastly.get_user(user_id)
86
+ assert_raises(Fastly::Error) do
87
+ fastly.get_user(user_id)
88
+ end
87
89
  end
88
90
  end
89
91
  end
@@ -19,7 +19,7 @@ class MissingApiKeyTest < Fastly::TestCase
19
19
  service_name = "fastly-test-service-#{random_string}"
20
20
  service = @fastly.create_service(:name => service_name)
21
21
 
22
- assert_raises Fastly::AuthRequired do
22
+ assert_raises Fastly::KeyAuthRequired do
23
23
  service.purge_by_key('somekey')
24
24
  end
25
25
  ensure
@@ -23,42 +23,35 @@ class StatsTest < Fastly::TestCase
23
23
 
24
24
  def test_usage
25
25
  usage = @fastly.usage(:from => FROM)
26
- assert(usage['usa'], 'Found a USA region in usage')
27
- assert(usage['usa']['requests'], 'USA region has a requests field')
26
+ # usage can be and empty hash if no usage stats
27
+ # this client is not responsiblew for verifying the stats api,
28
+ # just that requests to stats work
29
+ assert(usage)
30
+ assert(usage['meta'])
31
+ assert_equal 'success', usage['status']
28
32
 
29
33
  usage = @fastly.usage(:from => FROM, :by_service => 1)
30
- assert(usage['usa'], 'Found a USA region in usage')
31
- assert(usage['usa']['requests'].nil?, "USA region doesn't have a requests field")
34
+ assert(usage)
35
+ assert(usage['meta'])
36
+ assert_equal 'success', usage['status']
32
37
  end
33
38
 
34
39
  def test_stats
35
40
  stats = @fastly.stats(:from => FROM)
36
- service1, service2 = stats.keys
37
- assert(stats[service1][0]['requests'], 'Found requests')
38
- assert(stats[service1][0]['hits'], 'Found hits')
39
- assert(stats[service2][0]['requests'], 'Found requests')
40
- assert(stats[service2][0]['hits'], 'Found hits')
41
+ # stats can be and empty hash if no usage stats
42
+ assert(stats)
43
+ assert_equal 'success', stats['status']
44
+ assert_equal 'all', stats['meta']['region']
41
45
 
42
46
  stats = @fastly.stats(:from => FROM, :field => 'requests')
43
- assert(stats[service1][0]['requests'], 'Found requests')
44
- assert(stats[service1][0]['hits'].nil?, "Didn't find hits")
45
- assert(stats[service2][0]['requests'], 'Found requests')
46
- assert(stats[service2][0]['hits'].nil?, "Didn't find hits")
47
-
48
- stats = @fastly.stats(:from => FROM, :service => service1)
49
- assert_equal(stats[0]['service_id'], service1, 'Got correct service id')
50
- assert(stats[0]['requests'], 'Found requests')
51
- assert(stats[0]['hits'], 'Found hits')
52
-
53
- stats = @fastly.stats(:from => FROM, :field => 'requests', :service => service1)
54
- assert_equal(stats[0]['service_id'], service1, 'Got correct service id')
55
- assert(stats[0]['requests'], 'Found requests')
56
- assert(stats[0]['hits'].nil?, "Didn't find hits")
47
+ assert(stats)
48
+ assert_equal 'success', stats['status']
49
+ assert_equal 'all', stats['meta']['region']
57
50
 
58
51
  stats = @fastly.stats(:from => FROM, :aggregate => true)
59
- assert(stats[0]['service_id'].nil?, 'No service id')
60
- assert(stats[0]['requests'], 'Found requests')
61
- assert(stats[0]['hits'], 'Found hits')
52
+ assert(stats)
53
+ assert_equal 'success', stats['status']
54
+ assert_equal 'all', stats['meta']['region']
62
55
 
63
56
  # stats aggregate with field
64
57
  assert_raises Fastly::Error do
@@ -67,11 +60,11 @@ class StatsTest < Fastly::TestCase
67
60
 
68
61
  # stats aggregate with service
69
62
  assert_raises Fastly::Error do
70
- @fastly.stats(:from => FROM, :service => service1, :aggregate => true)
63
+ @fastly.stats(:from => FROM, :service => 'myserviceId', :aggregate => true)
71
64
  end
72
65
 
73
66
  assert_raises Fastly::Error do
74
- @fastly.stats(:from => FROM, :service => service1, :field => 'requests', :aggregate => true)
67
+ @fastly.stats(:from => FROM, :service => 'datServiceID', :field => 'requests', :aggregate => true)
75
68
  end
76
69
  end
77
70
  end
@@ -1,2 +1,3 @@
1
1
  require 'minitest/autorun'
2
+ require 'webmock/minitest'
2
3
  require 'fastly'
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fastly
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-16 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: curb
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: 0.8.6
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 0.8.6
27
- - !ruby/object:Gem::Dependency
28
- name: curb-fu
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: 0.6.2
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ~>
39
- - !ruby/object:Gem::Version
40
- version: 0.6.2
11
+ date: 2015-02-06 00:00:00.000000000 Z
12
+ dependencies: []
41
13
  description: Client library for the Fastly acceleration system
42
14
  email:
43
15
  - simon@fastly.com
@@ -60,14 +32,12 @@ files:
60
32
  - bin/fastly_create_domain
61
33
  - bin/fastly_upload_vcl
62
34
  - fastly.gemspec
63
- - lib/ext/curb_fu/response/base.rb
64
35
  - lib/fastly.rb
65
36
  - lib/fastly/backend.rb
66
37
  - lib/fastly/base.rb
67
38
  - lib/fastly/belongs_to_service_and_version.rb
68
39
  - lib/fastly/cache_setting.rb
69
40
  - lib/fastly/client.rb
70
- - lib/fastly/client/curl.rb
71
41
  - lib/fastly/condition.rb
72
42
  - lib/fastly/customer.rb
73
43
  - lib/fastly/director.rb
@@ -93,6 +63,7 @@ files:
93
63
  - test/admin_test.rb
94
64
  - test/api_key_test.rb
95
65
  - test/common.rb
66
+ - test/fastly/client_test.rb
96
67
  - test/fastly/util_test.rb
97
68
  - test/full_login_test.rb
98
69
  - test/helper.rb
@@ -127,6 +98,7 @@ test_files:
127
98
  - test/admin_test.rb
128
99
  - test/api_key_test.rb
129
100
  - test/common.rb
101
+ - test/fastly/client_test.rb
130
102
  - test/fastly/util_test.rb
131
103
  - test/full_login_test.rb
132
104
  - test/helper.rb
@@ -1,20 +0,0 @@
1
- require 'curb-fu'
2
-
3
- module CurbFu
4
- module Response
5
- # :nodoc: all
6
- class Base
7
- def get_fields(key)
8
- if (match = @headers.find { |k, _| k.downcase == key.downcase })
9
- [match.last].flatten
10
- else
11
- []
12
- end
13
- end
14
-
15
- def [](key)
16
- get_fields(key).last
17
- end
18
- end
19
- end
20
- end
@@ -1,57 +0,0 @@
1
- require 'curb-fu'
2
-
3
- class Fastly
4
- class Client
5
- # :nodoc: all
6
- class Curl
7
- attr_accessor :uri, :host, :port, :protocol
8
-
9
- def initialize(uri)
10
- @uri = uri
11
- @host = uri.host
12
- @port = uri.port
13
- @protocol = uri.scheme
14
- end
15
-
16
- def get(path, headers = {})
17
- CurbFu.get({
18
- host: host,
19
- port: port,
20
- path: path,
21
- headers: headers,
22
- protocol: protocol
23
- })
24
- end
25
-
26
- def post(path, params, headers = {})
27
- CurbFu.post({
28
- host: host,
29
- port: port,
30
- path: path,
31
- headers: headers,
32
- protocol: protocol
33
- }, params)
34
- end
35
-
36
- def put(path, params, headers = {})
37
- CurbFu.put({
38
- host: host,
39
- port: port,
40
- path: path,
41
- headers: headers,
42
- protocol: protocol
43
- }, params)
44
- end
45
-
46
- def delete(path, headers = {})
47
- CurbFu.delete({
48
- host: host,
49
- port: port,
50
- path: path,
51
- headers: headers,
52
- protocol: protocol
53
- })
54
- end
55
- end
56
- end
57
- end