bosh_cli 0.19.1 → 0.19.2
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/lib/cli/commands/base.rb +37 -0
- data/lib/cli/commands/cloudcheck.rb +13 -29
- data/lib/cli/commands/deployment.rb +6 -27
- data/lib/cli/commands/job_management.rb +12 -17
- data/lib/cli/commands/job_rename.rb +29 -34
- data/lib/cli/commands/log_management.rb +1 -0
- data/lib/cli/commands/maintenance.rb +2 -2
- data/lib/cli/commands/misc.rb +6 -6
- data/lib/cli/commands/release.rb +33 -34
- data/lib/cli/commands/ssh.rb +4 -3
- data/lib/cli/commands/stemcell.rb +9 -29
- data/lib/cli/config.rb +2 -2
- data/lib/cli/core_ext.rb +4 -1
- data/lib/cli/deployment_helper.rb +1 -1
- data/lib/cli/director.rb +159 -73
- data/lib/cli/event_log_renderer.rb +49 -13
- data/lib/cli/release_compiler.rb +6 -9
- data/lib/cli/release_tarball.rb +10 -5
- data/lib/cli/runner.rb +36 -1
- data/lib/cli/task_log_renderer.rb +1 -1
- data/lib/cli/task_tracker.rb +13 -6
- data/lib/cli/version.rb +1 -1
- data/spec/unit/core_ext_spec.rb +5 -1
- data/spec/unit/director_spec.rb +40 -23
- data/spec/unit/job_rename_spec.rb +4 -0
- data/spec/unit/release_tarball_spec.rb +3 -1
- data/spec/unit/runner_spec.rb +20 -0
- data/spec/unit/task_tracker_spec.rb +0 -27
- metadata +4 -4
data/lib/cli/commands/ssh.rb
CHANGED
@@ -22,9 +22,10 @@ module Bosh::Cli::Command
|
|
22
22
|
args.shift
|
23
23
|
end
|
24
24
|
rescue ArgumentError, TypeError
|
25
|
+
# No index given
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
+
%w(public_key gateway_host gateway_user).each do |option|
|
28
29
|
pos = args.index("--#{option}")
|
29
30
|
if pos
|
30
31
|
options[option] = args[pos + 1]
|
@@ -98,13 +99,13 @@ module Bosh::Cli::Command
|
|
98
99
|
encrypt_password(password))
|
99
100
|
|
100
101
|
unless results && results.kind_of?(Array) && !results.empty?
|
101
|
-
err("Error setting up ssh, #{results.inspect}, "
|
102
|
+
err("Error setting up ssh, #{results.inspect}, " +
|
102
103
|
"check task logs for more details")
|
103
104
|
end
|
104
105
|
|
105
106
|
results.each do |result|
|
106
107
|
unless result.kind_of?(Hash)
|
107
|
-
err("Unexpected results #{results.inspect}, "
|
108
|
+
err("Unexpected results #{results.inspect}, " +
|
108
109
|
"check task logs for more details")
|
109
110
|
end
|
110
111
|
end
|
@@ -59,19 +59,9 @@ module Bosh::Cli::Command
|
|
59
59
|
|
60
60
|
say("\nUploading stemcell...\n")
|
61
61
|
|
62
|
-
status,
|
63
|
-
|
64
|
-
responses = {
|
65
|
-
:done => "Stemcell uploaded and created",
|
66
|
-
:non_trackable => "Uploaded stemcell but director at '#{target}' " +
|
67
|
-
"doesn't support creation tracking",
|
68
|
-
:track_timeout => "Uploaded stemcell but timed out out " +
|
69
|
-
"while tracking status",
|
70
|
-
:error => "Uploaded stemcell but received an error " +
|
71
|
-
"while tracking status",
|
72
|
-
}
|
62
|
+
status, _ = director.upload_stemcell(stemcell.stemcell_file)
|
73
63
|
|
74
|
-
|
64
|
+
task_report(status, "Stemcell uploaded and created")
|
75
65
|
end
|
76
66
|
|
77
67
|
def list
|
@@ -147,41 +137,31 @@ module Bosh::Cli::Command
|
|
147
137
|
|
148
138
|
url = yaml[stemcell_name]["url"]
|
149
139
|
size = yaml[stemcell_name]["size"]
|
150
|
-
|
151
|
-
|
140
|
+
progress_bar = ProgressBar.new(stemcell_name, size)
|
141
|
+
progress_bar.file_transfer_mode
|
152
142
|
File.open("#{stemcell_name}", "w") { |file|
|
153
143
|
@http_client.get(url) do |chunk|
|
154
144
|
file.write(chunk)
|
155
|
-
|
145
|
+
progress_bar.inc(chunk.size)
|
156
146
|
end
|
157
147
|
}
|
158
|
-
|
148
|
+
progress_bar.finish
|
159
149
|
puts("Download complete.")
|
160
150
|
end
|
161
151
|
|
162
152
|
def delete(name, version)
|
163
153
|
auth_required
|
164
154
|
|
165
|
-
say("You are going to delete stemcell `#{name}
|
155
|
+
say("You are going to delete stemcell `#{name}/#{version}'".red)
|
166
156
|
|
167
157
|
unless confirmed?
|
168
158
|
say("Canceled deleting stemcell".green)
|
169
159
|
return
|
170
160
|
end
|
171
161
|
|
172
|
-
status,
|
173
|
-
|
174
|
-
responses = {
|
175
|
-
:done => "Deleted stemcell #{name} (#{version})",
|
176
|
-
:non_trackable => "Stemcell delete in progress but director " +
|
177
|
-
"at '#{target}' doesn't support task tracking",
|
178
|
-
:track_timeout => "Timed out out while tracking " +
|
179
|
-
"stemcell deletion progress",
|
180
|
-
:error => "Attempted to delete stemcell but received an error " +
|
181
|
-
"while tracking status",
|
182
|
-
}
|
162
|
+
status, _ = director.delete_stemcell(name, version)
|
183
163
|
|
184
|
-
|
164
|
+
task_report(status, "Deleted stemcell `#{name}/#{version}'")
|
185
165
|
end
|
186
166
|
end
|
187
167
|
end
|
data/lib/cli/config.rb
CHANGED
@@ -107,8 +107,8 @@ module Bosh::Cli
|
|
107
107
|
# deployment file.
|
108
108
|
def set_deployment(deployment_file_path)
|
109
109
|
raise MissingTarget, "Must have a target set." if target.nil?
|
110
|
-
@config_file["deployment"] = {
|
111
|
-
@config_file["deployment"] ||= {
|
110
|
+
@config_file["deployment"] = {} if is_old_deployment_config?
|
111
|
+
@config_file["deployment"] ||= {}
|
112
112
|
@config_file["deployment"][target] = deployment_file_path
|
113
113
|
end
|
114
114
|
|
data/lib/cli/core_ext.rb
CHANGED
@@ -108,7 +108,10 @@ module BoshStringExtensions
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def colorize(color_code)
|
111
|
-
if Bosh::Cli::Config.
|
111
|
+
if Bosh::Cli::Config.output.tty? &&
|
112
|
+
Bosh::Cli::Config.colorize &&
|
113
|
+
COLOR_CODES[color_code]
|
114
|
+
|
112
115
|
"#{COLOR_CODES[color_code]}#{self}\e[0m"
|
113
116
|
else
|
114
117
|
self
|
@@ -163,7 +163,7 @@ module Bosh::Cli
|
|
163
163
|
end
|
164
164
|
|
165
165
|
if old_stemcells.size != new_stemcells.size
|
166
|
-
say("Stemcell update seems to be inconsistent with current " +
|
166
|
+
say("Stemcell update seems to be inconsistent with current ".red +
|
167
167
|
"deployment. Please carefully review changes above.".red)
|
168
168
|
unless confirmed?("Are you sure this configuration is correct?")
|
169
169
|
cancel_deployment
|
data/lib/cli/director.rb
CHANGED
@@ -47,12 +47,15 @@ module Bosh
|
|
47
47
|
|
48
48
|
def create_user(username, password)
|
49
49
|
payload = JSON.generate("username" => username, "password" => password)
|
50
|
-
response_code,
|
50
|
+
response_code, _ = post("/users", "application/json", payload)
|
51
51
|
response_code == 204
|
52
52
|
end
|
53
53
|
|
54
|
-
def upload_stemcell(filename)
|
55
|
-
|
54
|
+
def upload_stemcell(filename, options = {})
|
55
|
+
options = options.dup
|
56
|
+
options[:content_type] = "application/x-compressed"
|
57
|
+
|
58
|
+
upload_and_track(:post, "/stemcells", filename, options)
|
56
59
|
end
|
57
60
|
|
58
61
|
def get_version
|
@@ -92,6 +95,17 @@ module Bosh
|
|
92
95
|
get_json("/releases/#{name}")
|
93
96
|
end
|
94
97
|
|
98
|
+
def match_packages(manifest_yaml)
|
99
|
+
url = "/packages/matches"
|
100
|
+
status, body = post(url, "text/yaml", manifest_yaml)
|
101
|
+
|
102
|
+
if status == 200
|
103
|
+
JSON.parse(body)
|
104
|
+
else
|
105
|
+
err(parse_error_message(status, body))
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
95
109
|
def get_deployment(name)
|
96
110
|
status, body = get_json_with_status("/deployments/#{name}")
|
97
111
|
if status == 404
|
@@ -108,43 +122,65 @@ module Bosh
|
|
108
122
|
body
|
109
123
|
end
|
110
124
|
|
111
|
-
def upload_release(filename)
|
112
|
-
|
125
|
+
def upload_release(filename, options = {})
|
126
|
+
options = options.dup
|
127
|
+
options[:content_type] = "application/x-compressed"
|
128
|
+
|
129
|
+
upload_and_track(:post, "/releases", filename, options)
|
113
130
|
end
|
114
131
|
|
115
132
|
def delete_stemcell(name, version, options = {})
|
116
|
-
|
133
|
+
options = options.dup
|
134
|
+
request_and_track(:delete, "/stemcells/#{name}/#{version}", options)
|
117
135
|
end
|
118
136
|
|
119
137
|
def delete_deployment(name, options = {})
|
138
|
+
options = options.dup
|
139
|
+
force = options.delete(:force)
|
140
|
+
|
120
141
|
url = "/deployments/#{name}"
|
121
|
-
query_params = []
|
122
|
-
query_params << "force=true" if options[:force]
|
123
|
-
url += "?#{query_params.join("&")}" if query_params.size > 0
|
124
142
|
|
125
|
-
|
143
|
+
extras = []
|
144
|
+
extras << "force=true" if force
|
145
|
+
|
146
|
+
request_and_track(:delete, add_query_string(url, extras), options)
|
126
147
|
end
|
127
148
|
|
128
149
|
def delete_release(name, options = {})
|
129
|
-
|
150
|
+
options = options.dup
|
151
|
+
force = options.delete(:force)
|
152
|
+
version = options.delete(:version)
|
130
153
|
|
131
|
-
|
132
|
-
query_params << "force=true" if options[:force]
|
133
|
-
query_params << "version=#{options[:version]}" if options[:version]
|
154
|
+
url = "/releases/#{name}"
|
134
155
|
|
135
|
-
|
156
|
+
extras = []
|
157
|
+
extras << "force=true" if force
|
158
|
+
extras << "version=#{version}" if version
|
136
159
|
|
137
|
-
request_and_track(:delete, url)
|
160
|
+
request_and_track(:delete, add_query_string(url, extras), options)
|
138
161
|
end
|
139
162
|
|
140
163
|
def deploy(manifest_yaml, options = {})
|
164
|
+
options = options.dup
|
165
|
+
|
166
|
+
recreate = options.delete(:recreate)
|
167
|
+
options[:content_type] = "text/yaml"
|
168
|
+
options[:payload] = manifest_yaml
|
169
|
+
|
141
170
|
url = "/deployments"
|
142
|
-
|
143
|
-
|
171
|
+
|
172
|
+
extras = []
|
173
|
+
extras << "recreate=true" if recreate
|
174
|
+
|
175
|
+
request_and_track(:post, add_query_string(url, extras), options)
|
144
176
|
end
|
145
177
|
|
146
|
-
def setup_ssh(deployment_name, job, index, user,
|
178
|
+
def setup_ssh(deployment_name, job, index, user,
|
179
|
+
public_key, password, options = {})
|
180
|
+
options = options.dup
|
181
|
+
|
147
182
|
url = "/deployments/#{deployment_name}/ssh"
|
183
|
+
|
148
184
|
payload = {
|
149
185
|
"command" => "setup",
|
150
186
|
"deployment_name" => deployment_name,
|
@@ -159,17 +195,19 @@ module Bosh
|
|
159
195
|
}
|
160
196
|
}
|
161
197
|
|
162
|
-
|
163
|
-
|
164
|
-
JSON.generate(payload), :log_type => "result")
|
198
|
+
options[:payload] = JSON.generate(payload)
|
199
|
+
options[:content_type] = "application/json"
|
165
200
|
|
166
|
-
|
201
|
+
status, task_id = request_and_track(:post, url, options)
|
167
202
|
|
168
|
-
|
203
|
+
# TODO: this needs to be done in command handler, not in director.rb
|
204
|
+
return nil if status != :done
|
205
|
+
JSON.parse(get_task_result_log(task_id))
|
169
206
|
end
|
170
207
|
|
171
|
-
def cleanup_ssh(deployment_name, job, user_regex, indexes)
|
172
|
-
|
208
|
+
def cleanup_ssh(deployment_name, job, user_regex, indexes, options = {})
|
209
|
+
options = options.dup
|
210
|
+
|
173
211
|
url = "/deployments/#{deployment_name}/ssh"
|
174
212
|
|
175
213
|
payload = {
|
@@ -177,68 +215,90 @@ module Bosh
|
|
177
215
|
"deployment_name" => deployment_name,
|
178
216
|
"target" => {
|
179
217
|
"job" => job,
|
180
|
-
"indexes" => indexes.compact
|
218
|
+
"indexes" => (indexes || []).compact
|
181
219
|
},
|
182
220
|
"params" => { "user_regex" => user_regex }
|
183
221
|
}
|
184
222
|
|
185
|
-
|
186
|
-
|
223
|
+
options[:payload] = JSON.generate(payload)
|
224
|
+
options[:content_type] = "application/json"
|
225
|
+
|
226
|
+
request_and_track(:post, url, options)
|
187
227
|
end
|
188
228
|
|
189
229
|
def change_job_state(deployment_name, manifest_yaml,
|
190
|
-
|
230
|
+
job_name, index, new_state, options = {})
|
231
|
+
options = options.dup
|
232
|
+
|
191
233
|
url = "/deployments/#{deployment_name}/jobs/#{job_name}"
|
192
234
|
url += "/#{index}" if index
|
193
235
|
url += "?state=#{new_state}"
|
194
|
-
|
236
|
+
|
237
|
+
options[:payload] = manifest_yaml
|
238
|
+
options[:content_type] = "text/yaml"
|
239
|
+
|
240
|
+
request_and_track(:put, url, options)
|
195
241
|
end
|
196
242
|
|
243
|
+
# TODO: should pass 'force' with options, not as a separate argument
|
197
244
|
def rename_job(deployment_name, manifest_yaml, old_name, new_name,
|
198
|
-
force =
|
245
|
+
force = false, options = {})
|
246
|
+
options = options.dup
|
247
|
+
|
199
248
|
url = "/deployments/#{deployment_name}/jobs/#{old_name}"
|
200
249
|
|
201
|
-
|
202
|
-
|
250
|
+
extras = []
|
251
|
+
extras << "new_name=#{new_name}"
|
252
|
+
extras << "force=true" if force
|
203
253
|
|
204
|
-
|
205
|
-
|
206
|
-
|
254
|
+
options[:content_type] = "text/yaml"
|
255
|
+
options[:payload] = manifest_yaml
|
256
|
+
|
257
|
+
request_and_track(:put, add_query_string(url, extras), options)
|
207
258
|
end
|
208
259
|
|
209
|
-
def fetch_logs(deployment_name, job_name, index, log_type,
|
260
|
+
def fetch_logs(deployment_name, job_name, index, log_type,
|
261
|
+
filters = nil, options = {})
|
262
|
+
options = options.dup
|
263
|
+
|
210
264
|
url = "/deployments/#{deployment_name}/jobs/#{job_name}"
|
211
265
|
url += "/#{index}/logs?type=#{log_type}&filters=#{filters}"
|
212
266
|
|
213
|
-
status, task_id = request_and_track(:get, url)
|
214
|
-
|
267
|
+
status, task_id = request_and_track(:get, url, options)
|
268
|
+
|
269
|
+
# TODO: this should be done in command handler, not in director.rb
|
270
|
+
return nil if status != :done
|
215
271
|
get_task_result(task_id)
|
216
272
|
end
|
217
273
|
|
218
|
-
def fetch_vm_state(deployment_name)
|
274
|
+
def fetch_vm_state(deployment_name, options = {})
|
275
|
+
options = options.dup
|
276
|
+
|
219
277
|
url = "/deployments/#{deployment_name}/vms?format=full"
|
220
278
|
|
221
|
-
status, task_id,
|
222
|
-
request_and_track(:get, url, nil, nil, :log_type => "result")
|
279
|
+
status, task_id = request_and_track(:get, url, options)
|
223
280
|
|
224
|
-
|
281
|
+
# TODO: this should be done in command handler, not in director.rb
|
282
|
+
if status != :done
|
225
283
|
raise DirectorError, "Failed to fetch VMs information from director"
|
226
284
|
end
|
227
285
|
|
286
|
+
output = get_task_result_log(task_id)
|
287
|
+
|
228
288
|
output.to_s.split("\n").map do |vm_state|
|
229
289
|
JSON.parse(vm_state)
|
230
290
|
end
|
231
291
|
end
|
232
292
|
|
233
293
|
def download_resource(id)
|
234
|
-
status, tmp_file,
|
235
|
-
|
294
|
+
status, tmp_file, _ = get("/resources/#{id}",
|
295
|
+
nil, nil, {}, :file => true)
|
236
296
|
|
237
297
|
if status == 200
|
238
298
|
tmp_file
|
239
299
|
else
|
240
|
-
raise DirectorError,
|
241
|
-
|
300
|
+
raise DirectorError,
|
301
|
+
"Cannot download resource `#{id}': HTTP status #{status}"
|
242
302
|
end
|
243
303
|
end
|
244
304
|
|
@@ -269,9 +329,11 @@ module Bosh
|
|
269
329
|
get_json(url)
|
270
330
|
end
|
271
331
|
|
272
|
-
def perform_cloud_scan(deployment_name)
|
332
|
+
def perform_cloud_scan(deployment_name, options = {})
|
333
|
+
options = options.dup
|
273
334
|
url = "/deployments/#{deployment_name}/scans"
|
274
|
-
|
335
|
+
|
336
|
+
request_and_track(:post, url, options)
|
275
337
|
end
|
276
338
|
|
277
339
|
def list_problems(deployment_name)
|
@@ -279,14 +341,18 @@ module Bosh
|
|
279
341
|
get_json(url)
|
280
342
|
end
|
281
343
|
|
282
|
-
def apply_resolutions(deployment_name, resolutions)
|
344
|
+
def apply_resolutions(deployment_name, resolutions, options = {})
|
345
|
+
options = options.dup
|
346
|
+
|
283
347
|
url = "/deployments/#{deployment_name}/problems"
|
284
|
-
|
285
|
-
|
348
|
+
options[:content_type] = "application/json"
|
349
|
+
options[:payload] = JSON.generate("resolutions" => resolutions)
|
350
|
+
|
351
|
+
request_and_track(:put, url, options)
|
286
352
|
end
|
287
353
|
|
288
354
|
def get_current_time
|
289
|
-
|
355
|
+
_, _, headers = get("/info")
|
290
356
|
Time.parse(headers[:date]) rescue nil
|
291
357
|
end
|
292
358
|
|
@@ -320,11 +386,16 @@ module Bosh
|
|
320
386
|
get_task(task_id)["result"]
|
321
387
|
end
|
322
388
|
|
389
|
+
def get_task_result_log(task_id)
|
390
|
+
log, _ = get_task_output(task_id, 0, "result")
|
391
|
+
log
|
392
|
+
end
|
393
|
+
|
323
394
|
def get_task_output(task_id, offset, log_type = nil)
|
324
395
|
uri = "/tasks/#{task_id}/output"
|
325
396
|
uri += "?type=#{log_type}" if log_type
|
326
397
|
|
327
|
-
headers = {
|
398
|
+
headers = {"Range" => "bytes=#{offset}-"}
|
328
399
|
response_code, body, headers = get(uri, nil, nil, headers)
|
329
400
|
|
330
401
|
if response_code == 206 &&
|
@@ -349,20 +420,28 @@ module Bosh
|
|
349
420
|
end
|
350
421
|
end
|
351
422
|
|
352
|
-
|
353
|
-
|
354
|
-
|
423
|
+
# Perform director HTTP request and track director task (if request
|
424
|
+
# started one).
|
425
|
+
# @param [Symbol] method HTTP method
|
426
|
+
# @param [String] uri URI
|
427
|
+
# @param [Hash] options Request and tracking options
|
428
|
+
def request_and_track(method, uri, options = {})
|
429
|
+
options = options.dup
|
430
|
+
|
431
|
+
content_type = options.delete(:content_type)
|
432
|
+
payload = options.delete(:payload)
|
433
|
+
track_opts = options
|
434
|
+
|
435
|
+
http_status, _, headers = request(method, uri, content_type, payload)
|
355
436
|
location = headers[:location]
|
356
437
|
redirected = http_status == 302
|
357
438
|
task_id = nil
|
358
|
-
output = nil
|
359
439
|
|
360
440
|
if redirected
|
361
441
|
if location =~ /\/tasks\/(\d+)\/?$/ # Looks like we received task URI
|
362
442
|
task_id = $1
|
363
|
-
tracker = Bosh::Cli::TaskTracker.new(self, task_id,
|
443
|
+
tracker = Bosh::Cli::TaskTracker.new(self, task_id, track_opts)
|
364
444
|
status = tracker.track
|
365
|
-
output = tracker.output
|
366
445
|
else
|
367
446
|
status = :non_trackable
|
368
447
|
end
|
@@ -370,13 +449,12 @@ module Bosh
|
|
370
449
|
status = :failed
|
371
450
|
end
|
372
451
|
|
373
|
-
[status, task_id
|
452
|
+
[status, task_id]
|
374
453
|
end
|
375
454
|
|
376
|
-
def upload_and_track(
|
455
|
+
def upload_and_track(method, uri, filename, options = {})
|
377
456
|
file = FileWithProgressBar.open(filename, "r")
|
378
|
-
method
|
379
|
-
request_and_track(method, uri, content_type, file, options)
|
457
|
+
request_and_track(method, uri, options.merge(:payload => file))
|
380
458
|
ensure
|
381
459
|
file.stop_progress_bar if file
|
382
460
|
end
|
@@ -384,6 +462,8 @@ module Bosh
|
|
384
462
|
def request(method, uri, content_type = nil, payload = nil,
|
385
463
|
headers = {}, options = {})
|
386
464
|
headers = headers.dup
|
465
|
+
tmp_file = nil
|
466
|
+
|
387
467
|
headers["Content-Type"] = content_type if content_type
|
388
468
|
|
389
469
|
if options[:file]
|
@@ -429,16 +509,14 @@ module Bosh
|
|
429
509
|
end
|
430
510
|
|
431
511
|
def parse_error_message(status, body)
|
432
|
-
parsed_body = JSON.parse(body.to_s)
|
512
|
+
parsed_body = JSON.parse(body.to_s) rescue {}
|
433
513
|
|
434
514
|
if parsed_body["code"] && parsed_body["description"]
|
435
|
-
"
|
436
|
-
|
515
|
+
"Error %s: %s" % [parsed_body["code"],
|
516
|
+
parsed_body["description"]]
|
437
517
|
else
|
438
|
-
"
|
518
|
+
"HTTP %s: %s" % [status, body]
|
439
519
|
end
|
440
|
-
rescue JSON::ParserError
|
441
|
-
"Director error (HTTP %s): %s" % [status, body]
|
442
520
|
end
|
443
521
|
|
444
522
|
private
|
@@ -463,7 +541,7 @@ module Bosh
|
|
463
541
|
|
464
542
|
rescue HTTPClient::BadResponseError => e
|
465
543
|
err("Received bad HTTP response from director: #{e}")
|
466
|
-
rescue URI::Error, SocketError,
|
544
|
+
rescue URI::Error, SocketError, SystemCallError
|
467
545
|
raise # We handle these upstream
|
468
546
|
rescue => e
|
469
547
|
# httpclient (sadly) doesn't have a generic exception
|
@@ -478,13 +556,21 @@ module Bosh
|
|
478
556
|
end
|
479
557
|
|
480
558
|
def get_json_with_status(url)
|
481
|
-
status, body,
|
559
|
+
status, body, _ = get(url, "application/json")
|
482
560
|
body = JSON.parse(body) if status == 200
|
483
561
|
[status, body]
|
484
562
|
rescue JSON::ParserError
|
485
563
|
raise DirectorError, "Cannot parse director response: #{body}"
|
486
564
|
end
|
487
565
|
|
566
|
+
def add_query_string(url, parts)
|
567
|
+
if parts.size > 0
|
568
|
+
"#{url}?#{parts.join("&")}"
|
569
|
+
else
|
570
|
+
url
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
488
574
|
end
|
489
575
|
|
490
576
|
class FileWithProgressBar < ::File
|