pbox 1.17.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +11 -0
- data/README.md +40 -0
- data/Rakefile +6 -0
- data/autocomplete/pbox_bash +1639 -0
- data/bin/pbox +37 -0
- data/conf/protonbox.conf +8 -0
- data/features/assets/deploy.tar.gz +0 -0
- data/features/core_feature.rb +178 -0
- data/features/deployments_feature.rb +127 -0
- data/features/domains_feature.rb +49 -0
- data/features/keys_feature.rb +37 -0
- data/features/members_feature.rb +166 -0
- data/lib/rhc/auth/basic.rb +64 -0
- data/lib/rhc/auth/token.rb +102 -0
- data/lib/rhc/auth/token_store.rb +53 -0
- data/lib/rhc/auth.rb +5 -0
- data/lib/rhc/autocomplete.rb +66 -0
- data/lib/rhc/autocomplete_templates/bash.erb +39 -0
- data/lib/rhc/cartridge_helpers.rb +118 -0
- data/lib/rhc/cli.rb +40 -0
- data/lib/rhc/command_runner.rb +186 -0
- data/lib/rhc/commands/account.rb +25 -0
- data/lib/rhc/commands/alias.rb +124 -0
- data/lib/rhc/commands/app.rb +701 -0
- data/lib/rhc/commands/apps.rb +20 -0
- data/lib/rhc/commands/authorization.rb +96 -0
- data/lib/rhc/commands/base.rb +174 -0
- data/lib/rhc/commands/cartridge.rb +326 -0
- data/lib/rhc/commands/deployment.rb +82 -0
- data/lib/rhc/commands/domain.rb +167 -0
- data/lib/rhc/commands/env.rb +142 -0
- data/lib/rhc/commands/git_clone.rb +29 -0
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/member.rb +148 -0
- data/lib/rhc/commands/port_forward.rb +197 -0
- data/lib/rhc/commands/server.rb +40 -0
- data/lib/rhc/commands/setup.rb +60 -0
- data/lib/rhc/commands/snapshot.rb +137 -0
- data/lib/rhc/commands/ssh.rb +51 -0
- data/lib/rhc/commands/sshkey.rb +97 -0
- data/lib/rhc/commands/tail.rb +47 -0
- data/lib/rhc/commands/threaddump.rb +14 -0
- data/lib/rhc/commands.rb +396 -0
- data/lib/rhc/config.rb +320 -0
- data/lib/rhc/context_helper.rb +121 -0
- data/lib/rhc/core_ext.rb +202 -0
- data/lib/rhc/coverage_helper.rb +33 -0
- data/lib/rhc/deployment_helpers.rb +88 -0
- data/lib/rhc/exceptions.rb +232 -0
- data/lib/rhc/git_helpers.rb +91 -0
- data/lib/rhc/help_formatter.rb +55 -0
- data/lib/rhc/helpers.rb +477 -0
- data/lib/rhc/highline_extensions.rb +479 -0
- data/lib/rhc/json.rb +51 -0
- data/lib/rhc/output_helpers.rb +260 -0
- data/lib/rhc/rest/activation.rb +11 -0
- data/lib/rhc/rest/alias.rb +42 -0
- data/lib/rhc/rest/api.rb +87 -0
- data/lib/rhc/rest/application.rb +332 -0
- data/lib/rhc/rest/attributes.rb +36 -0
- data/lib/rhc/rest/authorization.rb +8 -0
- data/lib/rhc/rest/base.rb +79 -0
- data/lib/rhc/rest/cartridge.rb +154 -0
- data/lib/rhc/rest/client.rb +650 -0
- data/lib/rhc/rest/deployment.rb +18 -0
- data/lib/rhc/rest/domain.rb +98 -0
- data/lib/rhc/rest/environment_variable.rb +15 -0
- data/lib/rhc/rest/gear_group.rb +16 -0
- data/lib/rhc/rest/httpclient.rb +145 -0
- data/lib/rhc/rest/key.rb +44 -0
- data/lib/rhc/rest/membership.rb +105 -0
- data/lib/rhc/rest/mock.rb +1024 -0
- data/lib/rhc/rest/user.rb +32 -0
- data/lib/rhc/rest.rb +148 -0
- data/lib/rhc/ssh_helpers.rb +378 -0
- data/lib/rhc/tar_gz.rb +51 -0
- data/lib/rhc/usage_templates/command_help.erb +51 -0
- data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
- data/lib/rhc/usage_templates/help.erb +35 -0
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/usage_templates/options_help.erb +12 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/vendor/sshkey.rb +253 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/version.rb +5 -0
- data/lib/rhc/wizard.rb +633 -0
- data/lib/rhc.rb +34 -0
- data/spec/coverage_helper.rb +89 -0
- data/spec/direct_execution_helper.rb +338 -0
- data/spec/keys/example.pem +23 -0
- data/spec/keys/example_private.pem +27 -0
- data/spec/keys/server.pem +19 -0
- data/spec/rest_spec_helper.rb +31 -0
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/assets/env_vars.txt +7 -0
- data/spec/rhc/assets/env_vars_2.txt +1 -0
- data/spec/rhc/assets/foo.txt +1 -0
- data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
- data/spec/rhc/assets/targz_sample.tar.gz +0 -0
- data/spec/rhc/auth_spec.rb +442 -0
- data/spec/rhc/cli_spec.rb +188 -0
- data/spec/rhc/command_spec.rb +435 -0
- data/spec/rhc/commands/account_spec.rb +42 -0
- data/spec/rhc/commands/alias_spec.rb +333 -0
- data/spec/rhc/commands/app_spec.rb +754 -0
- data/spec/rhc/commands/apps_spec.rb +39 -0
- data/spec/rhc/commands/authorization_spec.rb +145 -0
- data/spec/rhc/commands/cartridge_spec.rb +641 -0
- data/spec/rhc/commands/deployment_spec.rb +286 -0
- data/spec/rhc/commands/domain_spec.rb +383 -0
- data/spec/rhc/commands/env_spec.rb +493 -0
- data/spec/rhc/commands/git_clone_spec.rb +80 -0
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/member_spec.rb +228 -0
- data/spec/rhc/commands/port_forward_spec.rb +217 -0
- data/spec/rhc/commands/server_spec.rb +69 -0
- data/spec/rhc/commands/setup_spec.rb +118 -0
- data/spec/rhc/commands/snapshot_spec.rb +179 -0
- data/spec/rhc/commands/ssh_spec.rb +163 -0
- data/spec/rhc/commands/sshkey_spec.rb +188 -0
- data/spec/rhc/commands/tail_spec.rb +81 -0
- data/spec/rhc/commands/threaddump_spec.rb +84 -0
- data/spec/rhc/config_spec.rb +407 -0
- data/spec/rhc/helpers_spec.rb +524 -0
- data/spec/rhc/highline_extensions_spec.rb +314 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/rest_application_spec.rb +248 -0
- data/spec/rhc/rest_client_spec.rb +752 -0
- data/spec/rhc/rest_spec.rb +740 -0
- data/spec/rhc/targz_spec.rb +55 -0
- data/spec/rhc/wizard_spec.rb +756 -0
- data/spec/spec_helper.rb +575 -0
- data/spec/wizard_spec_helper.rb +330 -0
- metadata +435 -0
@@ -0,0 +1,332 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module RHC
|
4
|
+
module Rest
|
5
|
+
class Application < Base
|
6
|
+
include Membership
|
7
|
+
|
8
|
+
define_attr :domain_id, :name, :creation_time, :uuid,
|
9
|
+
:git_url, :app_url, :gear_profile, :framework,
|
10
|
+
:scalable, :health_check_path, :embedded, :gear_count,
|
11
|
+
:ssh_url, :building_app, :cartridges, :initial_git_url,
|
12
|
+
:auto_deploy, :deployment_branch, :deployment_type, :keep_deployments, :deployments
|
13
|
+
alias_method :domain_name, :domain_id
|
14
|
+
|
15
|
+
# Query helper to say consistent with cartridge
|
16
|
+
def scalable?
|
17
|
+
scalable
|
18
|
+
end
|
19
|
+
|
20
|
+
def id
|
21
|
+
attributes['id'] || uuid
|
22
|
+
end
|
23
|
+
|
24
|
+
def domain
|
25
|
+
domain_id
|
26
|
+
end
|
27
|
+
|
28
|
+
def scalable_carts
|
29
|
+
return [] unless scalable?
|
30
|
+
carts = cartridges.select(&:scalable?)
|
31
|
+
scales_with = carts.map(&:scales_with)
|
32
|
+
carts.delete_if{|x| scales_with.include?(x.name)}
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_cartridge(cart, options={})
|
36
|
+
debug "Adding cartridge #{name}"
|
37
|
+
clear_attribute :cartridges
|
38
|
+
cart =
|
39
|
+
if cart.is_a? String
|
40
|
+
{:name => cart}
|
41
|
+
elsif cart.respond_to? :[]
|
42
|
+
cart
|
43
|
+
else
|
44
|
+
c = cart.url ? {:url => cart.url} : {:name => cart.name}
|
45
|
+
if cart.respond_to?(:environment_variables) && cart.environment_variables.present?
|
46
|
+
c[:environment_variables] = cart.environment_variables
|
47
|
+
end
|
48
|
+
if cart.respond_to?(:gear_size) && cart.gear_size.present?
|
49
|
+
c[:gear_size] = cart.gear_size
|
50
|
+
end
|
51
|
+
cart = c
|
52
|
+
end
|
53
|
+
|
54
|
+
if cart.respond_to?(:[]) and cart[:url] and !has_param?('ADD_CARTRIDGE', 'url')
|
55
|
+
raise RHC::Rest::DownloadingCartridgesNotSupported, "The server does not support downloading cartridges."
|
56
|
+
end
|
57
|
+
|
58
|
+
rest_method(
|
59
|
+
"ADD_CARTRIDGE",
|
60
|
+
cart,
|
61
|
+
options
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def cartridges
|
66
|
+
@cartridges ||=
|
67
|
+
unless (carts = attributes['cartridges']).nil?
|
68
|
+
carts.map{|x| Cartridge.new(x, client) }
|
69
|
+
else
|
70
|
+
debug "Getting all cartridges for application #{name}"
|
71
|
+
rest_method "LIST_CARTRIDGES"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def gear_info
|
76
|
+
{ :gear_count => gear_count, :gear_profile => gear_profile } unless gear_count.nil?
|
77
|
+
end
|
78
|
+
|
79
|
+
def gear_groups
|
80
|
+
debug "Getting all gear groups for application #{name}"
|
81
|
+
rest_method "GET_GEAR_GROUPS"
|
82
|
+
end
|
83
|
+
|
84
|
+
def gears
|
85
|
+
gear_groups.map{ |group| group.gears }.flatten
|
86
|
+
end
|
87
|
+
|
88
|
+
def gear_ssh_url(gear_id)
|
89
|
+
gear = gears.find{ |g| g['id'] == gear_id }
|
90
|
+
|
91
|
+
raise ArgumentError, "Gear #{gear_id} not found" if gear.nil?
|
92
|
+
gear['ssh_url'] or raise NoPerGearOperations
|
93
|
+
end
|
94
|
+
|
95
|
+
def tidy
|
96
|
+
debug "Starting application #{name}"
|
97
|
+
rest_method 'TIDY', :event => "tidy"
|
98
|
+
end
|
99
|
+
|
100
|
+
def start
|
101
|
+
debug "Starting application #{name}"
|
102
|
+
rest_method 'START', :event => "start"
|
103
|
+
end
|
104
|
+
|
105
|
+
def stop(force=false)
|
106
|
+
debug "Stopping application #{name} force-#{force}"
|
107
|
+
|
108
|
+
if force
|
109
|
+
payload = {:event=> "force-stop"}
|
110
|
+
else
|
111
|
+
payload = {:event=> "stop"}
|
112
|
+
end
|
113
|
+
|
114
|
+
rest_method "STOP", payload
|
115
|
+
end
|
116
|
+
|
117
|
+
def restart
|
118
|
+
debug "Restarting application #{name}"
|
119
|
+
rest_method "RESTART", :event => "restart"
|
120
|
+
end
|
121
|
+
|
122
|
+
def destroy
|
123
|
+
debug "Deleting application #{name}"
|
124
|
+
rest_method "DELETE"
|
125
|
+
end
|
126
|
+
alias :delete :destroy
|
127
|
+
|
128
|
+
def reload
|
129
|
+
debug "Reload application #{name}"
|
130
|
+
rest_method "RELOAD", :event => "reload"
|
131
|
+
end
|
132
|
+
|
133
|
+
def threaddump
|
134
|
+
debug "Running thread dump for #{name}"
|
135
|
+
rest_method "THREAD_DUMP", :event => "thread-dump"
|
136
|
+
end
|
137
|
+
|
138
|
+
def environment_variables
|
139
|
+
debug "Getting all environment variables for application #{name}"
|
140
|
+
if supports? "LIST_ENVIRONMENT_VARIABLES"
|
141
|
+
rest_method "LIST_ENVIRONMENT_VARIABLES"
|
142
|
+
else
|
143
|
+
raise RHC::EnvironmentVariablesNotSupportedException.new
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def find_environment_variable(env_var_name)
|
148
|
+
find_environment_variables(env_var_name).first
|
149
|
+
end
|
150
|
+
|
151
|
+
def find_environment_variables(env_var_names=nil)
|
152
|
+
return environment_variables if env_var_names.nil?
|
153
|
+
env_var_names = [env_var_names].flatten
|
154
|
+
debug "Finding environment variable(s) #{env_var_names.inspect} in app #{@name}"
|
155
|
+
env_vars = environment_variables.select { |item| env_var_names.include? item.name }
|
156
|
+
raise RHC::EnvironmentVariableNotFoundException.new("Environment variable(s) #{env_var_names.join(', ')} can't be found in application #{name}.") if env_vars.empty?
|
157
|
+
env_vars
|
158
|
+
end
|
159
|
+
|
160
|
+
# @param [Array<RHC::Rest::EnvironmentVariable>] Array of RHC::Rest::EnvironmentVariable to be set
|
161
|
+
def set_environment_variables(env_vars=[])
|
162
|
+
debug "Adding environment variable(s) #{env_vars.inspect} for #{name}"
|
163
|
+
if supports? "SET_UNSET_ENVIRONMENT_VARIABLES"
|
164
|
+
rest_method "SET_UNSET_ENVIRONMENT_VARIABLES", :environment_variables => env_vars.map{|item| item.to_hash}
|
165
|
+
else
|
166
|
+
raise RHC::EnvironmentVariablesNotSupportedException.new
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# @param [Array<String>] Array of env var names like ['FOO', 'BAR']
|
171
|
+
def unset_environment_variables(env_vars=[])
|
172
|
+
debug "Removing environment variable(s) #{env_vars.inspect} for #{name}"
|
173
|
+
if supports? "SET_UNSET_ENVIRONMENT_VARIABLES"
|
174
|
+
rest_method "SET_UNSET_ENVIRONMENT_VARIABLES", :environment_variables => env_vars.map{|item| {:name => item}}
|
175
|
+
else
|
176
|
+
raise RHC::EnvironmentVariablesNotSupportedException.new
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def supports_add_cartridge_with_env_vars?
|
181
|
+
has_param?('ADD_CARTRIDGE', 'environment_variables')
|
182
|
+
end
|
183
|
+
|
184
|
+
def supports_add_cartridge_with_gear_size?
|
185
|
+
has_param?('ADD_CARTRIDGE', 'gear_size')
|
186
|
+
end
|
187
|
+
|
188
|
+
def deployments
|
189
|
+
debug "Listing deployments for application #{name}"
|
190
|
+
raise RHC::DeploymentsNotSupportedException if !supports? "LIST_DEPLOYMENTS"
|
191
|
+
rest_method("LIST_DEPLOYMENTS").sort
|
192
|
+
end
|
193
|
+
|
194
|
+
def deployment_activations
|
195
|
+
items = []
|
196
|
+
|
197
|
+
# building an array of activations with their deployments
|
198
|
+
deployments.each do |deployment|
|
199
|
+
deployment.activations.each do |activation|
|
200
|
+
items << {:activation => activation, :deployment => deployment}
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
items.sort! {|a,b| a[:activation].created_at <=> b[:activation].created_at }
|
205
|
+
|
206
|
+
first_activation = {}
|
207
|
+
|
208
|
+
items.each do |item|
|
209
|
+
deployment = item[:deployment]
|
210
|
+
activation = item[:activation]
|
211
|
+
|
212
|
+
# set the currently active (last activation by date)
|
213
|
+
item[:active] = item == items.last
|
214
|
+
|
215
|
+
# mark rollbacks (activations whose deployment had previous activations)
|
216
|
+
if rollback_to = first_activation[deployment.id]
|
217
|
+
item[:rollback] = true
|
218
|
+
item[:rollback_to] = rollback_to
|
219
|
+
# mark rolled back (all in between a rollback and its original deployment)
|
220
|
+
items.each {|i| i[:rolled_back] = true if i[:activation].created_at > rollback_to && i[:activation].created_at < activation.created_at }
|
221
|
+
else
|
222
|
+
first_activation[deployment.id] = activation.created_at
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
items
|
228
|
+
end
|
229
|
+
|
230
|
+
def configure(options={})
|
231
|
+
debug "Running update for #{name} with options #{options.inspect}"
|
232
|
+
if supports? "UPDATE"
|
233
|
+
rest_method "UPDATE", options
|
234
|
+
else
|
235
|
+
raise RHC::DeploymentsNotSupportedException
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def add_alias(app_alias)
|
240
|
+
debug "Running add_alias for #{name}"
|
241
|
+
rest_method "ADD_ALIAS", :event => "add-alias", :alias => app_alias
|
242
|
+
end
|
243
|
+
|
244
|
+
def remove_alias(app_alias)
|
245
|
+
debug "Running remove_alias for #{name}"
|
246
|
+
if (client.api_version_negotiated >= 1.4)
|
247
|
+
find_alias(app_alias).destroy
|
248
|
+
else
|
249
|
+
rest_method "REMOVE_ALIAS", :event => "remove-alias", :alias => app_alias
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def aliases
|
254
|
+
debug "Getting all aliases for application #{name}"
|
255
|
+
@aliases ||= begin
|
256
|
+
aliases = attributes['aliases']
|
257
|
+
if aliases.nil? or not aliases.is_a?(Array)
|
258
|
+
supports?('LIST_ALIASES') ? rest_method("LIST_ALIASES") : []
|
259
|
+
else
|
260
|
+
aliases.map do |a|
|
261
|
+
Alias.new(a.is_a?(String) ? {'id' => a} : a, client)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def find_alias(name, options={})
|
268
|
+
debug "Finding alias #{name} in app #{@name}"
|
269
|
+
|
270
|
+
if name.is_a?(Hash)
|
271
|
+
options = name
|
272
|
+
name = options[:name]
|
273
|
+
end
|
274
|
+
aliases.each { |a| return a if a.is_a?(String) || a.id == name.downcase }
|
275
|
+
raise RHC::AliasNotFoundException.new("Alias #{name} can't be found in application #{@name}.")
|
276
|
+
end
|
277
|
+
|
278
|
+
#Find Cartridge by name
|
279
|
+
def find_cartridge(sought, options={})
|
280
|
+
debug "Finding cartridge #{sought} in app #{name}"
|
281
|
+
|
282
|
+
type = options[:type]
|
283
|
+
|
284
|
+
cartridges.each { |cart| return cart if cart.name == sought and (type.nil? or cart.type == type) }
|
285
|
+
|
286
|
+
suggested_msg = ""
|
287
|
+
valid_cartridges = cartridges.select {|c| type.nil? or c.type == type}
|
288
|
+
unless valid_cartridges.empty?
|
289
|
+
suggested_msg = "\n\nValid cartridges:"
|
290
|
+
valid_cartridges.each { |cart| suggested_msg += "\n#{cart.name}" }
|
291
|
+
end
|
292
|
+
raise RHC::CartridgeNotFoundException.new("Cartridge #{sought} can't be found in application #{name}.#{suggested_msg}")
|
293
|
+
end
|
294
|
+
|
295
|
+
#Find Cartridges by name or regex
|
296
|
+
def find_cartridges(name, options={})
|
297
|
+
if name.is_a?(Hash)
|
298
|
+
options = name
|
299
|
+
name = options[:name]
|
300
|
+
end
|
301
|
+
|
302
|
+
type = options[:type]
|
303
|
+
regex = options[:regex]
|
304
|
+
debug "Finding cartridge #{name || regex} in app #{@name}"
|
305
|
+
|
306
|
+
filtered = Array.new
|
307
|
+
cartridges.each do |cart|
|
308
|
+
if regex
|
309
|
+
filtered.push(cart) if cart.name.match(/(?i:#{regex})/) and (type.nil? or cart.type == type)
|
310
|
+
else
|
311
|
+
filtered.push(cart) if cart.name.downcase == name.downcase and (type.nil? or cart.type == type)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
filtered
|
315
|
+
end
|
316
|
+
|
317
|
+
def host
|
318
|
+
@host ||= URI.parse(app_url).host rescue nil
|
319
|
+
end
|
320
|
+
|
321
|
+
def ssh_string
|
322
|
+
RHC::Helpers.ssh_string(ssh_url)
|
323
|
+
end
|
324
|
+
|
325
|
+
def <=>(other)
|
326
|
+
c = name.downcase <=> other.name.downcase
|
327
|
+
return c unless c == 0
|
328
|
+
domain_id <=> other.domain_id
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RHC::Rest::Attributes
|
2
|
+
def attributes
|
3
|
+
@attributes
|
4
|
+
end
|
5
|
+
|
6
|
+
def attributes=(attr=nil)
|
7
|
+
@attributes = (attr || {}).stringify_keys!
|
8
|
+
end
|
9
|
+
|
10
|
+
def attribute(name)
|
11
|
+
instance_variable_get("@#{name}") || attributes[name.to_s]
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear_attribute(name)
|
15
|
+
v = instance_variable_set("@#{name}", nil)
|
16
|
+
attributes.delete(name.to_s) or v
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module RHC::Rest::AttributesClass
|
21
|
+
def define_attr(*names)
|
22
|
+
names.map(&:to_sym).each do |name|
|
23
|
+
define_method(name) do
|
24
|
+
attribute(name)
|
25
|
+
end
|
26
|
+
define_method("#{name}=") do |value|
|
27
|
+
instance_variable_set(:"@#{name}", nil)
|
28
|
+
attributes[name.to_s] = value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def model_name
|
34
|
+
name.split("::").last
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module RHC
|
4
|
+
module Rest
|
5
|
+
class Base
|
6
|
+
include Attributes
|
7
|
+
extend AttributesClass
|
8
|
+
|
9
|
+
define_attr :messages
|
10
|
+
|
11
|
+
def initialize(attrs=nil, client=nil)
|
12
|
+
@attributes = (attrs || {}).stringify_keys!
|
13
|
+
@attributes['messages'] ||= []
|
14
|
+
@client = client
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_message(msg)
|
18
|
+
messages << msg
|
19
|
+
end
|
20
|
+
|
21
|
+
def rest_method(link_name, payload={}, options={})
|
22
|
+
link = link(link_name)
|
23
|
+
raise "No link defined for #{link_name}" unless link
|
24
|
+
url = link['href']
|
25
|
+
url = url.gsub(/:\w+/) { |s| CGI.escape(options[:params][s]) || s } if options[:params]
|
26
|
+
method = options[:method] || link['method']
|
27
|
+
|
28
|
+
result = client.request(options.merge({
|
29
|
+
:url => url,
|
30
|
+
:method => method,
|
31
|
+
:payload => payload,
|
32
|
+
}))
|
33
|
+
if result.is_a?(Hash) && (result['messages'] || result['errors'])
|
34
|
+
attributes['messages'] = Array(result['messages'])
|
35
|
+
result = self
|
36
|
+
end
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
def links
|
41
|
+
attributes['links'] || {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def supports?(sym)
|
45
|
+
!!link(sym)
|
46
|
+
end
|
47
|
+
|
48
|
+
def has_param?(sym, name)
|
49
|
+
if l = link(sym)
|
50
|
+
(l['required_params'] || []).any?{ |p| p['name'] == name} or (l['optional_params'] || []).any?{ |p| p['name'] == name}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def link_href(sym, params=nil, resource=nil, &block)
|
55
|
+
if (l = link(sym)) && (h = l['href'])
|
56
|
+
h = h.gsub(/:\w+/){ |s| params[s].nil? ? s : CGI.escape(params[s]) } if params
|
57
|
+
h = "#{h}/#{resource}" if resource
|
58
|
+
return h
|
59
|
+
end
|
60
|
+
yield if block_given?
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
attr_reader :client
|
65
|
+
|
66
|
+
def link(sym)
|
67
|
+
(links[sym.to_s] || links[sym.to_s.upcase])
|
68
|
+
end
|
69
|
+
|
70
|
+
def debug(msg, obj=nil)
|
71
|
+
client.debug("#{msg}#{obj ? " #{obj}" : ''}") if client && client.debug?
|
72
|
+
end
|
73
|
+
|
74
|
+
def debug?
|
75
|
+
client && client.debug?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module RHC
|
2
|
+
module Rest
|
3
|
+
class Cartridge < Base
|
4
|
+
HIDDEN_TAGS = [:framework, :web_framework, :cartridge].map(&:to_s)
|
5
|
+
|
6
|
+
define_attr :type, :name, :display_name, :properties, :gear_profile, :status_messages, :scales_to, :scales_from, :scales_with,
|
7
|
+
:current_scale, :supported_scales_to, :supported_scales_from, :tags, :description, :collocated_with, :base_gear_storage,
|
8
|
+
:additional_gear_storage, :url, :environment_variables, :gear_size
|
9
|
+
|
10
|
+
def scalable?
|
11
|
+
supported_scales_to != supported_scales_from
|
12
|
+
end
|
13
|
+
|
14
|
+
def custom?
|
15
|
+
url.present?
|
16
|
+
end
|
17
|
+
|
18
|
+
def only_in_new?
|
19
|
+
type == 'standalone'
|
20
|
+
end
|
21
|
+
|
22
|
+
def only_in_existing?
|
23
|
+
type == 'embedded'
|
24
|
+
end
|
25
|
+
|
26
|
+
def shares_gears?
|
27
|
+
Array(collocated_with).present?
|
28
|
+
end
|
29
|
+
def collocated_with
|
30
|
+
Array(attribute(:collocated_with))
|
31
|
+
end
|
32
|
+
|
33
|
+
def tags
|
34
|
+
Array(attribute(:tags))
|
35
|
+
end
|
36
|
+
|
37
|
+
def gear_storage
|
38
|
+
(base_gear_storage + additional_gear_storage) * 1024 * 1024 * 1024
|
39
|
+
end
|
40
|
+
|
41
|
+
def additional_gear_storage
|
42
|
+
attribute(:additional_gear_storage).to_i rescue 0
|
43
|
+
end
|
44
|
+
|
45
|
+
def display_name
|
46
|
+
attribute(:display_name) || name || url_basename
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Use this value when the user should interact with this cart via CLI arguments
|
51
|
+
#
|
52
|
+
def short_name
|
53
|
+
name || url
|
54
|
+
end
|
55
|
+
|
56
|
+
def usage_rate?
|
57
|
+
rate = usage_rate
|
58
|
+
rate && rate > 0.0
|
59
|
+
end
|
60
|
+
|
61
|
+
def usage_rate
|
62
|
+
rate = attribute(:usage_rate_usd)
|
63
|
+
|
64
|
+
if attribute(:usage_rates)
|
65
|
+
rate ||= attribute(:usage_rates).inject(0) { |total, rate| total + rate['usd'].to_f }
|
66
|
+
end
|
67
|
+
|
68
|
+
rate.to_f rescue 0.0
|
69
|
+
end
|
70
|
+
|
71
|
+
def scaling
|
72
|
+
{
|
73
|
+
:current_scale => current_scale,
|
74
|
+
:scales_from => scales_from,
|
75
|
+
:scales_to => scales_to,
|
76
|
+
:gear_profile => gear_profile,
|
77
|
+
} if scalable?
|
78
|
+
end
|
79
|
+
|
80
|
+
def property(type, key)
|
81
|
+
key, type = key.to_s, type.to_s
|
82
|
+
properties.select{ |p| p['type'] == type }.find{ |p| p['name'] == key }
|
83
|
+
end
|
84
|
+
|
85
|
+
def status
|
86
|
+
debug "Getting cartridge #{name}'s status"
|
87
|
+
result = rest_method "GET", :include => "status_messages"
|
88
|
+
result.status_messages
|
89
|
+
end
|
90
|
+
|
91
|
+
def start
|
92
|
+
debug "Starting cartridge #{name}"
|
93
|
+
rest_method "START", :event => "start"
|
94
|
+
end
|
95
|
+
|
96
|
+
def stop
|
97
|
+
debug "Stopping cartridge #{name}"
|
98
|
+
rest_method "STOP", :event => "stop"
|
99
|
+
end
|
100
|
+
|
101
|
+
def restart
|
102
|
+
debug "Restarting cartridge #{name}"
|
103
|
+
rest_method "RESTART", :event => "restart"
|
104
|
+
end
|
105
|
+
|
106
|
+
def reload
|
107
|
+
debug "Reloading cartridge #{name}"
|
108
|
+
rest_method "RESTART", :event => "reload"
|
109
|
+
end
|
110
|
+
|
111
|
+
def destroy
|
112
|
+
debug "Deleting cartridge #{name}"
|
113
|
+
rest_method "DELETE"
|
114
|
+
end
|
115
|
+
alias :delete :destroy
|
116
|
+
|
117
|
+
def set_scales(values)
|
118
|
+
values.delete_if{|k,v| v.nil? }
|
119
|
+
debug "Setting scales = %s" % values.map{|k,v| "#{k}: #{v}"}.join(" ")
|
120
|
+
rest_method "UPDATE", values
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_storage(values)
|
124
|
+
debug "Setting additional storage: #{values[:additional_gear_storage]}GB"
|
125
|
+
rest_method "UPDATE", values
|
126
|
+
end
|
127
|
+
|
128
|
+
def connection_info
|
129
|
+
info = property(:cart_data, :connection_url) || property(:cart_data, :job_url) || property(:cart_data, :monitoring_url)
|
130
|
+
info ? (info["value"] || '').rstrip : nil
|
131
|
+
end
|
132
|
+
|
133
|
+
def <=>(other)
|
134
|
+
return -1 if other.type == 'standalone' && type != 'standalone'
|
135
|
+
return 1 if type == 'standalone' && other.type != 'standalone'
|
136
|
+
name <=> other.name
|
137
|
+
end
|
138
|
+
|
139
|
+
def url_basename
|
140
|
+
uri = URI.parse(url)
|
141
|
+
name = uri.fragment
|
142
|
+
name = Rack::Utils.parse_nested_query(uri.query)['name'] if name.blank? && uri.query
|
143
|
+
name = File.basename(uri.path) if name.blank? && uri.path.present? && uri.path != '/'
|
144
|
+
name.presence || url
|
145
|
+
rescue
|
146
|
+
url
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.for_url(url)
|
150
|
+
new 'url' => url
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|