class CloudstackClient::Connection
Constants
- DEF_ASYNC_TIMEOUT
- DEF_POLL_INTERVAL
- DEF_REQ_TIMEOUT
Attributes
Public Class Methods
Source
# File lib/cloudstack_client/connection.rb 19 def initialize(api_url, api_key, secret_key, options = {}) 20 @api_url = api_url 21 @api_key = api_key 22 @secret_key = secret_key 23 @verbose = options[:quiet] ? false : true 24 @debug = options[:debug] ? true : false 25 @symbolize_keys = options[:symbolize_keys] ? true : false 26 @host = options[:host] 27 @read_timeout = options[:read_timeout] || DEF_REQ_TIMEOUT 28 @async_poll_interval = options[:async_poll_interval] || DEF_POLL_INTERVAL 29 @async_timeout = options[:async_timeout] || DEF_ASYNC_TIMEOUT 30 @options = options 31 validate_input! 32 end
Public Instance Methods
Source
# File lib/cloudstack_client/connection.rb 90 def send_async_request(params) 91 data = send_request(params) 92 93 params = { 94 'command' => 'queryAsyncJobResult', 95 'jobid' => data[k('jobid')] 96 } 97 98 max_tries.times do 99 data = send_request(params) 100 print "." if @verbose 101 102 case data[k('jobstatus')] 103 when 1 104 return data[k('jobresult')] 105 when 2 106 raise JobError, "Request failed (#{data[k('jobresultcode')]}): #{data[k('jobresult')][k('errortext')]}." 107 end 108 109 STDOUT.flush if @verbose 110 sleep @async_poll_interval 111 end 112 113 raise TimeoutError, "Asynchronous request timed out." 114 end
Sends an asynchronous request and waits for the response.
The contents of the ‘jobresult’ element are returned upon completion of the command.
Source
# File lib/cloudstack_client/connection.rb 38 def send_request(params) 39 params['response'] = 'json' 40 params['apiKey'] = @api_key 41 print_debug_output JSON.pretty_generate(params) if @debug 42 43 data = params_to_data(params) 44 uri = URI.parse "#{@api_url}?#{data}&signature=#{create_signature(data)}" 45 46 http = Net::HTTP.new(uri.host, uri.port) 47 if uri.scheme == 'https' 48 http.use_ssl = true 49 http.verify_mode = OpenSSL::SSL::VERIFY_NONE 50 end 51 http.read_timeout = @read_timeout 52 53 begin 54 req = Net::HTTP::Get.new(uri.request_uri) 55 req['Host'] = host if host.present? 56 response = http.request(req) 57 rescue 58 raise ConnectionError, "API URL \'#{@api_url}\' is not reachable." 59 end 60 61 begin 62 body = JSON.parse(response.body, symbolize_names: @symbolize_keys).values.first 63 rescue JSON::ParserError 64 raise ParseError, 65 "Response from server is not readable. Check if the API endpoint (#{@api_url}) is valid and accessible." 66 end 67 68 if response.is_a?(Net::HTTPOK) 69 return body unless body.respond_to?(:keys) 70 if body.size == 2 && body.key?(k('count')) 71 return body.reject { |key, _| key == k('count') }.values.first 72 elsif body.size == 1 && body.values.first.respond_to?(:keys) 73 item = body.values.first 74 return (item.is_a?(Array) || item.is_a?(Hash)) ? item : [] 75 else 76 body.reject! { |key, _| key == k('count') } if body.key?(k('count')) 77 body.size == 0 ? [] : body 78 end 79 else 80 message = body[k('errortext')] rescue body 81 raise ApiError, "Status #{response.code}: #{message}." 82 end 83 end
Sends a synchronous request to the CloudStack API and returns the response as a Hash.
Private Instance Methods
Source
# File lib/cloudstack_client/connection.rb 147 def create_signature(data) 148 signature = OpenSSL::HMAC.digest('sha1', @secret_key, data.downcase) 149 signature = Base64.encode64(signature).chomp 150 CGI.escape(signature) 151 end
Source
# File lib/cloudstack_client/connection.rb 157 def escape(input) 158 CGI.escape(input.to_s) 159 .gsub('+', '%20') 160 .gsub(' ', '%20') 161 .gsub('%2A', '*') 162 end
Source
# File lib/cloudstack_client/connection.rb 153 def max_tries 154 (@async_timeout / @async_poll_interval).round 155 end
Source
# File lib/cloudstack_client/connection.rb 126 def params_to_data(params) 127 params_arr = params.sort.map do |key, value| 128 case value 129 when Array # support for maps (Arrays of Hashes) 130 map = [] 131 value.each_with_index do |items, i| 132 items.each {|k, v| map << "#{key}[#{i}].#{k}=#{escape(v)}"} 133 end 134 map.sort.join("&") 135 when Hash # support for maps values of values (Hash values of Hashes) 136 value.each_with_index.map do |(k, v), i| 137 "#{key}[#{i}].key=#{escape(k)}&" + 138 "#{key}[#{i}].value=#{escape(v)}" 139 end.join("&") 140 else 141 "#{key}=#{escape(value)}" 142 end 143 end 144 params_arr.sort.join('&') 145 end
Source
# File lib/cloudstack_client/connection.rb 164 def symbolized_key(name) 165 @symbolize_keys ? name.to_sym : name 166 end
Also aliased as: k
Source
# File lib/cloudstack_client/connection.rb 118 def validate_input! 119 raise InputError, "API URL not set." if @api_url == nil 120 raise InputError, "API KEY not set." if @api_key == nil 121 raise InputError, "API SECRET KEY not set." if @secret_key == nil 122 raise InputError, "ASYNC POLL INTERVAL must be at least 1." if @async_poll_interval < 1.0 123 raise InputError, "ASYNC TIMEOUT must be at least 60." if @async_timeout < 60 124 end