fleet-api 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,73 +2,77 @@ require 'spec_helper'
2
2
 
3
3
  describe Fleet::Connection do
4
4
 
5
- describe 'registered middleware' do
6
-
7
- subject { Fleet::Client.new.connection }
8
-
9
- handlers = [
10
- Faraday::Request::UrlEncoded,
11
- FaradayMiddleware::ParseJson,
12
- Fleet::Middleware::Response::RaiseError,
13
- FaradayMiddleware::FollowRedirects,
14
- Faraday::Adapter::NetHttp
15
- ]
16
-
17
- handlers.each do |handler|
18
- it { expect(subject.builder.handlers).to include handler }
19
- end
20
-
21
- it "includes exactly #{handlers.count} handlers" do
22
- expect(subject.builder.handlers.count).to eql handlers.count
23
- end
24
- end
25
-
26
5
  describe 'connection options' do
27
6
 
28
- let(:url) { 'http://foo.com/bar' }
29
- let(:ssl_options) { { verify: true } }
30
- let(:proxy) { 'http://proxy.com' }
7
+ let(:open_timeout) { 30 }
8
+ let(:read_timeout) { 40 }
31
9
 
32
10
  subject do
33
11
  Fleet::Client.new(
34
- fleet_api_url: url,
35
- ssl_options: ssl_options,
36
- proxy: proxy).connection
12
+ open_timeout: open_timeout,
13
+ read_timeout: read_timeout).connection
37
14
  end
38
15
 
39
- describe 'scheme' do
40
- it 'matches the scheme of the URL' do
41
- expect(subject.scheme).to eq 'http'
16
+ describe 'open_timeout' do
17
+ it 'matches the the specified timeout value' do
18
+ expect(subject.data[:connect_timeout]).to eq open_timeout
42
19
  end
43
20
  end
44
21
 
45
- describe 'host' do
46
- it 'matches the host of the URL' do
47
- expect(subject.host).to eq 'foo.com'
22
+ describe 'read_timeout' do
23
+ it 'matches the the specified timeout value' do
24
+ expect(subject.data[:read_timeout]).to eq read_timeout
48
25
  end
49
26
  end
50
27
 
51
- describe 'port' do
52
- it 'matches the port of the URL' do
53
- expect(subject.port).to eq 80
28
+ context 'when URL is HTTP' do
29
+ let(:url) { 'http://foo.com/bar' }
30
+
31
+ subject do
32
+ Fleet::Client.new(fleet_api_url: url).connection
33
+ end
34
+ describe 'scheme' do
35
+ it 'matches the scheme of the URL' do
36
+ expect(subject.data[:scheme]).to eq 'http'
37
+ end
54
38
  end
55
- end
56
39
 
57
- describe 'path_prefix' do
58
- it 'matches the path of the URL' do
59
- expect(subject.path_prefix).to eq '/bar'
40
+ describe 'host' do
41
+ it 'matches the host of the URL' do
42
+ expect(subject.data[:host]).to eq 'foo.com'
43
+ end
60
44
  end
61
- end
62
45
 
63
- describe 'ssl' do
64
- it 'matches the specified SSL options' do
65
- expect(subject.ssl).to eq ssl_options
46
+ describe 'port' do
47
+ it 'matches the port of the URL' do
48
+ expect(subject.data[:port]).to eq 80
49
+ end
50
+ end
51
+
52
+ describe 'prefix' do
53
+ it 'matches the path of the URL' do
54
+ expect(subject.data[:path]).to eq '/bar'
55
+ end
66
56
  end
67
57
  end
68
58
 
69
- describe 'proxy' do
70
- it 'matches the specified SSL options' do
71
- expect(subject.proxy[:uri].to_s).to eq proxy
59
+ context 'when URL is UNIX' do
60
+ let(:url) { 'unix:///foo/bar.socket' }
61
+
62
+ subject do
63
+ Fleet::Client.new(fleet_api_url: url).connection
64
+ end
65
+
66
+ describe 'scheme' do
67
+ it 'matches the scheme of the URL' do
68
+ expect(subject.data[:scheme]).to eq 'unix'
69
+ end
70
+ end
71
+
72
+ describe 'socket' do
73
+ it 'matches the port of the URL' do
74
+ expect(subject.data[:socket]).to eq '/foo/bar.socket'
75
+ end
72
76
  end
73
77
  end
74
78
 
@@ -4,13 +4,11 @@ describe Fleet::Error do
4
4
 
5
5
  let(:message) { 'some message' }
6
6
  let(:error_code) { 12345 }
7
- let(:cause) { 'user error' }
8
7
 
9
- subject { Fleet::Error.new(message, error_code, cause) }
8
+ subject { Fleet::Error.new(message, error_code) }
10
9
 
11
10
  it { should respond_to(:message) }
12
11
  it { should respond_to(:error_code) }
13
- it { should respond_to(:cause) }
14
12
 
15
13
  describe '#initialize' do
16
14
 
@@ -21,9 +19,5 @@ describe Fleet::Error do
21
19
  it 'saves the passed-in error code' do
22
20
  expect(subject.error_code).to eq error_code
23
21
  end
24
-
25
- it 'saves the passed-in cause' do
26
- expect(subject.cause).to eq cause
27
- end
28
22
  end
29
23
  end
@@ -4,124 +4,91 @@ describe Fleet::Request do
4
4
 
5
5
  subject { Fleet::Client.new }
6
6
 
7
- let(:path) { '/path' }
8
-
9
- let(:request) do
10
- double(:request,
11
- options: {},
12
- headers: {},
13
- params: {},
14
- 'headers=' => nil,
15
- 'path=' => nil)
16
- end
7
+ let(:path) { '/foo bar@' }
17
8
 
18
9
  let(:response) do
19
- double(:response, body: 'foo')
10
+ double(:response, body: '{"name":"foo"}', status: 200)
20
11
  end
21
12
 
22
13
  let(:connection) { double(:connection) }
23
14
 
24
15
  before do
25
- allow(connection).to receive(:send).and_yield(request).and_return(response)
16
+ allow(connection).to receive(:send).and_return(response)
26
17
  allow(subject).to receive(:connection).and_return(connection)
27
18
  end
28
19
 
29
- [:get, :delete, :head, :put, :post].each do |method|
30
-
31
- context "##{method}" do
20
+ describe '#get' do
32
21
 
33
- it 'sets the path' do
34
- expect(request).to receive(:path=).with(path)
35
- subject.send(method, path)
36
- end
22
+ let(:options) do
23
+ { foo: 'bar' }
24
+ end
37
25
 
38
- it 'sets the headers' do
39
- headers = { foo: :bar }
40
- expect(request).to receive(:headers=).with(hash_including(headers))
41
- subject.send(method, path, {}, headers)
42
- end
26
+ it 'invokes #get on the connection with the correct params' do
27
+ opts = { path: '/foo%20bar%40', query: options }
28
+ expect(connection).to receive(:send).with(:get, opts)
43
29
 
44
- it 'returns the response body' do
45
- expect(subject.send(method, path)).to eql(response.body)
46
- end
30
+ subject.send(:get, path, options)
31
+ end
47
32
 
48
- context 'when a Faraday::Error::ConnectionFailed error is raised' do
33
+ it 'returns the parsed response body' do
34
+ expect(subject.send(:get, path, options)).to eq('name' => 'foo')
35
+ end
49
36
 
50
- before do
51
- allow(connection).to receive(:send)
52
- .and_raise(Faraday::Error::ConnectionFailed, 'oops')
53
- end
37
+ context 'when there is a SocketError' do
38
+ before do
39
+ allow(connection).to receive(:send)
40
+ .and_raise(Excon::Errors::SocketError, Excon::Errors::Error.new('oops'))
41
+ end
54
42
 
55
- it 'raises a Fleet::ConnectionError' do
56
- expect { subject.send(method, path) }.to raise_error(Fleet::ConnectionError, 'oops')
57
- end
43
+ it 'raises a Fleet::ConnectionError' do
44
+ expect { subject.send(:get, path, options) }.to raise_error(Fleet::ConnectionError)
58
45
  end
59
46
  end
60
- end
61
-
62
- [:get, :delete, :head].each do |method|
63
-
64
- context "##{method}" do
65
47
 
66
- context 'when options provided' do
67
-
68
- it 'sets options on the request' do
69
- options = { a: :b }
70
- expect(request).to receive(:params=).with(options)
71
- subject.send(method, path, options)
72
- end
48
+ context 'when a non-200 status code is returned' do
49
+ let(:response) do
50
+ double(:response, body: '{"error": {"message": "oops", "code": "400"}}', status: 400)
73
51
  end
74
52
 
75
- context 'when no options provided' do
76
-
77
- it 'does not set options on the request' do
78
- expect(request).to_not receive(:params=)
79
- subject.send(method, path)
80
- end
53
+ it 'raises a Fleet::ConnectionError' do
54
+ expect { subject.send(:get, path, options) }.to raise_error(Fleet::BadRequest, 'oops')
81
55
  end
82
56
  end
83
57
  end
84
58
 
85
- [:put, :post].each do |method|
86
-
87
- context "##{method}" do
59
+ describe '#put' do
88
60
 
89
- context 'when options provided' do
90
-
91
- it 'sets options on the request' do
92
- options = { a: :b }
93
- expect(request).to receive(:body=).with(options)
94
- subject.send(method, path, options)
95
- end
96
- end
61
+ let(:options) do
62
+ { foo: 'bar' }
63
+ end
97
64
 
98
- context 'when no options provided' do
65
+ it 'invokes #put on the connection with the correct params' do
66
+ opts = {
67
+ path: '/foo%20bar%40',
68
+ headers: { 'Content-Type' => 'application/json' },
69
+ body: JSON.dump(options)
70
+ }
71
+ expect(connection).to receive(:send).with(:put, opts)
99
72
 
100
- it 'does not set options on the request' do
101
- expect(request).to_not receive(:body=)
102
- subject.send(method, path)
103
- end
104
- end
73
+ subject.send(:put, path, options)
74
+ end
105
75
 
106
- context 'when querystring AND body provided' do
107
- let(:options) { { querystring: { a: :b }, body: { c: :d } } }
76
+ it 'returns true' do
77
+ expect(subject.send(:put, path, options)).to eq(true)
78
+ end
79
+ end
108
80
 
109
- before do
110
- allow(request).to receive(:params=)
111
- allow(request).to receive(:body=)
112
- end
81
+ describe '#delete' do
113
82
 
114
- it 'sets the querystring as request params' do
115
- expect(request).to receive(:params=).with(options[:querystring])
116
- subject.send(method, path, options)
117
- end
83
+ it 'invokes #get on the connection with the correct params' do
84
+ opts = { path: '/foo%20bar%40' }
85
+ expect(connection).to receive(:send).with(:delete, opts)
118
86
 
119
- it 'sets the body as request body' do
120
- expect(request).to receive(:body=).with(options[:body])
121
- subject.send(method, path, options)
122
- end
123
- end
87
+ subject.send(:delete, path, nil)
88
+ end
124
89
 
90
+ it 'returns true' do
91
+ expect(subject.send(:delete, path, nil)).to eq(true)
125
92
  end
126
93
  end
127
94
 
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Fleet::ServiceDefinition do
4
4
 
5
- let(:name) { 'myservice.service' }
5
+ let(:name) { 'foo.service' }
6
6
 
7
7
  let(:service_hash) do
8
8
  {
@@ -16,64 +16,23 @@ describe Fleet::ServiceDefinition do
16
16
  }
17
17
  end
18
18
 
19
- subject { described_class.new(name) }
20
-
21
- it { should respond_to :name }
22
-
23
- describe '#initialize' do
24
-
25
- subject { described_class.new(name) }
26
-
27
- describe 'name' do
28
- it 'should equal the passed-in name' do
29
- expect(subject.name).to eq name
30
- end
31
- end
32
- end
33
-
34
19
  describe '#to_unit' do
35
20
 
36
- subject { described_class.new(name, service_hash) }
21
+ subject { described_class.new(service_hash) }
37
22
 
38
23
  it 'provides a fleet formatted unit definition' do
39
24
 
40
- raw = <<UNIT_FILE
41
- [Unit]
42
- Description=#{service_hash['Unit']['Description']}
43
-
44
- [Service]
45
- ExecStartPre=#{service_hash['Service']['ExecStartPre'].first}
46
- ExecStartPre=#{service_hash['Service']['ExecStartPre'].last}
47
- ExecStart=#{service_hash['Service']['ExecStart']}
48
- UNIT_FILE
49
-
50
- expected = { 'Raw' => raw }
51
-
52
- expect(subject.to_unit).to eq expected
53
- end
54
- end
55
-
56
- describe '#to_job' do
57
-
58
- subject { described_class.new(name, service_hash) }
59
-
60
- it 'generates the appropriate job definition' do
61
-
62
25
  expected = {
63
- 'Name' => name,
64
- 'UnitHash' => [173,163,19,156,23,184,6,223,77,240,208,230,238,54,179,201,80,147,228,89]
26
+ "name" => name,
27
+ "options"=> [
28
+ { "section" => "Unit", "name" => "Description", "value" => "infinite loop"},
29
+ { "section" => "Service", "name" => "ExecStartPre", "value" => "foo" },
30
+ { "section" => "Service", "name" => "ExecStartPre", "value" => "bar" },
31
+ { "section" => "Service", "name" => "ExecStart", "value" => "/bin/bash -c \"while true; do sleep 1; done\"" }
32
+ ]
65
33
  }
66
34
 
67
- expect(subject.to_job).to eq expected
68
- end
69
- end
70
-
71
- describe '#sha1' do
72
-
73
- subject { described_class.new(name, service_hash) }
74
-
75
- it 'generates the appropriate sha1 hash' do
76
- expect(subject.sha1).to eq 'ada3139c17b806df4df0d0e6ee36b3c95093e459'
35
+ expect(subject.to_unit(name)).to eq expected
77
36
  end
78
37
  end
79
38
  end
data/spec/fleet_spec.rb CHANGED
@@ -38,15 +38,21 @@ describe Fleet do
38
38
  let(:url) { 'http://foo.com/bar' }
39
39
 
40
40
  before do
41
- stub_const('Fleet::Configuration::DEFAULT_ETCD_API_URL', url)
41
+ stub_const('Fleet::Configuration::DEFAULT_FLEET_API_URL', url)
42
42
  Fleet.reset
43
43
  end
44
44
 
45
- it 'defaults to the value of DEFAULT_ETCD_API_URL' do
45
+ it 'defaults to the value of DEFAULT_FLEET_API_URL' do
46
46
  expect(Fleet.fleet_api_url).to eq url
47
47
  end
48
48
  end
49
49
 
50
+ describe '.fleet_api_version' do
51
+ it 'defaults to v1' do
52
+ expect(Fleet.fleet_api_version).to eq 'v1'
53
+ end
54
+ end
55
+
50
56
  describe '.open_timeout' do
51
57
  it 'defaults to 2' do
52
58
  expect(Fleet.open_timeout).to eq 2
@@ -59,18 +65,6 @@ describe Fleet do
59
65
  end
60
66
  end
61
67
 
62
- describe '.ssl_options' do
63
- it 'defaults to { verify: false }' do
64
- expect(Fleet.ssl_options).to eq(verify: false)
65
- end
66
- end
67
-
68
- describe '.proxy' do
69
- it 'defaults to nil' do
70
- expect(Fleet.proxy).to be_nil
71
- end
72
- end
73
-
74
68
  describe '.configure' do
75
69
  it "accepts a block" do
76
70
  expect { Fleet.configure {} }.to_not raise_error
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fleet-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - CenturyLink
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-14 00:00:00.000000000 Z
11
+ date: 2015-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: faraday
14
+ name: excon
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
18
- - !ruby/object:Gem::Version
19
- version: 0.8.9
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.9
27
- - !ruby/object:Gem::Dependency
28
- name: faraday_middleware
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
17
+ - - ">="
32
18
  - !ruby/object:Gem::Version
33
- version: 0.9.0
19
+ version: 0.27.4
34
20
  type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
- - - '='
24
+ - - ">="
39
25
  - !ruby/object:Gem::Version
40
- version: 0.9.0
26
+ version: 0.27.4
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rake
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -112,18 +98,15 @@ files:
112
98
  - fleet-api.gemspec
113
99
  - lib/fleet.rb
114
100
  - lib/fleet/client.rb
115
- - lib/fleet/client/job.rb
116
101
  - lib/fleet/client/machines.rb
117
102
  - lib/fleet/client/state.rb
118
103
  - lib/fleet/client/unit.rb
119
104
  - lib/fleet/configuration.rb
120
105
  - lib/fleet/connection.rb
121
106
  - lib/fleet/error.rb
122
- - lib/fleet/middleware/response/raise_error.rb
123
107
  - lib/fleet/request.rb
124
108
  - lib/fleet/service_definition.rb
125
109
  - lib/fleet/version.rb
126
- - spec/fleet/client/job_spec.rb
127
110
  - spec/fleet/client/machines_spec.rb
128
111
  - spec/fleet/client/state_spec.rb
129
112
  - spec/fleet/client/unit_spec.rb
@@ -131,7 +114,6 @@ files:
131
114
  - spec/fleet/configuration_spec.rb
132
115
  - spec/fleet/connection_spec.rb
133
116
  - spec/fleet/error_spec.rb
134
- - spec/fleet/middleware/response/raise_error_spec.rb
135
117
  - spec/fleet/request_spec.rb
136
118
  - spec/fleet/service_definition_spec.rb
137
119
  - spec/fleet_spec.rb
@@ -161,7 +143,6 @@ signing_key:
161
143
  specification_version: 4
162
144
  summary: A simple REST client for the CoreOS Fleet API
163
145
  test_files:
164
- - spec/fleet/client/job_spec.rb
165
146
  - spec/fleet/client/machines_spec.rb
166
147
  - spec/fleet/client/state_spec.rb
167
148
  - spec/fleet/client/unit_spec.rb
@@ -169,7 +150,6 @@ test_files:
169
150
  - spec/fleet/configuration_spec.rb
170
151
  - spec/fleet/connection_spec.rb
171
152
  - spec/fleet/error_spec.rb
172
- - spec/fleet/middleware/response/raise_error_spec.rb
173
153
  - spec/fleet/request_spec.rb
174
154
  - spec/fleet/service_definition_spec.rb
175
155
  - spec/fleet_spec.rb
@@ -1,44 +0,0 @@
1
- module Fleet
2
- class Client
3
- module Job
4
-
5
- JOB_RESOURCE = 'job'
6
-
7
- def list_jobs
8
- opts = { consistent: true, recursive: true, sorted: true }
9
- get(job_path, opts)
10
- end
11
-
12
- def get_job(service_name)
13
- opts = { consistent: true, recursive: true, sorted: false }
14
- get(job_path(service_name, :object), opts)
15
- end
16
-
17
- def create_job(service_name, job)
18
- opts = {
19
- querystring: { 'prevExist' => false },
20
- body: { value: job.to_json }
21
- }
22
- put(job_path(service_name, :object), opts)
23
- end
24
-
25
- def delete_job(service_name)
26
- opts = { dir: false, recursive: true }
27
- delete(job_path(service_name), opts)
28
- end
29
-
30
- # Valid values for state - :loaded, :launched, :inactive
31
- def update_job_target_state(service_name, state)
32
- opts = { value: state }
33
- put(job_path(service_name, 'target-state'), opts)
34
- end
35
-
36
- private
37
-
38
- def job_path(*parts)
39
- resource_path(JOB_RESOURCE, *parts)
40
- end
41
-
42
- end
43
- end
44
- end
@@ -1,37 +0,0 @@
1
- require 'faraday'
2
- require 'json'
3
- require 'fleet/error'
4
-
5
- module Fleet::Middleware
6
- module Response
7
-
8
- class RaiseError < Faraday::Response::Middleware
9
-
10
- def on_complete(env)
11
- status = env[:status].to_i
12
- return unless (400..600).include?(status)
13
-
14
- error = parse_error(env[:body])
15
-
16
- # Find the error class that matches the HTTP status code. Default to
17
- # Error if no matching class exists.
18
- class_name = Fleet::Error::HTTP_CODE_MAP.fetch(status, 'Error')
19
-
20
- fail Fleet.const_get(class_name).new(
21
- error['message'],
22
- error['errorCode'],
23
- error['cause'])
24
- end
25
-
26
- private
27
-
28
- def parse_error(body)
29
- JSON.parse(body)
30
- rescue StandardError
31
- { 'message' => body }
32
- end
33
- end
34
-
35
- Faraday.register_middleware :response, raise_fleet_error: -> { RaiseError }
36
- end
37
- end