cloulu 0.0.0 → 0.1.1
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.
- data/bin/{cloulu → cl} +0 -0
- data/lib/cc_api_stub/applications.rb +53 -0
- data/lib/cc_api_stub/domains.rb +16 -0
- data/lib/cc_api_stub/frameworks.rb +22 -0
- data/lib/cc_api_stub/helper.rb +131 -0
- data/lib/cc_api_stub/login.rb +21 -0
- data/lib/cc_api_stub/organization_users.rb +21 -0
- data/lib/cc_api_stub/organizations.rb +70 -0
- data/lib/cc_api_stub/routes.rb +26 -0
- data/lib/cc_api_stub/runtimes.rb +22 -0
- data/lib/cc_api_stub/service_bindings.rb +22 -0
- data/lib/cc_api_stub/service_instances.rb +22 -0
- data/lib/cc_api_stub/services.rb +25 -0
- data/lib/cc_api_stub/spaces.rb +49 -0
- data/lib/cc_api_stub/users.rb +84 -0
- data/lib/cc_api_stub.rb +17 -0
- data/lib/cfoundry/auth_token.rb +63 -0
- data/lib/cfoundry/baseclient.rb +201 -0
- data/lib/cfoundry/chatty_hash.rb +46 -0
- data/lib/cfoundry/client.rb +46 -0
- data/lib/cfoundry/concerns/login_helpers.rb +13 -0
- data/lib/cfoundry/errors.rb +160 -0
- data/lib/cfoundry/rest_client.rb +299 -0
- data/lib/cfoundry/test_support.rb +3 -0
- data/lib/cfoundry/trace_helpers.rb +40 -0
- data/lib/cfoundry/uaaclient.rb +112 -0
- data/lib/cfoundry/upload_helpers.rb +187 -0
- data/lib/cfoundry/v1/app.rb +363 -0
- data/lib/cfoundry/v1/base.rb +72 -0
- data/lib/cfoundry/v1/client.rb +193 -0
- data/lib/cfoundry/v1/framework.rb +21 -0
- data/lib/cfoundry/v1/model.rb +178 -0
- data/lib/cfoundry/v1/model_magic.rb +129 -0
- data/lib/cfoundry/v1/runtime.rb +24 -0
- data/lib/cfoundry/v1/service.rb +39 -0
- data/lib/cfoundry/v1/service_instance.rb +32 -0
- data/lib/cfoundry/v1/service_plan.rb +19 -0
- data/lib/cfoundry/v1/user.rb +22 -0
- data/lib/cfoundry/v2/app.rb +392 -0
- data/lib/cfoundry/v2/base.rb +83 -0
- data/lib/cfoundry/v2/client.rb +138 -0
- data/lib/cfoundry/v2/domain.rb +11 -0
- data/lib/cfoundry/v2/framework.rb +14 -0
- data/lib/cfoundry/v2/model.rb +148 -0
- data/lib/cfoundry/v2/model_magic.rb +449 -0
- data/lib/cfoundry/v2/organization.rb +16 -0
- data/lib/cfoundry/v2/route.rb +15 -0
- data/lib/cfoundry/v2/runtime.rb +12 -0
- data/lib/cfoundry/v2/service.rb +19 -0
- data/lib/cfoundry/v2/service_auth_token.rb +9 -0
- data/lib/cfoundry/v2/service_binding.rb +10 -0
- data/lib/cfoundry/v2/service_instance.rb +14 -0
- data/lib/cfoundry/v2/service_plan.rb +12 -0
- data/lib/cfoundry/v2/space.rb +18 -0
- data/lib/cfoundry/v2/user.rb +64 -0
- data/lib/cfoundry/validator.rb +39 -0
- data/lib/cfoundry/version.rb +4 -0
- data/lib/cfoundry/zip.rb +56 -0
- data/lib/cfoundry.rb +2 -0
- data/lib/manifests-vmc-plugin/errors.rb +21 -0
- data/lib/manifests-vmc-plugin/loader/builder.rb +34 -0
- data/lib/manifests-vmc-plugin/loader/normalizer.rb +149 -0
- data/lib/manifests-vmc-plugin/loader/resolver.rb +79 -0
- data/lib/manifests-vmc-plugin/loader.rb +31 -0
- data/lib/manifests-vmc-plugin/plugin.rb +145 -0
- data/lib/manifests-vmc-plugin/version.rb +3 -0
- data/lib/manifests-vmc-plugin.rb +313 -0
- data/lib/mothership/base.rb +99 -0
- data/lib/mothership/callbacks.rb +85 -0
- data/lib/mothership/command.rb +146 -0
- data/lib/mothership/errors.rb +38 -0
- data/lib/mothership/help/commands.rb +53 -0
- data/lib/mothership/help/printer.rb +170 -0
- data/lib/mothership/help.rb +64 -0
- data/lib/mothership/inputs.rb +189 -0
- data/lib/mothership/parser.rb +182 -0
- data/lib/mothership/version.rb +3 -0
- data/lib/mothership.rb +64 -0
- data/lib/tunnel-vmc-plugin/plugin.rb +178 -0
- data/lib/tunnel-vmc-plugin/tunnel.rb +308 -0
- data/lib/tunnel-vmc-plugin/version.rb +3 -0
- data/lib/uaa/http.rb +168 -0
- data/lib/uaa/misc.rb +121 -0
- data/lib/uaa/scim.rb +292 -0
- data/lib/uaa/token_coder.rb +196 -0
- data/lib/uaa/token_issuer.rb +255 -0
- data/lib/uaa/util.rb +235 -0
- data/lib/uaa/version.rb +19 -0
- data/lib/uaa.rb +18 -0
- data/lib/vmc/cli/app/app.rb +45 -0
- data/lib/vmc/cli/app/apps.rb +99 -0
- data/lib/vmc/cli/app/base.rb +90 -0
- data/lib/vmc/cli/app/crashes.rb +42 -0
- data/lib/vmc/cli/app/delete.rb +95 -0
- data/lib/vmc/cli/app/deprecated.rb +11 -0
- data/lib/vmc/cli/app/env.rb +78 -0
- data/lib/vmc/cli/app/files.rb +137 -0
- data/lib/vmc/cli/app/health.rb +26 -0
- data/lib/vmc/cli/app/instances.rb +53 -0
- data/lib/vmc/cli/app/logs.rb +76 -0
- data/lib/vmc/cli/app/push/create.rb +165 -0
- data/lib/vmc/cli/app/push/interactions.rb +94 -0
- data/lib/vmc/cli/app/push/sync.rb +64 -0
- data/lib/vmc/cli/app/push.rb +109 -0
- data/lib/vmc/cli/app/rename.rb +35 -0
- data/lib/vmc/cli/app/restart.rb +20 -0
- data/lib/vmc/cli/app/scale.rb +71 -0
- data/lib/vmc/cli/app/start.rb +143 -0
- data/lib/vmc/cli/app/stats.rb +67 -0
- data/lib/vmc/cli/app/stop.rb +27 -0
- data/lib/vmc/cli/help.rb +11 -0
- data/lib/vmc/cli/interactive.rb +105 -0
- data/lib/vmc/cli/route/base.rb +12 -0
- data/lib/vmc/cli/route/map.rb +82 -0
- data/lib/vmc/cli/route/routes.rb +25 -0
- data/lib/vmc/cli/route/unmap.rb +94 -0
- data/lib/vmc/cli/service/base.rb +8 -0
- data/lib/vmc/cli/service/bind.rb +44 -0
- data/lib/vmc/cli/service/create.rb +126 -0
- data/lib/vmc/cli/service/delete.rb +86 -0
- data/lib/vmc/cli/service/rename.rb +35 -0
- data/lib/vmc/cli/service/service.rb +42 -0
- data/lib/vmc/cli/service/services.rb +114 -0
- data/lib/vmc/cli/service/unbind.rb +38 -0
- data/lib/vmc/cli/start/base.rb +94 -0
- data/lib/vmc/cli/start/colors.rb +13 -0
- data/lib/vmc/cli/start/info.rb +126 -0
- data/lib/vmc/cli/start/login.rb +97 -0
- data/lib/vmc/cli/start/logout.rb +17 -0
- data/lib/vmc/cli/start/target.rb +60 -0
- data/lib/vmc/cli/start/target_interactions.rb +37 -0
- data/lib/vmc/cli/start/targets.rb +16 -0
- data/lib/vmc/cli/user/base.rb +29 -0
- data/lib/vmc/cli/user/create.rb +39 -0
- data/lib/vmc/cli/user/delete.rb +27 -0
- data/lib/vmc/cli/user/passwd.rb +50 -0
- data/lib/vmc/cli/user/register.rb +42 -0
- data/lib/vmc/cli/user/users.rb +32 -0
- data/lib/vmc/cli/v2_check_cli.rb +16 -0
- data/lib/vmc/cli.rb +474 -0
- data/lib/vmc/constants.rb +13 -0
- data/lib/vmc/detect.rb +129 -0
- data/lib/vmc/errors.rb +19 -0
- data/lib/vmc/plugin.rb +56 -0
- data/lib/vmc/spacing.rb +89 -0
- data/lib/vmc/spec_helper.rb +1 -0
- data/lib/vmc/test_support.rb +6 -0
- data/lib/vmc/version.rb +3 -0
- data/lib/vmc.rb +8 -0
- data/vendor/errors/v1.yml +189 -0
- data/vendor/errors/v2.yml +360 -0
- metadata +303 -190
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
require "tmpdir"
|
|
2
|
+
require "multi_json"
|
|
3
|
+
|
|
4
|
+
require "cfoundry/zip"
|
|
5
|
+
require "cfoundry/upload_helpers"
|
|
6
|
+
require "cfoundry/chatty_hash"
|
|
7
|
+
|
|
8
|
+
require "cfoundry/v2/model"
|
|
9
|
+
|
|
10
|
+
module CFoundry::V2
|
|
11
|
+
# Class for representing a user's application on a given target (via
|
|
12
|
+
# Client).
|
|
13
|
+
#
|
|
14
|
+
# Does not guarantee that the app exists; used for both app creation and
|
|
15
|
+
# retrieval, as the attributes are all lazily retrieved. Setting attributes
|
|
16
|
+
# does not perform any requests; use #update! to commit your changes.
|
|
17
|
+
class App < Model
|
|
18
|
+
include CFoundry::UploadHelpers
|
|
19
|
+
|
|
20
|
+
attribute :name, :string
|
|
21
|
+
attribute :production, :boolean, :default => false
|
|
22
|
+
to_one :space
|
|
23
|
+
to_one :runtime
|
|
24
|
+
to_one :framework
|
|
25
|
+
attribute :environment_json, :hash, :default => {}
|
|
26
|
+
attribute :memory, :integer, :default => 256
|
|
27
|
+
attribute :total_instances, :integer, :default => 1, :at => :instances
|
|
28
|
+
attribute :disk_quota, :integer, :default => 256
|
|
29
|
+
attribute :state, :string, :default => "STOPPED"
|
|
30
|
+
attribute :command, :string, :default => nil
|
|
31
|
+
attribute :console, :boolean, :default => false
|
|
32
|
+
attribute :buildpack, :string, :default => nil
|
|
33
|
+
to_many :service_bindings
|
|
34
|
+
to_many :routes
|
|
35
|
+
|
|
36
|
+
scoped_to_space
|
|
37
|
+
|
|
38
|
+
queryable_by :name, :space_guid, :organization_guid, :framework_guid,
|
|
39
|
+
:runtime_guid
|
|
40
|
+
|
|
41
|
+
has_summary :urls => proc { |x| self.cache[:uris] = x },
|
|
42
|
+
:running_instances => proc { |x|
|
|
43
|
+
self.cache[:running_instances] = x
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
:instances => proc { |x|
|
|
47
|
+
self.total_instances = x
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
# TODO: remove these when cc consistently returns nested hashes
|
|
51
|
+
:framework_guid => proc { |x|
|
|
52
|
+
if f = self.cache[:framework]
|
|
53
|
+
f.guid = x
|
|
54
|
+
else
|
|
55
|
+
self.framework = @client.framework(x, true)
|
|
56
|
+
end
|
|
57
|
+
},
|
|
58
|
+
:framework_name => proc { |x|
|
|
59
|
+
if f = self.cache[:framework]
|
|
60
|
+
f.name = x
|
|
61
|
+
else
|
|
62
|
+
self.framework = @client.framework(nil, true)
|
|
63
|
+
self.framework.name = x
|
|
64
|
+
end
|
|
65
|
+
},
|
|
66
|
+
:runtime_guid => proc { |x|
|
|
67
|
+
if f = self.cache[:runtime]
|
|
68
|
+
f.guid = x
|
|
69
|
+
else
|
|
70
|
+
self.runtime = @client.runtime(x, true)
|
|
71
|
+
end
|
|
72
|
+
},
|
|
73
|
+
:runtime_name => proc { |x|
|
|
74
|
+
if f = self.cache[:runtime]
|
|
75
|
+
f.name = x
|
|
76
|
+
else
|
|
77
|
+
self.runtime = @client.runtime(nil, true)
|
|
78
|
+
self.runtime.name = x
|
|
79
|
+
end
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private :environment_json
|
|
83
|
+
|
|
84
|
+
def instances
|
|
85
|
+
@client.base.instances(@guid).collect do |i, m|
|
|
86
|
+
Instance.new(self, i.to_s, @client, m)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def crashes
|
|
91
|
+
@client.base.crashes(@guid).collect do |m|
|
|
92
|
+
Instance.new(self, m[:instance], @client, m)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def stats
|
|
97
|
+
stats = {}
|
|
98
|
+
|
|
99
|
+
@client.base.stats(@guid).each do |idx, info|
|
|
100
|
+
stats[idx.to_s] = info
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
stats
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def services
|
|
107
|
+
service_bindings.collect(&:service_instance)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def env
|
|
111
|
+
CFoundry::ChattyHash.new(
|
|
112
|
+
method(:env=),
|
|
113
|
+
stringify(environment_json))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def env=(x)
|
|
117
|
+
self.environment_json = stringify(x.to_hash)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def debug_mode # TODO v2
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def uris
|
|
125
|
+
return @cache[:uris] if @cache[:uris]
|
|
126
|
+
|
|
127
|
+
routes.collect do |r|
|
|
128
|
+
"#{r.host}.#{r.domain.name}"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
alias :urls :uris
|
|
132
|
+
|
|
133
|
+
def uris=(uris)
|
|
134
|
+
raise CFoundry::Deprecated,
|
|
135
|
+
"App#uris= is invalid against V2 APIs; use add/remove_route"
|
|
136
|
+
end
|
|
137
|
+
alias :urls= :uris=
|
|
138
|
+
|
|
139
|
+
def create_routes(*uris)
|
|
140
|
+
uris.each do |uri|
|
|
141
|
+
host, domain_name = uri.split(".", 2)
|
|
142
|
+
|
|
143
|
+
domain =
|
|
144
|
+
@client.current_space.domains.find { |d|
|
|
145
|
+
d.name == domain_name
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
unless domain
|
|
149
|
+
raise CFoundry::Error, "Invalid domain '#{domain_name}'"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
route = @client.routes.find { |r|
|
|
153
|
+
r.host == host && r.domain == domain
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
unless route
|
|
157
|
+
route = @client.route
|
|
158
|
+
route.host = host
|
|
159
|
+
route.domain = domain
|
|
160
|
+
route.space = space
|
|
161
|
+
route.create!
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
add_route(route)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
alias :create_route :create_routes
|
|
168
|
+
|
|
169
|
+
def uri
|
|
170
|
+
if uris = @cache[:uris]
|
|
171
|
+
return uris.first
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
if route = routes.first
|
|
175
|
+
"#{route.host}.#{route.domain.name}"
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
alias :url :uri
|
|
179
|
+
|
|
180
|
+
def uri=(x)
|
|
181
|
+
self.uris = [x]
|
|
182
|
+
end
|
|
183
|
+
alias :url= :uri=
|
|
184
|
+
|
|
185
|
+
# Stop the application.
|
|
186
|
+
def stop!
|
|
187
|
+
self.state = "STOPPED"
|
|
188
|
+
update!
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Start the application.
|
|
192
|
+
def start!(async = false, &blk)
|
|
193
|
+
self.state = "STARTED"
|
|
194
|
+
update!(async, &blk)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Restart the application.
|
|
198
|
+
def restart!(async = false, &blk)
|
|
199
|
+
stop!
|
|
200
|
+
start!(async, &blk)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def update!(async = false)
|
|
204
|
+
response = @client.base.update_app(@guid, @diff, async)
|
|
205
|
+
|
|
206
|
+
yield response[:headers]["x-app-staging-log"] if block_given?
|
|
207
|
+
|
|
208
|
+
@manifest = @client.base.send(:parse_json, response[:body])
|
|
209
|
+
|
|
210
|
+
@diff.clear
|
|
211
|
+
|
|
212
|
+
true
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Determine application health.
|
|
216
|
+
#
|
|
217
|
+
# If all instances are running, returns "RUNNING". If only some are
|
|
218
|
+
# started, returns the precentage of them that are healthy.
|
|
219
|
+
#
|
|
220
|
+
# Otherwise, returns application's status.
|
|
221
|
+
def health
|
|
222
|
+
if state == "STARTED"
|
|
223
|
+
healthy_count = running_instances
|
|
224
|
+
expected = total_instances
|
|
225
|
+
|
|
226
|
+
if expected > 0
|
|
227
|
+
ratio = healthy_count / expected.to_f
|
|
228
|
+
if ratio == 1.0
|
|
229
|
+
"RUNNING"
|
|
230
|
+
else
|
|
231
|
+
"#{(ratio * 100).to_i}%"
|
|
232
|
+
end
|
|
233
|
+
else
|
|
234
|
+
"N/A"
|
|
235
|
+
end
|
|
236
|
+
else
|
|
237
|
+
state
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def running_instances
|
|
242
|
+
return @cache[:running_instances] if @cache[:running_instances]
|
|
243
|
+
|
|
244
|
+
running = 0
|
|
245
|
+
|
|
246
|
+
instances.each do |i|
|
|
247
|
+
running += 1 if i.state == "RUNNING"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
running
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Check that all application instances are running.
|
|
254
|
+
def healthy?
|
|
255
|
+
# invalidate cache so the check is fresh
|
|
256
|
+
invalidate!
|
|
257
|
+
health == "RUNNING"
|
|
258
|
+
end
|
|
259
|
+
alias_method :running?, :healthy?
|
|
260
|
+
|
|
261
|
+
# Is the application stopped?
|
|
262
|
+
def stopped?
|
|
263
|
+
state == "STOPPED"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Is the application started?
|
|
267
|
+
#
|
|
268
|
+
# Note that this does not imply that all instances are running. See
|
|
269
|
+
# #healthy?
|
|
270
|
+
def started?
|
|
271
|
+
state == "STARTED"
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Bind services to application.
|
|
275
|
+
def bind(*instances)
|
|
276
|
+
instances.each do |i|
|
|
277
|
+
binding = @client.service_binding
|
|
278
|
+
binding.app = self
|
|
279
|
+
binding.service_instance = i
|
|
280
|
+
binding.create!
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
self
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Unbind services from application.
|
|
287
|
+
def unbind(*instances)
|
|
288
|
+
service_bindings.each do |b|
|
|
289
|
+
if instances.include? b.service_instance
|
|
290
|
+
b.delete!
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
self
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def binds?(instance)
|
|
298
|
+
service_bindings.any? { |b|
|
|
299
|
+
b.service_instance == instance
|
|
300
|
+
}
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def files(*path)
|
|
304
|
+
Instance.new(self, "0", @client).files(*path)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def file(*path)
|
|
308
|
+
Instance.new(self, "0", @client).file(*path)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def stream_file(*path, &blk)
|
|
312
|
+
Instance.new(self, "0", @client).stream_file(*path, &blk)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
private
|
|
316
|
+
|
|
317
|
+
def stringify(hash)
|
|
318
|
+
new = {}
|
|
319
|
+
|
|
320
|
+
hash.each do |k, v|
|
|
321
|
+
new[k.to_s] = v.to_s
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
new
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
class Instance
|
|
328
|
+
attr_reader :app, :id
|
|
329
|
+
|
|
330
|
+
def initialize(app, id, client, manifest = {})
|
|
331
|
+
@app = app
|
|
332
|
+
@id = id
|
|
333
|
+
@client = client
|
|
334
|
+
@manifest = manifest
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def inspect
|
|
338
|
+
"#<App::Instance '#{@app.name}' \##@id>"
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def state
|
|
342
|
+
@manifest[:state]
|
|
343
|
+
end
|
|
344
|
+
alias_method :status, :state
|
|
345
|
+
|
|
346
|
+
def since
|
|
347
|
+
if since = @manifest[:since]
|
|
348
|
+
Time.at(@manifest[:since])
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def debugger
|
|
353
|
+
return unless @manifest[:debug_ip] and @manifest[:debug_port]
|
|
354
|
+
|
|
355
|
+
{ :ip => @manifest[:debug_ip],
|
|
356
|
+
:port => @manifest[:debug_port]
|
|
357
|
+
}
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def console
|
|
361
|
+
return unless @manifest[:console_ip] and @manifest[:console_port]
|
|
362
|
+
|
|
363
|
+
{ :ip => @manifest[:console_ip],
|
|
364
|
+
:port => @manifest[:console_port]
|
|
365
|
+
}
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def healthy?
|
|
369
|
+
case state
|
|
370
|
+
when "STARTING", "RUNNING"
|
|
371
|
+
true
|
|
372
|
+
when "DOWN", "FLAPPING"
|
|
373
|
+
false
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def files(*path)
|
|
378
|
+
@client.base.files(@app.guid, @id, *path).split("\n").collect do |entry|
|
|
379
|
+
path + [entry.split(/\s+/, 2)[0]]
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def file(*path)
|
|
384
|
+
@client.base.files(@app.guid, @id, *path)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def stream_file(*path, &blk)
|
|
388
|
+
@client.base.stream_file(@app.guid, @id, *path, &blk)
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require "multi_json"
|
|
2
|
+
|
|
3
|
+
require "cfoundry/baseclient"
|
|
4
|
+
require "cfoundry/uaaclient"
|
|
5
|
+
|
|
6
|
+
require "cfoundry/errors"
|
|
7
|
+
|
|
8
|
+
module CFoundry::V2
|
|
9
|
+
class Base < CFoundry::BaseClient
|
|
10
|
+
include BaseClientMethods
|
|
11
|
+
|
|
12
|
+
def resource_match(fingerprints)
|
|
13
|
+
put("v2", "resource_match", :content => :json, :accept => :json, :payload => fingerprints)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def upload_app(guid, zipfile = nil, resources = [])
|
|
17
|
+
payload = {}
|
|
18
|
+
payload[:resources] = MultiJson.dump(resources)
|
|
19
|
+
|
|
20
|
+
if zipfile
|
|
21
|
+
payload[:application] =
|
|
22
|
+
UploadIO.new(
|
|
23
|
+
if zipfile.is_a? File
|
|
24
|
+
zipfile
|
|
25
|
+
elsif zipfile.is_a? String
|
|
26
|
+
File.new(zipfile, "rb")
|
|
27
|
+
end,
|
|
28
|
+
"application/zip")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
put("v2", "apps", guid, "bits", :payload => payload)
|
|
32
|
+
rescue EOFError
|
|
33
|
+
retry
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def files(guid, instance, *path)
|
|
37
|
+
get("v2", "apps", guid, "instances", instance, "files", *path)
|
|
38
|
+
end
|
|
39
|
+
alias :file :files
|
|
40
|
+
|
|
41
|
+
def stream_file(guid, instance, *path, &blk)
|
|
42
|
+
path_and_options = path + [{:return_response => true, :follow_redirects => false}]
|
|
43
|
+
redirect = get("v2", "apps", guid, "instances", instance, "files", *path_and_options)
|
|
44
|
+
|
|
45
|
+
if location = redirect[:headers]["location"]
|
|
46
|
+
stream_url(location + "&tail", &blk)
|
|
47
|
+
else
|
|
48
|
+
yield redirect[:body]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def instances(guid)
|
|
53
|
+
get("v2", "apps", guid, "instances", :accept => :json)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def crashes(guid)
|
|
57
|
+
get("v2", "apps", guid, "crashes", :accept => :json)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def stats(guid)
|
|
61
|
+
get("v2", "apps", guid, "stats", :accept => :json)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def update_app(guid, diff, async = false)
|
|
65
|
+
put("v2", "apps", guid,
|
|
66
|
+
:content => :json,
|
|
67
|
+
:payload => diff,
|
|
68
|
+
:return_response => true,
|
|
69
|
+
:params => { :stage_async => !!async })
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def all_pages(paginated)
|
|
73
|
+
payload = paginated[:resources]
|
|
74
|
+
|
|
75
|
+
while next_page = paginated[:next_url]
|
|
76
|
+
paginated = get(next_page, :accept => :json)
|
|
77
|
+
payload += paginated[:resources]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
payload
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require File.expand_path("../../concerns/login_helpers", __FILE__)
|
|
2
|
+
|
|
3
|
+
module CFoundry::V2
|
|
4
|
+
# The primary API entrypoint. Wraps a BaseClient to provide nicer return
|
|
5
|
+
# values. Initialize with the target and, optionally, an auth token. These
|
|
6
|
+
# are the only two internal states.
|
|
7
|
+
class Client
|
|
8
|
+
include ClientMethods, CFoundry::LoginHelpers
|
|
9
|
+
|
|
10
|
+
# Internal BaseClient instance. Normally won't be touching this.
|
|
11
|
+
attr_reader :base
|
|
12
|
+
|
|
13
|
+
# [Organization] Currently targeted organization.
|
|
14
|
+
attr_accessor :current_organization
|
|
15
|
+
|
|
16
|
+
# [Space] Currently targeted space.
|
|
17
|
+
attr_accessor :current_space
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Create a new Client for interfacing with the given target.
|
|
21
|
+
#
|
|
22
|
+
# A token may also be provided to skip the login step.
|
|
23
|
+
def initialize(target = "http://api.cloudfoundry.com", token = nil)
|
|
24
|
+
@base = Base.new(target, token)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def version
|
|
28
|
+
2
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# The current target URL of the client.
|
|
32
|
+
def target
|
|
33
|
+
@base.target
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Current authentication token.
|
|
37
|
+
def token
|
|
38
|
+
@base.token
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Set the authentication token.
|
|
42
|
+
def token=(token)
|
|
43
|
+
@base.token = token
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Current proxy user. Usually nil.
|
|
47
|
+
def proxy
|
|
48
|
+
@base.proxy
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Set the proxy user for the client. Must be authorized as an
|
|
52
|
+
# administrator for this to have any effect.
|
|
53
|
+
def proxy=(email)
|
|
54
|
+
@base.proxy = email
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Is the client tracing API requests?
|
|
58
|
+
def trace
|
|
59
|
+
@base.trace
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Set the tracing flag; if true, API requests and responses will be
|
|
63
|
+
# printed out.
|
|
64
|
+
def trace=(bool)
|
|
65
|
+
@base.trace = bool
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# The current log. See +log=+.
|
|
69
|
+
def log
|
|
70
|
+
@base.log
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Set the logging mode. Mode can be one of:
|
|
74
|
+
#
|
|
75
|
+
# [+String+] Name of a file to log the last 10 requests to.
|
|
76
|
+
# [+Array+] Array to append with log data (a Hash).
|
|
77
|
+
# [+IO+] An IO object to write to.
|
|
78
|
+
# [+false+] No logging.
|
|
79
|
+
def log=(mode)
|
|
80
|
+
@base.log = mode
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# The currently authenticated user.
|
|
84
|
+
def current_user
|
|
85
|
+
return unless token
|
|
86
|
+
|
|
87
|
+
token_data = @base.token.token_data
|
|
88
|
+
if guid = token_data[:user_id]
|
|
89
|
+
user = user(guid)
|
|
90
|
+
user.emails = [{ :value => token_data[:email] }]
|
|
91
|
+
user
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Cloud metadata
|
|
96
|
+
def info
|
|
97
|
+
@base.info
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def login(username, password)
|
|
101
|
+
@current_organization = nil
|
|
102
|
+
@current_space = nil
|
|
103
|
+
super
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def register(email, password)
|
|
107
|
+
uaa_user = @base.uaa.add_user(email, password)
|
|
108
|
+
cc_user = user
|
|
109
|
+
cc_user.guid = uaa_user['id']
|
|
110
|
+
cc_user.create!
|
|
111
|
+
cc_user
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Clear client token. No requests are made for this.
|
|
115
|
+
def logout
|
|
116
|
+
@base.token = nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Is an authentication token set on the client?
|
|
120
|
+
def logged_in?
|
|
121
|
+
!!@base.token
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def query_target(klass)
|
|
125
|
+
if klass.scoped_space && space = current_space
|
|
126
|
+
space
|
|
127
|
+
elsif klass.scoped_organization && org = current_organization
|
|
128
|
+
org
|
|
129
|
+
else
|
|
130
|
+
self
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def stream_url(url, &blk)
|
|
135
|
+
@base.stream_url(url, &blk)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require "cfoundry/v2/model"
|
|
2
|
+
|
|
3
|
+
module CFoundry::V2
|
|
4
|
+
class Domain < Model
|
|
5
|
+
attribute :name, :string
|
|
6
|
+
attribute :wildcard, :boolean
|
|
7
|
+
to_one :owning_organization, :as => :organization, :default => nil
|
|
8
|
+
|
|
9
|
+
queryable_by :name, :owning_organization_guid, :space_guid
|
|
10
|
+
end
|
|
11
|
+
end
|