class Bosh::Cli::Client::Director
Constants
- API_TIMEOUT
- CONNECT_TIMEOUT
- DIRECTOR_HTTP_ERROR_CODES
Attributes
director_uri[R]
num_retries[R]
retry_wait_interval[R]
Public Class Methods
new(director_uri, credentials = nil, options = {})
click to toggle source
Options can include:
-
:no_track => true - do not use
TaskTracker
for long-running+request_and_track+ calls
# File lib/cli/client/director.rb, line 26 def initialize(director_uri, credentials = nil, options = {}) if director_uri.nil? || director_uri =~ /^\s*$/ raise DirectorMissing, 'no director URI given' end @director_uri = URI.parse(director_uri) @director_host = @director_uri.host @scheme = @director_uri.scheme @port = @director_uri.port @credentials = credentials @track_tasks = !options.delete(:no_track) @num_retries = options.fetch(:num_retries, 5) @retry_wait_interval = options.fetch(:retry_wait_interval, 5) @ca_cert = options[:ca_cert] end
Public Instance Methods
apply_resolutions(deployment_name, resolutions, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 521 def apply_resolutions(deployment_name, resolutions, options = {}) options = options.dup url = "/deployments/#{deployment_name}/problems" options[:content_type] = 'application/json' options[:payload] = JSON.generate('resolutions' => resolutions) request_and_track(:put, url, options) end
attach_disk(deployment_name, job_name, instance_id, disk_cid)
click to toggle source
# File lib/cli/client/director.rb, line 206 def attach_disk(deployment_name, job_name, instance_id, disk_cid) request_and_track(:put, "/disks/#{disk_cid}/attachments?deployment=#{deployment_name}&job=#{job_name}&instance_id=#{instance_id}") end
authenticated?()
click to toggle source
# File lib/cli/client/director.rb, line 67 def authenticated? # getting status verifies credentials # if credentials are wrong it will raise DirectorError status = get_status # Backward compatibility: older directors return 200 # only for logged in users return true if !status.has_key?('version') !status['user'].nil? rescue DirectorError false end
cancel_task(task_id)
click to toggle source
# File lib/cli/client/director.rb, line 590 def cancel_task(task_id) response_code, body = delete("/task/#{task_id}") raise AuthError if response_code == 401 raise MissingTask, "No task##{task_id} found" if response_code == 404 [body, response_code] end
change_instance_ignore_state(deployment_name, instance_group_name, id, ignore_state)
click to toggle source
# File lib/cli/client/director.rb, line 390 def change_instance_ignore_state(deployment_name, instance_group_name, id, ignore_state) url = "/deployments/#{deployment_name}/instance_groups/#{instance_group_name}/#{id}/ignore" payload = JSON.generate('ignore' => ignore_state) put(url, 'application/json', payload) end
change_job_state(deployment_name, manifest_yaml, job, index_or_id, new_state, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 357 def change_job_state(deployment_name, manifest_yaml, job, index_or_id, new_state, options = {}) options = options.dup skip_drain = !!options.delete(:skip_drain) canaries = options.delete(:canaries) max_in_flight = options.delete(:max_in_flight) url = "/deployments/#{deployment_name}/jobs/#{job}" url += "/#{index_or_id}" if index_or_id url += "?state=#{new_state}" url += "&skip_drain=true" if skip_drain url += "&max_in_flight=#{max_in_flight}" if max_in_flight url += "&canaries=#{canaries}" if canaries options[:payload] = manifest_yaml options[:content_type] = 'text/yaml' request_and_track(:put, url, options) end
change_vm_resurrection(deployment_name, job_name, index, value)
click to toggle source
# File lib/cli/client/director.rb, line 378 def change_vm_resurrection(deployment_name, job_name, index, value) url = "/deployments/#{deployment_name}/jobs/#{job_name}/#{index}/resurrection" payload = JSON.generate('resurrection_paused' => value) put(url, 'application/json', payload) end
change_vm_resurrection_for_all(value)
click to toggle source
# File lib/cli/client/director.rb, line 384 def change_vm_resurrection_for_all(value) url = "/resurrection" payload = JSON.generate('resurrection_paused' => value) put(url, 'application/json', payload) end
check_director_restart(poll_interval, timeout)
click to toggle source
# File lib/cli/client/director.rb, line 610 def check_director_restart(poll_interval, timeout) current_time = start_time = Time.now() #step 1, wait until director is stopped while current_time.to_i - start_time.to_i <= timeout do status, body = get_json_with_status('/info') break if status != 200 sleep(poll_interval) current_time = Time.now() end #step 2, wait until director is started while current_time.to_i - start_time.to_i <= timeout do status, body = get_json_with_status('/info') return true if status == 200 sleep(poll_interval) current_time = Time.now() end return false end
cleanup(config = {})
click to toggle source
# File lib/cli/client/director.rb, line 722 def cleanup(config = {}) options = {} options[:payload] = JSON.generate('config' => config) options[:content_type] = 'application/json' request_and_track(:post, '/cleanup', options) end
cleanup_ssh(deployment_name, job, user_regex, id, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 334 def cleanup_ssh(deployment_name, job, user_regex, id, options = {}) options = options.dup url = "/deployments/#{deployment_name}/ssh" payload = { 'command' => 'cleanup', 'deployment_name' => deployment_name, 'target' => { 'job' => job, 'indexes' => (id || []).compact, 'ids' => (id || []).compact, }, 'params' => { 'user_regex' => user_regex } } options[:payload] = JSON.generate(payload) options[:content_type] = 'application/json' options[:task_success_state] = :queued request_and_track(:post, url, options) end
create_backup()
click to toggle source
# File lib/cli/client/director.rb, line 597 def create_backup request_and_track(:post, '/backups', {}) end
create_property(deployment_name, property_name, value)
click to toggle source
# File lib/cli/client/director.rb, line 445 def create_property(deployment_name, property_name, value) url = "/deployments/#{deployment_name}/properties" payload = JSON.generate('name' => property_name, 'value' => value) post(url, 'application/json', payload) end
create_user(username, password)
click to toggle source
# File lib/cli/client/director.rb, line 79 def create_user(username, password) payload = JSON.generate('username' => username, 'password' => password) response_code, _ = post('/users', 'application/json', payload) response_code == 204 end
delete(uri, content_type = nil, payload = nil, headers = {}, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 741 def delete(uri, content_type = nil, payload = nil, headers = {}, options = {}) request(:delete, uri, content_type, payload, headers, options) end
delete_all_snapshots(deployment_name, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 493 def delete_all_snapshots(deployment_name, options = {}) options = options.dup url = "/deployments/#{deployment_name}/snapshots" request_and_track(:delete, url, options) end
delete_deployment(name, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 247 def delete_deployment(name, options = {}) options = options.dup force = options.delete(:force) url = "/deployments/#{name}" extras = [] extras << ['force', 'true'] if force request_and_track(:delete, add_query_string(url, extras), options) end
delete_orphan_disk_by_disk_cid(orphan_disk_cid)
click to toggle source
# File lib/cli/client/director.rb, line 210 def delete_orphan_disk_by_disk_cid(orphan_disk_cid) request_and_track(:delete, "/disks/#{orphan_disk_cid}") end
delete_property(deployment_name, property_name)
click to toggle source
# File lib/cli/client/director.rb, line 457 def delete_property(deployment_name, property_name) url = "/deployments/#{deployment_name}/properties/#{property_name}" delete(url, 'application/json') end
delete_release(name, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 259 def delete_release(name, options = {}) options = options.dup force = options.delete(:force) version = options.delete(:version) url = "/releases/#{name}" extras = [] extras << ['force', 'true'] if force extras << ['version', version] if version request_and_track(:delete, add_query_string(url, extras), options) end
delete_snapshot(deployment_name, snapshot_cid, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 501 def delete_snapshot(deployment_name, snapshot_cid, options = {}) options = options.dup url = "/deployments/#{deployment_name}/snapshots/#{snapshot_cid}" request_and_track(:delete, url, options) end
delete_stemcell(name, version, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 235 def delete_stemcell(name, version, options = {}) options = options.dup force = options.delete(:force) url = "/stemcells/#{name}/#{version}" extras = [] extras << ['force', 'true'] if force request_and_track(:delete, add_query_string(url, extras), options) end
delete_user(username)
click to toggle source
# File lib/cli/client/director.rb, line 85 def delete_user(username) response_code, _ = delete("/users/#{username}") response_code == 204 end
delete_vm_by_cid(vm_cid)
click to toggle source
# File lib/cli/client/director.rb, line 273 def delete_vm_by_cid(vm_cid) request_and_track(:delete, "/vms/#{vm_cid}") end
deploy(manifest_yaml, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 277 def deploy(manifest_yaml, options = {}) options = options.dup recreate = options.delete(:recreate) skip_drain = options.delete(:skip_drain) context = options.delete(:context) options[:content_type] = 'text/yaml' options[:payload] = manifest_yaml url = '/deployments' extras = [] extras << ['recreate', 'true'] if recreate extras << ['context', JSON.dump(context)] if context extras << ['skip_drain', skip_drain] if skip_drain request_and_track(:post, add_query_string(url, extras), options) end
diff_deployment(name, manifest_yaml, redact_diff = true)
click to toggle source
# File lib/cli/client/director.rb, line 296 def diff_deployment(name, manifest_yaml, redact_diff = true) redact_param = redact_diff ? '' : '?redact=false' uri = "/deployments/#{name}/diff#{redact_param}" status, body = post(uri, 'text/yaml', manifest_yaml) if status == 200 JSON.parse(body) else err(parse_error_message(status, body)) end end
download_resource(id)
click to toggle source
# File lib/cli/client/director.rb, line 433 def download_resource(id) status, tmp_file, _ = get("/resources/#{id}", nil, nil, {}, :file => true) if status == 200 tmp_file else raise DirectorError, "Cannot download resource '#{id}': HTTP status #{status}" end end
exists?()
click to toggle source
# File lib/cli/client/director.rb, line 46 def exists? get_status true rescue AuthError true # For compatibility with directors that return 401 for /info rescue DirectorError false end
fetch_backup()
click to toggle source
# File lib/cli/client/director.rb, line 601 def fetch_backup _, path, _ = get('/backups', nil, nil, {}, :file => true) path end
fetch_logs(deployment_name, job_name, index, log_type, filters = nil, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 396 def fetch_logs(deployment_name, job_name, index, log_type, filters = nil, options = {}) options = options.dup url = "/deployments/#{deployment_name}/jobs/#{job_name}" url += "/#{index}/logs?type=#{log_type}&filters=#{filters}" status, task_id = request_and_track(:get, url, options) return nil if status != :done get_task_result(task_id) end
fetch_vm_state(deployment_name, options = {}, full = true)
click to toggle source
# File lib/cli/client/director.rb, line 409 def fetch_vm_state(deployment_name, options = {}, full = true) options = options.dup url = "/deployments/#{deployment_name}/vms" if full status, task_id = request_and_track(:get, "#{url}?format=full", options) raise DirectorError, 'Failed to fetch VMs information from director' if status != :done output = get_task_result_log(task_id) else status, output, _ = get(url, nil, nil, {}, options) raise DirectorError, 'Failed to fetch VMs information from director' if status != 200 end output = output.to_s.split("\n").map do |vm_state| JSON.parse(vm_state) end output.flatten end
get(uri, content_type = nil, payload = nil, headers = {}, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 737 def get(uri, content_type = nil, payload = nil, headers = {}, options = {}) request(:get, uri, content_type, payload, headers, options) end
get_cloud_config()
click to toggle source
# File lib/cli/client/director.rb, line 690 def get_cloud_config _, cloud_configs = get_json_with_status('/cloud_configs?limit=1') latest = cloud_configs.first if !latest.nil? Bosh::Cli::CloudConfig.new( properties: latest["properties"], created_at: latest["created_at"]) end end
get_current_time()
click to toggle source
# File lib/cli/client/director.rb, line 531 def get_current_time _, _, headers = get('/info') Time.parse(headers[:date]) rescue nil end
get_deployment(name)
click to toggle source
# File lib/cli/client/director.rb, line 196 def get_deployment(name) _, body = get_json_with_status("/deployments/#{name}") body end
get_property(deployment_name, property_name)
click to toggle source
# File lib/cli/client/director.rb, line 462 def get_property(deployment_name, property_name) url = "/deployments/#{deployment_name}/properties/#{property_name}" get_json_with_status(url) end
get_release(name)
click to toggle source
# File lib/cli/client/director.rb, line 161 def get_release(name) get_json("/releases/#{name}") end
get_runtime_config()
click to toggle source
# File lib/cli/client/director.rb, line 706 def get_runtime_config _, runtime_configs = get_json_with_status('/runtime_configs?limit=1') latest = runtime_configs.first if !latest.nil? Bosh::Cli::RuntimeConfig.new( properties: latest["properties"], created_at: latest["created_at"]) end end
get_status()
click to toggle source
# File lib/cli/client/director.rb, line 111 def get_status get_json('/info') end
get_task(task_id)
click to toggle source
# File lib/cli/client/director.rb, line 542 def get_task(task_id) response_code, body = get("/tasks/#{task_id}") raise AuthError if response_code == 401 raise MissingTask, "Task #{task_id} not found" if response_code == 404 if response_code != 200 raise TaskTrackError, "Got HTTP #{response_code} " + 'while tracking task state' end JSON.parse(body) rescue JSON::ParserError raise TaskTrackError, 'Cannot parse task JSON, ' + 'incompatible director version' end
get_task_output(task_id, offset, log_type = nil)
click to toggle source
# File lib/cli/client/director.rb, line 571 def get_task_output(task_id, offset, log_type = nil) uri = "/tasks/#{task_id}/output" uri += "?type=#{log_type}" if log_type headers = { 'Range' => "bytes=#{offset}-" } response_code, body, headers = get(uri, nil, nil, headers) if response_code == 206 && headers[:content_range].to_s =~ /bytes \d+-(\d+)\/\d+/ new_offset = $1.to_i + 1 else new_offset = nil # Delete the "Byte range unsatisfiable" message body = nil if response_code == 416 end [body, new_offset] end
get_task_result(task_id)
click to toggle source
# File lib/cli/client/director.rb, line 562 def get_task_result(task_id) get_task(task_id)['result'] end
get_task_result_log(task_id)
click to toggle source
# File lib/cli/client/director.rb, line 566 def get_task_result_log(task_id) log, _ = get_task_output(task_id, 0, 'result') log end
get_task_state(task_id)
click to toggle source
# File lib/cli/client/director.rb, line 558 def get_task_state(task_id) get_task(task_id)['state'] end
get_time_difference()
click to toggle source
# File lib/cli/client/director.rb, line 536 def get_time_difference # This includes the round-trip to director ctime = get_current_time ctime ? Time.now - ctime : 0 end
get_version()
click to toggle source
# File lib/cli/client/director.rb, line 107 def get_version get_status['version'] end
inspect_release(name, version)
click to toggle source
# File lib/cli/client/director.rb, line 165 def inspect_release(name, version) url = "/releases/#{name}" extras = [] extras << ['version', version] get_json(add_query_string(url, extras)) end
list_deployments()
click to toggle source
# File lib/cli/client/director.rb, line 123 def list_deployments get_json('/deployments') end
list_errands(deployment_name)
click to toggle source
# File lib/cli/client/director.rb, line 141 def list_errands(deployment_name) get_json("/deployments/#{deployment_name}/errands") end
list_events(options={})
click to toggle source
# File lib/cli/client/director.rb, line 127 def list_events(options={}) query_string = "/events" delimeter = "?" options[:before_time] = URI.encode(options.delete(:before)) if options[:before] options[:after_time] = URI.encode(options.delete(:after)) if options[:after] [:before_id, :deployment, :instance, :task, :before_time, :after_time].each do |param| if options[param] query_string += "#{delimeter}#{ param.to_s}=#{options[param]}" delimeter = "&" end end get_json(query_string) end
list_locks()
click to toggle source
# File lib/cli/client/director.rb, line 634 def list_locks get_json('/locks') end
list_orphan_disks()
click to toggle source
# File lib/cli/client/director.rb, line 214 def list_orphan_disks _, body = get_json_with_status('/disks') body end
list_problems(deployment_name)
click to toggle source
# File lib/cli/client/director.rb, line 516 def list_problems(deployment_name) url = "/deployments/#{deployment_name}/problems" get_json(url) end
list_properties(deployment_name)
click to toggle source
# File lib/cli/client/director.rb, line 467 def list_properties(deployment_name) url = "/deployments/#{deployment_name}/properties" get_json(url) end
list_recent_tasks(count = 30, verbose = 1, deployment_name = nil)
click to toggle source
# File lib/cli/client/director.rb, line 153 def list_recent_tasks(count = 30, verbose = 1, deployment_name = nil) if deployment_name get_json("/tasks?limit=#{count}&verbose=#{verbose}&deployment=#{deployment_name}") else get_json("/tasks?limit=#{count}&verbose=#{verbose}") end end
list_releases()
click to toggle source
# File lib/cli/client/director.rb, line 119 def list_releases get_json('/releases') end
list_running_tasks(verbose = 1, deployment_name = nil)
click to toggle source
# File lib/cli/client/director.rb, line 145 def list_running_tasks(verbose = 1, deployment_name = nil) if deployment_name get_json("/tasks?state=processing,cancelling,queued&verbose=#{verbose}&deployment=#{deployment_name}") else get_json("/tasks?state=processing,cancelling,queued&verbose=#{verbose}") end end
list_snapshots(deployment_name, job = nil, index = nil)
click to toggle source
# File lib/cli/client/director.rb, line 484 def list_snapshots(deployment_name, job = nil, index = nil) if job && index url = "/deployments/#{deployment_name}/jobs/#{job}/#{index}/snapshots" else url = "/deployments/#{deployment_name}/snapshots" end get_json(url) end
list_stemcells()
click to toggle source
# File lib/cli/client/director.rb, line 115 def list_stemcells get_json('/stemcells') end
list_vms(name)
click to toggle source
# File lib/cli/client/director.rb, line 201 def list_vms(name) _, body = get_json_with_status("/deployments/#{name}/vms") body end
login(username, password)
click to toggle source
# File lib/cli/client/director.rb, line 62 def login(username, password) @credentials = BasicCredentials.new(username, password) authenticated? end
match_compiled_packages(manifest_yaml)
click to toggle source
# File lib/cli/client/director.rb, line 185 def match_compiled_packages(manifest_yaml) url = '/packages/matches_compiled' status, body = post(url, 'text/yaml', manifest_yaml) if status == 200 JSON.parse(body) else err(parse_error_message(status, body)) end end
match_packages(manifest_yaml)
click to toggle source
# File lib/cli/client/director.rb, line 174 def match_packages(manifest_yaml) url = '/packages/matches' status, body = post(url, 'text/yaml', manifest_yaml) if status == 200 JSON.parse(body) else err(parse_error_message(status, body)) end end
perform_cloud_scan(deployment_name, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 509 def perform_cloud_scan(deployment_name, options = {}) options = options.dup url = "/deployments/#{deployment_name}/scans" request_and_track(:post, url, options) end
post(uri, content_type = nil, payload = nil, headers = {}, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 729 def post(uri, content_type = nil, payload = nil, headers = {}, options = {}) request(:post, uri, content_type, payload, headers, options) end
put(uri, content_type = nil, payload = nil, headers = {}, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 733 def put(uri, content_type = nil, payload = nil, headers = {}, options = {}) request(:put, uri, content_type, payload, headers, options) end
request_and_track(method, uri, options = {})
click to toggle source
Perform director HTTP request and track director task (if request started one). @param [Symbol] method HTTP method @param [String] uri URI @param [Hash] options Request and tracking options
# File lib/cli/client/director.rb, line 644 def request_and_track(method, uri, options = {}) options = options.dup content_type = options.delete(:content_type) payload = options.delete(:payload) track_opts = options http_status, _, headers = request(method, uri, content_type, payload) location = headers[:location] redirected = [302, 303].include? http_status task_id = nil if redirected if location =~ /\/tasks\/(\d+)\/?$/ # Looks like we received task URI task_id = $1 if @track_tasks tracker = Bosh::Cli::TaskTracking::TaskTracker.new(self, task_id, track_opts) status = tracker.track else status = :running end else status = :non_trackable end else status = :failed end [status, task_id] end
restore_db(filename)
click to toggle source
# File lib/cli/client/director.rb, line 606 def restore_db(filename) upload_without_track('/restore', filename, { content_type: 'application/x-compressed' }) end
setup_ssh(deployment_name, job, id, user, public_key, password, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 307 def setup_ssh(deployment_name, job, id, user, public_key, password, options = {}) options = options.dup url = "/deployments/#{deployment_name}/ssh" payload = { 'command' => 'setup', 'deployment_name' => deployment_name, 'target' => { 'job' => job, 'indexes' => [id].compact, # for backwards compatibility with old director 'ids' => [id].compact, }, 'params' => { 'user' => user, 'public_key' => public_key, 'password' => password } } options[:payload] = JSON.generate(payload) options[:content_type] = 'application/json' request_and_track(:post, url, options) end
take_snapshot(deployment_name, job = nil, index = nil, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 472 def take_snapshot(deployment_name, job = nil, index = nil, options = {}) options = options.dup if job && index url = "/deployments/#{deployment_name}/jobs/#{job}/#{index}/snapshots" else url = "/deployments/#{deployment_name}/snapshots" end request_and_track(:post, url, options) end
update_cloud_config(cloud_config_yaml)
click to toggle source
# File lib/cli/client/director.rb, line 701 def update_cloud_config(cloud_config_yaml) status, _ = post('/cloud_configs', 'text/yaml', cloud_config_yaml) status == 201 end
update_property(deployment_name, property_name, value)
click to toggle source
# File lib/cli/client/director.rb, line 451 def update_property(deployment_name, property_name, value) url = "/deployments/#{deployment_name}/properties/#{property_name}" payload = JSON.generate('value' => value) put(url, 'application/json', payload) end
update_runtime_config(runtime_config_yaml)
click to toggle source
# File lib/cli/client/director.rb, line 717 def update_runtime_config(runtime_config_yaml) status, _ = post('/runtime_configs', 'text/yaml', runtime_config_yaml) status == 201 end
upload_and_track(method, uri, filename, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 675 def upload_and_track(method, uri, filename, options = {}) file = FileWithProgressBar.open(filename, 'r') request_and_track(method, uri, options.merge(:payload => file)) ensure file.stop_progress_bar if file end
upload_release(filename, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 219 def upload_release(filename, options = {}) options = options.dup options[:content_type] = 'application/x-compressed' upload_and_track(:post, releases_path(options), filename, options) end
upload_remote_release(release_location, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 226 def upload_remote_release(release_location, options = {}) options = options.dup payload = { 'location' => release_location } options[:payload] = JSON.generate(payload) options[:content_type] = 'application/json' request_and_track(:post, releases_path(options), options) end
upload_remote_stemcell(stemcell_location, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 97 def upload_remote_stemcell(stemcell_location, options = {}) options = options.dup payload = { 'location' => stemcell_location } payload[:sha1] = options[:sha1] if options[:sha1] options[:payload] = JSON.generate(payload) options[:content_type] = 'application/json' request_and_track(:post, stemcells_path(options), options) end
upload_stemcell(filename, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 90 def upload_stemcell(filename, options = {}) options = options.dup options[:content_type] = 'application/x-compressed' upload_and_track(:post, stemcells_path(options), filename, options) end
upload_without_track(uri, filename, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 682 def upload_without_track(uri, filename, options = {}) file = FileWithProgressBar.open(filename, 'r') status, _ = post(uri, options[:content_type], file, {}, options) status ensure file.stop_progress_bar if file end
uuid()
click to toggle source
# File lib/cli/client/director.rb, line 42 def uuid @uuid ||= get_status['uuid'] end
wait_until_ready()
click to toggle source
# File lib/cli/client/director.rb, line 55 def wait_until_ready num_retries.times do return if exists? sleep retry_wait_interval end end
Private Instance Methods
add_query_string(url, parts)
click to toggle source
# File lib/cli/client/director.rb, line 950 def add_query_string(url, parts) if parts.size > 0 "#{url}?#{URI.encode_www_form(parts)}" else url end end
director_name()
click to toggle source
# File lib/cli/client/director.rb, line 747 def director_name @director_name ||= get_status['name'] end
generate_http_client()
click to toggle source
# File lib/cli/client/director.rb, line 843 def generate_http_client @http_client ||= HTTPClient.new.tap do |http_client| http_client.send_timeout = API_TIMEOUT http_client.receive_timeout = API_TIMEOUT http_client.connect_timeout = CONNECT_TIMEOUT end end
get_json(url)
click to toggle source
# File lib/cli/client/director.rb, line 935 def get_json(url) status, body = get_json_with_status(url) raise AuthError if status == 401 raise DirectorError, "Director HTTP #{status}" if status != 200 body end
get_json_with_status(url)
click to toggle source
# File lib/cli/client/director.rb, line 942 def get_json_with_status(url) status, body, _ = get(url, 'application/json') body = JSON.parse(body) if status == 200 [status, body] rescue JSON::ParserError raise DirectorError, "Cannot parse director response: #{body}" end
parse_error_message(status, body, uri)
click to toggle source
# File lib/cli/client/director.rb, line 816 def parse_error_message(status, body, uri) parsed_body = JSON.parse(body.to_s) rescue {} if parsed_body['code'] && parsed_body['description'] 'Error %s: %s' % [parsed_body['code'], parsed_body['description']] elsif status == 404 "The #{director_name} bosh director doesn't understand the following API call: #{uri}." + " The bosh deployment may need to be upgraded." else 'HTTP %s: %s' % [status, body] end end
perform_http_request(method, uri, payload = nil, headers = {}, &block)
click to toggle source
# File lib/cli/client/director.rb, line 851 def perform_http_request(method, uri, payload = nil, headers = {}, &block) http_client = generate_http_client if @ca_cert.nil? http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE http_client.ssl_config.verify_callback = Proc.new {} else unless File.exists?(@ca_cert) err('Invalid ca certificate path') end parsed_url = nil begin parsed_url = URI.parse(uri) rescue => e err("Failed to parse director URL: #{e.message}") end unless parsed_url.instance_of?(URI::HTTPS) err('CA certificate cannot be used with HTTP protocol') end # pass in client certificate begin cert_store = OpenSSL::X509::Store.new cert_store.add_file(@ca_cert) rescue OpenSSL::X509::StoreError => e err("Invalid SSL Cert for '#{uri}': #{e.message}") end http_client.ssl_config.cert_store = cert_store end if @credentials @credentials.refresh unless payload.nil? headers['Authorization'] = @credentials.authorization_header end response = http_client.request(method, uri, { :body => payload, :header => headers, }, &block) if !response.nil? && response.code == 401 if !payload.nil? return response end if @credentials.nil? || !@credentials.refresh raise AuthError end headers['Authorization'] = @credentials.authorization_header response = http_client.request(method, uri, { :body => payload, :header => headers, }, &block) end response rescue URI::Error, SocketError, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::ECONNRESET, Timeout::Error, HTTPClient::TimeoutError, HTTPClient::KeepAliveDisconnected, OpenSSL::SSL::SSLError, OpenSSL::X509::StoreError => e if e.is_a?(OpenSSL::SSL::SSLError) && e.message.include?('certificate verify failed') err("Invalid SSL Cert for '#{uri}': #{e.message}") end raise DirectorInaccessible, "cannot access director (#{e.message})" rescue HTTPClient::BadResponseError => e err("Received bad HTTP response from director: #{e}") # HTTPClient doesn't have a root exception but instead subclasses RuntimeError rescue RuntimeError => e say("Perform request #{method}, #{uri}, #{headers.inspect}, #{payload.inspect}") err("REST API call exception: #{e}") end
releases_path(options = {})
click to toggle source
# File lib/cli/client/director.rb, line 751 def releases_path(options = {}) path = '/releases' params = [:rebase, :skip_if_exists, :fix].select { |p| options[p] }.map { |p| "#{p}=true" } params.push "sha1=#{options[:sha1]}" unless options[:sha1].blank? path << "?#{params.join('&')}" unless params.empty? path end
request(method, uri, content_type = nil, payload = nil, headers = {}, options = {})
click to toggle source
# File lib/cli/client/director.rb, line 765 def request(method, uri, content_type = nil, payload = nil, headers = {}, options = {}) headers = headers.dup headers['Content-Type'] = content_type if content_type headers['Host'] = @director_uri.host tmp_file = nil response_reader = nil if options[:file] tmp_file = File.open(File.join(Dir.mktmpdir, 'streamed-response'), 'w') response_reader = lambda { |part| tmp_file.write(part) } end response = try_to_perform_http_request( method, "#{@scheme}://#{@director_host}:#{@port}#{uri}", payload, headers, num_retries, retry_wait_interval, &response_reader ) if options[:file] tmp_file.close body = tmp_file.path else body = response.body end if DIRECTOR_HTTP_ERROR_CODES.include?(response.code) if response.code == 404 raise ResourceNotFound, parse_error_message(response.code, body, uri) else raise DirectorError, parse_error_message(response.code, body, uri) end end headers = response.headers.inject({}) do |hash, (k, v)| # Some HTTP clients symbolize headers, some do not. # To make it easier to switch between them, we try # to symbolize them ourselves. hash[k.to_s.downcase.gsub(/-/, '_').to_sym] = v hash end [response.code, body, headers] rescue SystemCallError => e raise DirectorError, "System call error while talking to director: #{e}" end
stemcells_path(options = {})
click to toggle source
# File lib/cli/client/director.rb, line 759 def stemcells_path(options = {}) path = '/stemcells' path << "?fix=true" if options[:fix] path end
try_to_perform_http_request(method, uri, payload, headers, num_retries, retry_wait_interval, &response_reader)
click to toggle source
# File lib/cli/client/director.rb, line 830 def try_to_perform_http_request(method, uri, payload, headers, num_retries, retry_wait_interval, &response_reader) num_retries.downto(1) do |n| begin return perform_http_request(method, uri, payload, headers, &response_reader) rescue DirectorInaccessible warning("cannot access director, trying #{n-1} more times...") if n != 1 raise if n == 1 sleep(retry_wait_interval) end end end