marathon-api 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/bin/marathon +1 -1
  4. data/lib/marathon.rb +4 -6
  5. data/lib/marathon/app.rb +27 -21
  6. data/lib/marathon/connection.rb +11 -11
  7. data/lib/marathon/constraint.rb +1 -1
  8. data/lib/marathon/container.rb +2 -2
  9. data/lib/marathon/container_docker.rb +2 -2
  10. data/lib/marathon/container_docker_port_mapping.rb +2 -2
  11. data/lib/marathon/container_volume.rb +1 -1
  12. data/lib/marathon/deployment.rb +4 -1
  13. data/lib/marathon/deployment_action.rb +1 -0
  14. data/lib/marathon/deployment_info.rb +3 -2
  15. data/lib/marathon/deployment_step.rb +1 -1
  16. data/lib/marathon/error.rb +24 -16
  17. data/lib/marathon/event_subscriptions.rb +1 -1
  18. data/lib/marathon/group.rb +2 -1
  19. data/lib/marathon/health_check.rb +7 -7
  20. data/lib/marathon/leader.rb +1 -1
  21. data/lib/marathon/queue.rb +2 -1
  22. data/lib/marathon/task.rb +7 -3
  23. data/lib/marathon/util.rb +7 -7
  24. data/lib/marathon/version.rb +1 -1
  25. data/spec/marathon/app_spec.rb +58 -54
  26. data/spec/marathon/base_spec.rb +10 -10
  27. data/spec/marathon/container_docker_port_mapping_spec.rb +7 -7
  28. data/spec/marathon/container_docker_spec.rb +13 -13
  29. data/spec/marathon/container_spec.rb +9 -9
  30. data/spec/marathon/container_volume_spec.rb +4 -4
  31. data/spec/marathon/deployment_action_spec.rb +1 -1
  32. data/spec/marathon/deployment_info_spec.rb +2 -2
  33. data/spec/marathon/deployment_spec.rb +19 -19
  34. data/spec/marathon/deployment_step_spec.rb +4 -4
  35. data/spec/marathon/error_spec.rb +7 -7
  36. data/spec/marathon/group_spec.rb +47 -47
  37. data/spec/marathon/marathon_spec.rb +1 -1
  38. data/spec/marathon/queue_spec.rb +9 -9
  39. data/spec/marathon/task_spec.rb +12 -12
  40. data/spec/marathon/util_spec.rb +17 -17
  41. metadata +2 -2
@@ -2,7 +2,7 @@
2
2
  # See https://mesosphere.github.io/marathon/docs/rest-api.html#get-/v2/leader for full list of API's methods.
3
3
  class Marathon::Leader
4
4
 
5
- def initialize(marathon_instance)
5
+ def initialize(marathon_instance = Marathon.singleton)
6
6
  @connection = marathon_instance.connection
7
7
  end
8
8
 
@@ -6,7 +6,8 @@ class Marathon::Queue < Marathon::Base
6
6
 
7
7
  # Create a new queue element object.
8
8
  # ++hash++: Hash returned by API, including 'app' and 'delay'
9
- def initialize(hash, marathon_instance)
9
+ # ++marathon_instance++: MarathonInstance holding a connection to marathon
10
+ def initialize(hash, marathon_instance = Marathon.singleton)
10
11
  super(hash, %w[delay])
11
12
  @app = Marathon::App.new(info[:app], marathon_instance, true)
12
13
  @marathon_instance = marathon_instance
@@ -6,7 +6,8 @@ class Marathon::Task < Marathon::Base
6
6
 
7
7
  # Create a new task object.
8
8
  # ++hash++: Hash including all attributes
9
- def initialize(hash, marathon_instance)
9
+ # ++marathon_instance++: MarathonInstance holding a connection to marathon
10
+ def initialize(hash, marathon_instance = Marathon.singleton)
10
11
  super(hash, ACCESSORS)
11
12
  @marathon_instance = marathon_instance
12
13
  end
@@ -17,6 +18,7 @@ class Marathon::Task < Marathon::Base
17
18
  def delete!(scale = false)
18
19
  new_task = self.class.delete(id, scale)
19
20
  end
21
+
20
22
  alias :kill! :delete!
21
23
 
22
24
  def to_s
@@ -56,8 +58,9 @@ Version: #{version}
56
58
  # ++scale++: Scale the app down (i.e. decrement its instances setting by the number of tasks killed)
57
59
  # after killing the specified tasks.
58
60
  def delete(ids, scale = false)
59
- Marathon.singleton.tasks.delete(ids,scale)
61
+ Marathon.singleton.tasks.delete(ids, scale)
60
62
  end
63
+
61
64
  alias :remove :delete
62
65
  alias :kill :delete
63
66
 
@@ -67,8 +70,9 @@ Version: #{version}
67
70
  # ++scale++: Scale the app down (i.e. decrement its instances setting by the number of tasks killed)
68
71
  # after killing the specified tasks.
69
72
  def delete_all(appId, host = nil, scale = false)
70
- Marathon.singleton.tasks.delete_all(appId,host,scale)
73
+ Marathon.singleton.tasks.delete_all(appId, host, scale)
71
74
  end
75
+
72
76
  alias :remove_all :delete_all
73
77
  alias :kill_all :delete_all
74
78
  end
@@ -18,10 +18,10 @@ class Marathon::Util
18
18
  unless allowed.include?(value)
19
19
  if nil_allowed
20
20
  raise Marathon::Error::ArgumentError,
21
- "#{name} must be one of #{allowed.join(', ')} or nil, but is '#{value}'"
21
+ "#{name} must be one of #{allowed.join(', ')} or nil, but is '#{value}'"
22
22
  else
23
23
  raise Marathon::Error::ArgumentError,
24
- "#{name} must be one of #{allowed.join(', ')} or nil, but is '#{value}'"
24
+ "#{name} must be one of #{allowed.join(', ')} or nil, but is '#{value}'"
25
25
  end
26
26
  end
27
27
  end
@@ -43,12 +43,12 @@ class Marathon::Util
43
43
  # ++ignore_keys++: don't keywordize hashes under theses keys
44
44
  def keywordize_hash!(hash, ignore_keys = [:env])
45
45
  if hash.is_a?(Hash)
46
- hmap!(hash) do |k,v|
46
+ hmap!(hash) do |k, v|
47
47
  key = k.to_sym
48
48
  if ignore_keys.include?(key) and v.is_a?(Hash)
49
- { key => v }
49
+ {key => v}
50
50
  else
51
- { key => keywordize_hash!(v) }
51
+ {key => keywordize_hash!(v)}
52
52
  end
53
53
  end
54
54
  elsif hash.is_a?(Array)
@@ -63,7 +63,7 @@ class Marathon::Util
63
63
  def remove_keys(hash, keys)
64
64
  if hash.is_a?(Hash)
65
65
  new_hash = {}
66
- hash.each { |k,v| new_hash[k] = remove_keys(v, keys) unless keys.include?(k) }
66
+ hash.each { |k, v| new_hash[k] = remove_keys(v, keys) unless keys.include?(k) }
67
67
  new_hash
68
68
  elsif hash.is_a?(Array)
69
69
  hash.map { |e| remove_keys(e, keys) }
@@ -82,7 +82,7 @@ class Marathon::Util
82
82
  if item.nil?
83
83
  nil
84
84
  elsif item.is_a?(Array)
85
- item.map {|e| e.to_pretty_s}.join(',')
85
+ item.map { |e| e.to_pretty_s }.join(',')
86
86
  else
87
87
  item.to_pretty_s
88
88
  end
@@ -1,3 +1,3 @@
1
1
  module Marathon
2
- VERSION = '2.0.0'
2
+ VERSION = '2.0.1'
3
3
  end
@@ -4,18 +4,18 @@ describe Marathon::App do
4
4
 
5
5
  describe '#to_s' do
6
6
  subject { described_class.new({
7
- 'id' => '/app/foo',
8
- 'instances' => 1,
9
- 'tasks' => [],
10
- 'container' => {
11
- :type => 'DOCKER', 'docker' => { 'image' => 'foo/bar:latest' },
12
- },
13
- 'env' => {'FOO' => 'BAR', 'blubb' => 'blah'},
14
- 'constraints' => [['hostname', 'UNIQUE']],
15
- 'uris' => ['http://example.com/big.tar'],
16
- 'labels' => {'abc'=>'123'},
17
- 'version' => 'foo-version'
18
- }, double(Marathon::MarathonInstance)) }
7
+ 'id' => '/app/foo',
8
+ 'instances' => 1,
9
+ 'tasks' => [],
10
+ 'container' => {
11
+ :type => 'DOCKER', 'docker' => {'image' => 'foo/bar:latest'},
12
+ },
13
+ 'env' => {'FOO' => 'BAR', 'blubb' => 'blah'},
14
+ 'constraints' => [['hostname', 'UNIQUE']],
15
+ 'uris' => ['http://example.com/big.tar'],
16
+ 'labels' => {'abc' => '123'},
17
+ 'version' => 'foo-version'
18
+ }, double(Marathon::MarathonInstance)) }
19
19
 
20
20
  let(:expected_string) do
21
21
  "Marathon::App { :id => /app/foo }"
@@ -40,7 +40,7 @@ describe Marathon::App do
40
40
  end
41
41
 
42
42
  describe '#to_json' do
43
- subject { described_class.new({ 'id' => '/app/foo' }, double(Marathon::MarathonInstance)) }
43
+ subject { described_class.new({'id' => '/app/foo'}, double(Marathon::MarathonInstance)) }
44
44
 
45
45
  let(:expected_string) do
46
46
  '{"env":{},"labels":{},"ports":[],"uris":[],"id":"/app/foo"}'
@@ -50,7 +50,7 @@ describe Marathon::App do
50
50
  end
51
51
 
52
52
  describe '#check_read_only' do
53
- subject { described_class.new({ 'id' => '/ubuntu2' }, double(Marathon::MarathonInstance), true) }
53
+ subject { described_class.new({'id' => '/ubuntu2'}, double(Marathon::MarathonInstance), true) }
54
54
 
55
55
  it 'does not allow changing the app' do
56
56
  expect { subject.change!({}) }.to raise_error(Marathon::Error::ArgumentError)
@@ -59,8 +59,12 @@ describe Marathon::App do
59
59
 
60
60
  describe '#container' do
61
61
  subject { described_class.new({
62
- 'id' => '/ubuntu2', 'container' => {'type'=>'DOCKER', 'docker'=>{'image'=>'felixb/yocto-httpd'}}
63
- }, double(Marathon::MarathonInstance))}
62
+ 'id' => '/ubuntu2',
63
+ 'container' => {
64
+ 'type' => 'DOCKER',
65
+ 'docker' => {'image' => 'felixb/yocto-httpd'}
66
+ }
67
+ }, double(Marathon::MarathonInstance)) }
64
68
 
65
69
  it 'has container' do
66
70
  expect(subject.container).to be_instance_of(Marathon::Container)
@@ -69,7 +73,7 @@ describe Marathon::App do
69
73
  end
70
74
 
71
75
  describe '#constraints' do
72
- subject { described_class.new({ 'id' => '/ubuntu2', 'constraints' => [['hostname', 'UNIQUE']] },
76
+ subject { described_class.new({'id' => '/ubuntu2', 'constraints' => [['hostname', 'UNIQUE']]},
73
77
  double(Marathon::MarathonInstance)) }
74
78
 
75
79
  it 'has constraints' do
@@ -99,7 +103,7 @@ describe Marathon::App do
99
103
  end
100
104
 
101
105
  describe '#constraints' do
102
- subject { described_class.new({ 'id' => '/ubuntu2', 'healthChecks' => [{ 'path' => '/ping' }] },
106
+ subject { described_class.new({'id' => '/ubuntu2', 'healthChecks' => [{'path' => '/ping'}]},
103
107
  double(Marathon::MarathonInstance)) }
104
108
 
105
109
  it 'has healthChecks' do
@@ -109,7 +113,7 @@ describe Marathon::App do
109
113
  end
110
114
 
111
115
  describe '#tasks' do
112
- subject { described_class.new({ 'id' => '/ubuntu2' }, double(Marathon::MarathonInstance)) }
116
+ subject { described_class.new({'id' => '/ubuntu2'}, double(Marathon::MarathonInstance)) }
113
117
 
114
118
  it 'shows already loaded tasks w/o API call' do
115
119
  subject.info[:tasks] = []
@@ -142,26 +146,26 @@ describe Marathon::App do
142
146
  before(:each) do
143
147
  @apps = double(Marathon::Apps)
144
148
  @marathon_instance = double(Marathon::MarathonInstance, :apps => @apps)
145
- @subject = described_class.new({ 'id' => '/app/foo' }, @marathon_instance)
149
+ @subject = described_class.new({'id' => '/app/foo'}, @marathon_instance)
146
150
  end
147
151
 
148
152
  it 'checks for read only' do
149
153
  expect(@subject).to receive(:check_read_only)
150
154
  expect(@apps).to receive(:change).with(
151
155
  '/app/foo',
152
- {:env=>{}, :labels=>{}, :ports=>[], :uris=>[], :id=>"/app/foo"},
156
+ {:env => {}, :labels => {}, :ports => [], :uris => [], :id => "/app/foo"},
153
157
  false
154
- )
158
+ )
155
159
  @subject.start!
156
160
  end
157
161
 
158
162
  it 'starts the app' do
159
163
  expect(@apps).to receive(:change)
160
- .with(
161
- '/app/foo',
162
- {:env=>{}, :labels=>{}, :ports=>[], :uris=>[], :id=>"/app/foo"},
163
- false
164
- )
164
+ .with(
165
+ '/app/foo',
166
+ {:env => {}, :labels => {}, :ports => [], :uris => [], :id => "/app/foo"},
167
+ false
168
+ )
165
169
  @subject.start!
166
170
  end
167
171
  end
@@ -170,7 +174,7 @@ describe Marathon::App do
170
174
  before(:each) do
171
175
  @apps = double(Marathon::Apps)
172
176
  @marathon_instance = double(Marathon::MarathonInstance, :apps => @apps)
173
- @subject = described_class.new({ 'id' => '/app/foo' }, @marathon_instance)
177
+ @subject = described_class.new({'id' => '/app/foo'}, @marathon_instance)
174
178
  end
175
179
 
176
180
  it 'checks for read only' do
@@ -181,7 +185,7 @@ describe Marathon::App do
181
185
 
182
186
  it 'refreshs the app' do
183
187
  expect(@apps).to receive(:get).with('/app/foo') do
184
- described_class.new({ 'id' => '/app/foo', 'refreshed' => true }, double(Marathon::MarathonInstance))
188
+ described_class.new({'id' => '/app/foo', 'refreshed' => true}, double(Marathon::MarathonInstance))
185
189
  end
186
190
  @subject.refresh
187
191
  expect(@subject.info[:refreshed]).to be(true)
@@ -189,7 +193,7 @@ describe Marathon::App do
189
193
 
190
194
  it 'returns the app' do
191
195
  expect(@apps).to receive(:get).with('/app/foo') do
192
- described_class.new({ 'id' => '/app/foo' }, double(Marathon::MarathonInstance))
196
+ described_class.new({'id' => '/app/foo'}, double(Marathon::MarathonInstance))
193
197
  end
194
198
  expect(@subject.refresh).to be @subject
195
199
  end
@@ -211,13 +215,13 @@ describe Marathon::App do
211
215
 
212
216
  it 'restarts the app' do
213
217
  expect(@apps).to receive(:restart)
214
- .with('/app/foo', false)
218
+ .with('/app/foo', false)
215
219
  @subject.restart!
216
220
  end
217
221
 
218
222
  it 'restarts the app, force' do
219
223
  expect(@apps).to receive(:restart)
220
- .with('/app/foo', true)
224
+ .with('/app/foo', true)
221
225
  @subject.restart!(true)
222
226
  end
223
227
  end
@@ -236,7 +240,7 @@ describe Marathon::App do
236
240
  end
237
241
 
238
242
  it 'changes the app' do
239
- expect(@apps).to receive(:change).with('/app/foo', {:instances => 9000 }, false)
243
+ expect(@apps).to receive(:change).with('/app/foo', {:instances => 9000}, false)
240
244
  @subject.change!('instances' => 9000, 'version' => 'old-version')
241
245
  end
242
246
  end
@@ -256,12 +260,12 @@ describe Marathon::App do
256
260
  end
257
261
 
258
262
  it 'changes the app' do
259
- expect(@subject).to receive(:change!).with({:version => 'old_version' }, false)
263
+ expect(@subject).to receive(:change!).with({:version => 'old_version'}, false)
260
264
  @subject.roll_back!('old_version')
261
265
  end
262
266
 
263
267
  it 'changes the app with force' do
264
- expect(@subject).to receive(:change!).with({:version => 'old_version' }, true)
268
+ expect(@subject).to receive(:change!).with({:version => 'old_version'}, true)
265
269
  @subject.roll_back!('old_version', true)
266
270
  end
267
271
  end
@@ -320,23 +324,23 @@ describe Marathon::App do
320
324
 
321
325
  it 'passes arguments to api call' do
322
326
  expect(Marathon.connection).to receive(:get)
323
- .with('/v2/apps', {:cmd => 'foo', :embed => 'apps.tasks'})
324
- .and_return({ 'apps' => [] })
327
+ .with('/v2/apps', {:cmd => 'foo', :embed => 'apps.tasks'})
328
+ .and_return({'apps' => []})
325
329
  subject.list('foo', 'apps.tasks')
326
330
  end
327
331
 
328
332
  it 'passing id argument to api call' do
329
333
  expect(Marathon.connection).to receive(:get)
330
- .with('/v2/apps', {:id => '/app/foo'})
331
- .and_return({ 'apps' => [] })
334
+ .with('/v2/apps', {:id => '/app/foo'})
335
+ .and_return({'apps' => []})
332
336
  subject.list(nil, nil, '/app/foo')
333
337
  end
334
338
 
335
339
  it 'passing label argument to api call' do
336
340
  expect(Marathon.connection).to receive(:get)
337
- .with('/v2/apps', {:label => 'abc'})
338
- .and_return({ 'apps' => [] })
339
- subject.list(nil, nil ,nil, 'abc')
341
+ .with('/v2/apps', {:label => 'abc'})
342
+ .and_return({'apps' => []})
343
+ subject.list(nil, nil, nil, 'abc')
340
344
  end
341
345
 
342
346
  it 'raises error when run with strange embed' do
@@ -358,12 +362,12 @@ describe Marathon::App do
358
362
 
359
363
  it 'starts the app', :vcr do
360
364
  app = subject.start({
361
- :id => '/test-app',
362
- :cmd => 'sleep 10',
363
- :instances => 1,
364
- :cpus => 0.1,
365
- :mem => 32
366
- })
365
+ :id => '/test-app',
366
+ :cmd => 'sleep 10',
367
+ :instances => 1,
368
+ :cpus => 0.1,
369
+ :mem => 32
370
+ })
367
371
  expect(app).to be_instance_of(described_class)
368
372
  expect(app.id).to eq('/test-app')
369
373
  expect(app.instances).to eq(1)
@@ -402,7 +406,7 @@ describe Marathon::App do
402
406
 
403
407
  it 'deletes the app', :vcr do
404
408
  expect(subject.delete('/test-app'))
405
- .to be_instance_of(Marathon::DeploymentInfo)
409
+ .to be_instance_of(Marathon::DeploymentInfo)
406
410
  end
407
411
 
408
412
  it 'fails deleting not existing app', :vcr do
@@ -430,15 +434,15 @@ describe Marathon::App do
430
434
  subject { described_class }
431
435
 
432
436
  it 'changes the app', :vcr do
433
- expect(subject.change('/ubuntu2', { 'instances' => 2 }, true))
434
- .to be_instance_of(Marathon::DeploymentInfo)
435
- expect(subject.change('/ubuntu2', { 'instances' => 1 }, true))
436
- .to be_instance_of(Marathon::DeploymentInfo)
437
+ expect(subject.change('/ubuntu2', {'instances' => 2}, true))
438
+ .to be_instance_of(Marathon::DeploymentInfo)
439
+ expect(subject.change('/ubuntu2', {'instances' => 1}, true))
440
+ .to be_instance_of(Marathon::DeploymentInfo)
437
441
  end
438
442
 
439
443
  it 'fails with stange attributes', :vcr do
440
444
  expect {
441
- subject.change('/ubuntu2', { 'instances' => 'foo' })
445
+ subject.change('/ubuntu2', {'instances' => 'foo'})
442
446
  }.to raise_error(Marathon::Error::ClientError)
443
447
  end
444
448
  end
@@ -16,10 +16,10 @@ describe Marathon::Base do
16
16
 
17
17
  describe '#to_json' do
18
18
  subject { described_class.new({
19
- 'app' => { 'id' => '/app/foo' },
20
- :foo => 'blubb',
21
- :bar => 1
22
- }) }
19
+ 'app' => {'id' => '/app/foo'},
20
+ :foo => 'blubb',
21
+ :bar => 1
22
+ }) }
23
23
 
24
24
  let(:expected_string) do
25
25
  '{"foo":"blubb","bar":1,"app":{"id":"/app/foo"}}'
@@ -30,9 +30,9 @@ describe Marathon::Base do
30
30
 
31
31
  describe '#attr_readers' do
32
32
  subject { described_class.new({
33
- 'foo' => 'blubb',
34
- :bar => 1
35
- }, [:foo, 'bar']) }
33
+ 'foo' => 'blubb',
34
+ :bar => 1
35
+ }, [:foo, 'bar']) }
36
36
 
37
37
  its(:info) { should == {:foo => 'blubb', :bar => 1} }
38
38
  its(:foo) { should == 'blubb' }
@@ -41,9 +41,9 @@ describe Marathon::Base do
41
41
 
42
42
  describe '#attr_readers, from string array' do
43
43
  subject { described_class.new({
44
- 'foo' => 'blubb',
45
- :bar => 1
46
- }, %w[foo bar]) }
44
+ 'foo' => 'blubb',
45
+ :bar => 1
46
+ }, %w[foo bar]) }
47
47
 
48
48
  its(:info) { should == {:foo => 'blubb', :bar => 1} }
49
49
  its(:foo) { should == 'blubb' }
@@ -4,7 +4,7 @@ CONTAINER_DOCKER_PORT_MAPPING_EXAMPLE = {
4
4
  :protocol => 'tcp',
5
5
  :hostPort => 0,
6
6
  :containerPort => 8080
7
- }
7
+ }
8
8
 
9
9
  describe Marathon::ContainerDockerPortMapping do
10
10
 
@@ -13,23 +13,23 @@ describe Marathon::ContainerDockerPortMapping do
13
13
 
14
14
  it 'should fail with invalid protocol' do
15
15
  expect { subject.new(:protocol => 'foo', :containerPort => 8080) }
16
- .to raise_error(Marathon::Error::ArgumentError, /protocol must be one of /)
16
+ .to raise_error(Marathon::Error::ArgumentError, /protocol must be one of /)
17
17
  end
18
18
 
19
19
  it 'should fail with invalid containerPort' do
20
20
  expect { subject.new(:containerPort => 'foo') }
21
- .to raise_error(Marathon::Error::ArgumentError, /containerPort must be/)
21
+ .to raise_error(Marathon::Error::ArgumentError, /containerPort must be/)
22
22
  expect { subject.new(:containerPort => 0) }
23
- .not_to raise_error
23
+ .not_to raise_error
24
24
  expect { subject.new(:containerPort => -1) }
25
- .to raise_error(Marathon::Error::ArgumentError, /containerPort must be/)
25
+ .to raise_error(Marathon::Error::ArgumentError, /containerPort must be/)
26
26
  end
27
27
 
28
28
  it 'should fail with invalid hostPort' do
29
29
  expect { subject.new(:hostPort => 'foo', :containerPort => 8080) }
30
- .to raise_error(Marathon::Error::ArgumentError, /hostPort must be/)
30
+ .to raise_error(Marathon::Error::ArgumentError, /hostPort must be/)
31
31
  expect { subject.new(:hostPort => -1, :containerPort => 8080) }
32
- .to raise_error(Marathon::Error::ArgumentError, /hostPort must be/)
32
+ .to raise_error(Marathon::Error::ArgumentError, /hostPort must be/)
33
33
  end
34
34
  end
35
35