fastly 1.1.5 → 1.2.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 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