marathon-api 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.cane +3 -0
  3. data/.gitignore +7 -0
  4. data/.simplecov +5 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +22 -0
  8. data/README.md +91 -0
  9. data/Rakefile +34 -0
  10. data/TESTING.md +49 -0
  11. data/fixtures/marathon_docker_sample.json +14 -0
  12. data/fixtures/marathon_docker_sample_2.json +14 -0
  13. data/fixtures/vcr/Marathon/_info/returns_the_info_hash.yml +30 -0
  14. data/fixtures/vcr/Marathon/_ping/ping/.yml +35 -0
  15. data/fixtures/vcr/Marathon_App/_changes/changes_the_app.yml +57 -0
  16. data/fixtures/vcr/Marathon_App/_changes/fails_with_stange_attributes.yml +32 -0
  17. data/fixtures/vcr/Marathon_App/_delete/deletes_the_app.yml +30 -0
  18. data/fixtures/vcr/Marathon_App/_delete/fails_deleting_not_existing_app.yml +30 -0
  19. data/fixtures/vcr/Marathon_App/_get/fails_getting_not_existing_app.yml +30 -0
  20. data/fixtures/vcr/Marathon_App/_get/gets_the_app.yml +30 -0
  21. data/fixtures/vcr/Marathon_App/_list/lists_apps.yml +32 -0
  22. data/fixtures/vcr/Marathon_App/_restart/fails_restarting_not_existing_app.yml +30 -0
  23. data/fixtures/vcr/Marathon_App/_start/fails_getting_not_existing_app.yml +30 -0
  24. data/fixtures/vcr/Marathon_App/_start/starts_the_app.yml +32 -0
  25. data/fixtures/vcr/Marathon_App/_tasks/has_tasks.yml +30 -0
  26. data/fixtures/vcr/Marathon_App/_version/gets_a_version.yml +61 -0
  27. data/fixtures/vcr/Marathon_App/_versions/gets_versions.yml +32 -0
  28. data/fixtures/vcr/Marathon_Deployment/_delete/deletes_deployments.yml +61 -0
  29. data/fixtures/vcr/Marathon_Deployment/_list/lists_deployments.yml +90 -0
  30. data/fixtures/vcr/Marathon_EventSubscriptions/_list/lists_callbacks.yml +30 -0
  31. data/fixtures/vcr/Marathon_EventSubscriptions/_register/registers_callback.yml +30 -0
  32. data/fixtures/vcr/Marathon_EventSubscriptions/_unregister/unregisters_callback.yml +30 -0
  33. data/fixtures/vcr/Marathon_Leader/_delete/delete/.yml +30 -0
  34. data/fixtures/vcr/Marathon_Leader/_get/get/.yml +30 -0
  35. data/fixtures/vcr/Marathon_Queue/_list/lists_queue.yml +33 -0
  36. data/fixtures/vcr/Marathon_Task/_delete/kills_a_tasks_of_an_app.yml +57 -0
  37. data/fixtures/vcr/Marathon_Task/_delete_all/kills_all_tasks_of_an_app.yml +30 -0
  38. data/fixtures/vcr/Marathon_Task/_get/gets_tasks_of_an_app.yml +30 -0
  39. data/fixtures/vcr/Marathon_Task/_list/lists_running_tasks.yml +30 -0
  40. data/fixtures/vcr/Marathon_Task/_list/lists_tasks.yml +30 -0
  41. data/lib/marathon.rb +65 -0
  42. data/lib/marathon/app.rb +200 -0
  43. data/lib/marathon/connection.rb +97 -0
  44. data/lib/marathon/deployment.rb +60 -0
  45. data/lib/marathon/error.rb +62 -0
  46. data/lib/marathon/event_subscriptions.rb +33 -0
  47. data/lib/marathon/leader.rb +19 -0
  48. data/lib/marathon/queue.rb +36 -0
  49. data/lib/marathon/task.rb +85 -0
  50. data/lib/marathon/util.rb +35 -0
  51. data/lib/marathon/version.rb +3 -0
  52. data/marathon-api.gemspec +31 -0
  53. data/spec/marathon/app_spec.rb +334 -0
  54. data/spec/marathon/connection_spec.rb +40 -0
  55. data/spec/marathon/deployment_spec.rb +95 -0
  56. data/spec/marathon/error_spec.rb +40 -0
  57. data/spec/marathon/event_subscriptions_spec.rb +37 -0
  58. data/spec/marathon/leader_spec.rb +21 -0
  59. data/spec/marathon/marathon_spec.rb +47 -0
  60. data/spec/marathon/queue_spec.rb +62 -0
  61. data/spec/marathon/task_spec.rb +100 -0
  62. data/spec/marathon/util_spec.rb +44 -0
  63. data/spec/spec_helper.rb +34 -0
  64. metadata +271 -0
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/eventSubscriptions
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"callbackUrls":["http://localhost/events/foo"]}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:31:15 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://localhost:8080/v2/eventSubscriptions?callbackUrl=http://localhost/events/foo
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"clientIp":"10.0.2.2","callbackUrl":"http://localhost/events/foo","eventType":"subscribe_event","timestamp":"2015-03-03T18:31:14.688Z"}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:31:14 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: delete
5
+ uri: http://localhost:8080/v2/eventSubscriptions?callbackUrl=http://localhost/events/foo
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"clientIp":"10.0.2.2","callbackUrl":"http://localhost/events/foo","eventType":"unsubscribe_event","timestamp":"2015-03-03T18:31:15.066Z"}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:31:15 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: delete
5
+ uri: http://localhost:8080/v2/leader
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"message":"Leadership abdicted"}'
28
+ http_version:
29
+ recorded_at: Mon, 02 Mar 2015 10:49:28 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/leader
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"leader":"mesos:8080"}'
28
+ http_version:
29
+ recorded_at: Mon, 02 Mar 2015 10:49:28 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,33 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/queue
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - ub0r/Marathon-API 0.8.0
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Content-Type:
22
+ - application/json
23
+ Transfer-Encoding:
24
+ - chunked
25
+ Server:
26
+ - Jetty(8.y.z-SNAPSHOT)
27
+ body:
28
+ encoding: UTF-8
29
+ string: '{"queue":[{"app":{"id":"/test","cmd":"sleep 10","args":null,"user":null,"env":{},"instances":1,"cpus":0.1,"mem":32.0,"disk":0.0,"executor":"","constraints":[],"uris":[],"storeUrls":[],"ports":[10002],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":null,"healthChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1.0,"maximumOverCapacity":1.0},"labels":{},"version":"2015-03-04T16:34:16.561Z"},"count":0},{"app":{"id":"/ubuntu2","cmd":"while
30
+ sleep 10; do date -u +%T; done","args":null,"user":null,"env":{},"instances":1,"cpus":0.1,"mem":64.0,"disk":0.0,"executor":"","constraints":[],"uris":[],"storeUrls":[],"ports":[10001],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"libmesos/ubuntu","network":null,"portMappings":null,"privileged":false,"parameters":[]}},"healthChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1.0,"maximumOverCapacity":1.0},"labels":{},"version":"2015-03-04T16:34:15.691Z"},"count":0}]}'
31
+ http_version:
32
+ recorded_at: Wed, 04 Mar 2015 18:38:40 GMT
33
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,57 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/apps//ubuntu2/tasks
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"tasks":[{"appId":"/ubuntu2","id":"ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31290],"startedAt":"2015-03-03T18:07:57.097Z","stagedAt":"2015-03-03T18:07:56.457Z","version":"2015-03-03T18:07:47.581Z"}]}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:08:30 GMT
30
+ - request:
31
+ method: delete
32
+ uri: http://localhost:8080/v2/apps//ubuntu2/tasks/ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ''
36
+ headers:
37
+ Content-Type:
38
+ - application/json
39
+ Accept:
40
+ - application/json
41
+ response:
42
+ status:
43
+ code: 200
44
+ message: OK
45
+ headers:
46
+ Content-Type:
47
+ - application/json
48
+ Transfer-Encoding:
49
+ - chunked
50
+ Server:
51
+ - Jetty(8.y.z-SNAPSHOT)
52
+ body:
53
+ encoding: UTF-8
54
+ string: '{"task":{"id":"ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31290],"startedAt":"2015-03-03T18:07:57.097Z","stagedAt":"2015-03-03T18:07:56.457Z","version":"2015-03-03T18:07:47.581Z"}}'
55
+ http_version:
56
+ recorded_at: Tue, 03 Mar 2015 18:08:30 GMT
57
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: delete
5
+ uri: http://localhost:8080/v2/apps//ubuntu2/tasks
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"tasks":[{"id":"ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31290],"startedAt":"2015-03-03T18:07:57.097Z","stagedAt":"2015-03-03T18:07:56.457Z","version":"2015-03-03T18:07:47.581Z"}]}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:08:30 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/apps//ubuntu2/tasks
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"tasks":[{"appId":"/ubuntu2","id":"ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31290],"startedAt":"2015-03-03T18:07:57.097Z","stagedAt":"2015-03-03T18:07:56.457Z","version":"2015-03-03T18:07:47.581Z"}]}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:08:30 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/tasks?status=running
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"tasks":[{"appId":"/test","id":"test.482155d0-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31026],"startedAt":"2015-03-03T18:08:24.116Z","stagedAt":"2015-03-03T18:08:23.546Z","version":"2015-03-02T11:30:30.096Z","servicePorts":[10002]},{"appId":"/ubuntu2","id":"ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31290],"startedAt":"2015-03-03T18:07:57.097Z","stagedAt":"2015-03-03T18:07:56.457Z","version":"2015-03-03T18:07:47.581Z","servicePorts":[10001]}]}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:08:30 GMT
30
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8080/v2/tasks
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json
21
+ Transfer-Encoding:
22
+ - chunked
23
+ Server:
24
+ - Jetty(8.y.z-SNAPSHOT)
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"tasks":[{"appId":"/test","id":"test.482155d0-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31026],"startedAt":"2015-03-03T18:08:24.116Z","stagedAt":"2015-03-03T18:08:23.546Z","version":"2015-03-02T11:30:30.096Z","servicePorts":[10002]},{"appId":"/ubuntu2","id":"ubuntu2.37fbe1bc-c1d0-11e4-82d4-46b02d3b7f9e","host":"mesos","ports":[31290],"startedAt":"2015-03-03T18:07:57.097Z","stagedAt":"2015-03-03T18:07:56.457Z","version":"2015-03-03T18:07:47.581Z","servicePorts":[10001]}]}'
28
+ http_version:
29
+ recorded_at: Tue, 03 Mar 2015 18:08:30 GMT
30
+ recorded_with: VCR 2.9.3
data/lib/marathon.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'rubygems/package'
2
+ require 'httparty'
3
+ require 'json'
4
+ require 'uri'
5
+
6
+ # The top-level module for this gem. It's purpose is to hold global
7
+ # configuration variables that are used as defaults in other classes.
8
+ module Marathon
9
+
10
+ attr_accessor :logger
11
+
12
+ require 'marathon/util'
13
+ require 'marathon/error'
14
+ require 'marathon/connection'
15
+ require 'marathon/app'
16
+ require 'marathon/deployment'
17
+ require 'marathon/event_subscriptions'
18
+ require 'marathon/leader'
19
+ require 'marathon/queue'
20
+ require 'marathon/task'
21
+ require 'marathon/version'
22
+
23
+ DEFAULT_URL = 'http://localhost:8080'
24
+
25
+ # Get the marathon url from environment
26
+ def env_url
27
+ ENV['MARATHON_URL']
28
+ end
29
+
30
+ # Get the marathon url
31
+ def url
32
+ @url ||= env_url || DEFAULT_URL
33
+ @url
34
+ end
35
+
36
+ # Set a new url
37
+ def url=(new_url)
38
+ @url = new_url
39
+ reset_connection!
40
+ end
41
+
42
+ # Set a new connection
43
+ def connection
44
+ @connection ||= Connection.new(url)
45
+ end
46
+
47
+ # Reset the connection
48
+ def reset_connection!
49
+ @connection = nil
50
+ end
51
+
52
+ # Get information about the marathon server
53
+ def info
54
+ connection.get('/v2/info')
55
+ end
56
+
57
+ # Ping marathon
58
+ def ping
59
+ connection.get('/ping')
60
+ end
61
+
62
+ module_function :connection, :env_url, :info, :logger, :logger=,
63
+ :ping, :url, :url= ,:reset_connection!
64
+
65
+ end
@@ -0,0 +1,200 @@
1
+ # This class represents a Marathon App.
2
+ # See https://mesosphere.github.io/marathon/docs/rest-api.html#apps for full list of API's methods.
3
+ class Marathon::App
4
+
5
+ attr_reader :info, :read_only
6
+
7
+ # Create a new application object.
8
+ # ++hash++: Hash including all attributes.
9
+ # See https://mesosphere.github.io/marathon/docs/rest-api.html#post-/v2/apps for full details.
10
+ # ++read_only++: prevent actions on this application
11
+ def initialize(hash = {}, read_only = false)
12
+ @info = hash
13
+ @read_only = read_only
14
+ end
15
+
16
+ # Shortcuts for reaching attributes
17
+ %w[ id args cmd cpus disk env executor instances mem ports requirePorts
18
+ storeUris tasksRunning tasksStaged uris user version ].each do |method|
19
+ define_method(method) { |*args, &block| info[method] }
20
+ end
21
+
22
+ # Prevent actions on read only instances.
23
+ # Raises an ArgumentError when triying to change read_only instances.
24
+ def check_read_only
25
+ if read_only
26
+ raise Marathon::Error::ArgumentError, "This app is 'read only' and does not support any actions"
27
+ end
28
+ end
29
+
30
+ # List all running tasks for the application.
31
+ # Returns an Array of Task objects.
32
+ def tasks
33
+ check_read_only
34
+ unless @info['tasks']
35
+ refresh
36
+ end
37
+
38
+ raise Marathon::Error::UnexpectedResponseError, "Expected to find tasks element in app's info" unless @info['tasks']
39
+
40
+ @info['tasks'].map { |e| Marathon::Task.new(e) }
41
+ end
42
+
43
+ # List the versions of the application.
44
+ # ++version++: Get a specific versions
45
+ # Returns Array of Strings if ++version = nil++,
46
+ # else returns Hash with version information.
47
+ def versions(version = nil)
48
+ if version
49
+ self.class.version(id, version)
50
+ else
51
+ self.class.versions(id)
52
+ end
53
+ end
54
+
55
+ # Reload attributes from marathon API.
56
+ def refresh
57
+ check_read_only
58
+ new_app = self.class.get(id)
59
+ @info = new_app.info
60
+ end
61
+
62
+ # Create and start the application.
63
+ def start!
64
+ check_read_only
65
+ new_app = self.class.start(info)
66
+ @info = new_app.info
67
+ end
68
+
69
+ # Initiates a rolling restart of all running tasks of the given app.
70
+ # This call respects the configured minimumHealthCapacity.
71
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
72
+ # The current deployment can be overridden by setting the `force` query parameter.
73
+ def restart!(force = false)
74
+ check_read_only
75
+ self.class.restart(id, force)
76
+ end
77
+
78
+ # Change parameters of a running application.
79
+ # The new application parameters apply only to subsequently created tasks.
80
+ # Currently running tasks are restarted, while maintaining the minimumHealthCapacity.
81
+ # ++hash++: Hash of attributes to change.
82
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
83
+ # The current deployment can be overridden by setting the `force` query parameter.
84
+ def change!(hash, force = false)
85
+ check_read_only
86
+ self.class.change(id, hash, force)
87
+ end
88
+
89
+ # Create a new version with parameters of an old version.
90
+ # Currently running tasks are restarted, while maintaining the minimumHealthCapacity.
91
+ # ++version++: Version name of the old version.
92
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
93
+ # The current deployment can be overridden by setting the `force` query parameter.
94
+ def roll_back!(version, force = false)
95
+ change!({'version' => version}, force)
96
+ end
97
+
98
+ # Change the number of desired instances.
99
+ # ++instances++: Number of running instances.
100
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
101
+ # The current deployment can be overridden by setting the `force` query parameter.
102
+ def scale!(instances, force = false)
103
+ change!({'instances' => instances}, force)
104
+ end
105
+
106
+ # Change the number of desired instances to 0.
107
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
108
+ # The current deployment can be overridden by setting the `force` query parameter.
109
+ def suspend!(force = false)
110
+ scale!(0, force)
111
+ end
112
+
113
+ def to_s
114
+ "Marathon::App { :id => #{self.id} }"
115
+ end
116
+
117
+ # Return application as JSON formatted string.
118
+ def to_json
119
+ info.to_json
120
+ end
121
+
122
+ class << self
123
+
124
+ # List the application with id.
125
+ # ++id++: Application's id.
126
+ def get(id)
127
+ json = Marathon.connection.get("/v2/apps/#{id}")['app']
128
+ new(json)
129
+ end
130
+
131
+ # List all applications.
132
+ # ++:cmd++: Filter apps to only those whose commands contain cmd.
133
+ # ++:embed++: Embeds nested resources that match the supplied path.
134
+ # Possible values:
135
+ # "apps.tasks". Apps' tasks are not embedded in the response by default.
136
+ # "apps.failures". Apps' last failures are not embedded in the response by default.
137
+ def list(cmd = nil, embed = nil)
138
+ query = {}
139
+ query[:cmd] = cmd if cmd
140
+ Marathon::Util.add_choice(query, :embed, embed, %w[apps.tasks apps.failures])
141
+ json = Marathon.connection.get('/v2/apps', query)['apps']
142
+ json.map { |j| new(j) }
143
+ end
144
+
145
+ # Delete the application with id.
146
+ # ++id++: Application's id.
147
+ def delete(id)
148
+ Marathon.connection.delete("/v2/apps/#{id}")
149
+ end
150
+ alias :remove :delete
151
+
152
+ # Create and start an application.
153
+ # ++hash++: Hash including all attributes
154
+ # see https://mesosphere.github.io/marathon/docs/rest-api.html#post-/v2/apps for full details
155
+ def start(hash)
156
+ json = Marathon.connection.post('/v2/apps', nil, :body => hash)
157
+ new(json)
158
+ end
159
+ alias :create :start
160
+
161
+ # Restart the application with id.
162
+ # ++id++: Application's id.
163
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
164
+ # The current deployment can be overridden by setting the `force` query parameter.
165
+ def restart(id, force = false)
166
+ query = {}
167
+ query[:force] = true if force
168
+ json = Marathon.connection.post("/v2/apps/#{id}/restart", query)
169
+ # TODO parse deploymentId + version
170
+ end
171
+
172
+ # Change parameters of a running application. The new application parameters apply only to subsequently
173
+ # created tasks. Currently running tasks are restarted, while maintaining the minimumHealthCapacity.
174
+ # ++id++: Application's id.
175
+ # ++hash++: A subset of app's attributes.
176
+ # ++force++: If the app is affected by a running deployment, then the update operation will fail.
177
+ # The current deployment can be overridden by setting the `force` query parameter.
178
+ def change(id, hash, force = false)
179
+ query = {}
180
+ query[:force] = true if force
181
+ json = Marathon.connection.put("/v2/apps/#{id}", query, :body => hash)
182
+ # TODO parse deploymentId + version
183
+ end
184
+
185
+ # List the versions of the application with id.
186
+ # ++id++: Application id
187
+ def versions(id)
188
+ json = Marathon.connection.get("/v2/apps/#{id}/versions")
189
+ json['versions']
190
+ end
191
+
192
+ # List the configuration of the application with id at version.
193
+ # ++id++: Application id
194
+ # ++version++: Version name
195
+ def version(id, version)
196
+ json = Marathon.connection.get("/v2/apps/#{id}/versions/#{version}")
197
+ new(json, true)
198
+ end
199
+ end
200
+ end