class Morpheus::Cli::CurlCommand
Public Instance Methods
handle(args)
click to toggle source
# File lib/morpheus/cli/commands/curl_command.rb, line 7 def handle(args) curl_method = nil curl_data = nil show_progress = false options = {} optparse = Morpheus::Cli::OptionParser.new do|opts| opts.banner = "Usage: morpheus curl [path]" opts.on( '-p', '--pretty', "Print result as parsed JSON. Alias for -j" ) do options[:json] = true end opts.on( '-X', '--request METHOD', "HTTP request method. Default is GET" ) do |val| curl_method = val end opts.on( '--post', "Set the HTTP request method to POST" ) do curl_method = "POST" end opts.on( '--put', "Set the HTTP request method to PUT" ) do curl_method = "POST" end opts.on( '--delete', "Set the HTTP request method to DELETE" ) do curl_method = "DELETE" end opts.on( '--data DATA', String, "HTTP request body for use with POST and PUT, typically JSON." ) do |val| begin options[:payload] = JSON.parse(val.to_s) rescue => ex raise ::OptionParser::InvalidOption.new("Failed to parse payload as JSON. Error: #{ex.message}") end end opts.on('--absolute', "Absolute path, skip the addition of path prefix '/api/'") do options[:absolute_path] = true end opts.on('--inspect', "Inspect response, prints headers. By default only the body is printed.") do options[:inspect_response] = true end build_standard_api_options(opts, options) opts.footer = <<-EOT Execute an HTTP request against the remote appliance api to an arbitrary path. [path] is required. This is the path to path to request. By default By default the "/api" prefix is included in the request path. The --absolute option ban be used to supress this. Examples: morpheus curl "/api/whoami" morpheus curl whoami morpheus curl apps -r demo EOT end optparse.parse!(args) verify_args!(args:args, optparse:optparse, count: 1) # establish api client with connection, skips verification so check for appliance is done afterwards @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true})) if !@appliance_name raise_command_error "#{command_name} requires a remote to be specified, use -r [remote] or set the active remote with `remote use`" end # determine curl url, base_url is automatically applied api_path = args[0].to_s.strip # by default /api/ prefix is prepended if options[:absolute_path] || api_path.start_with?("http:") || api_path.start_with?("https:") api_path = api_path else api_path = "/#{api_path}" unless api_path.start_with?("/") api_path = "/api#{api_path}" unless api_path.start_with?("/api") end # build query parameters from --query k=v query_params = parse_query_options(options) # build payload from --payload '{}' and --option k=v payload = parse_payload(options) request_opts = {} request_opts[:method] = curl_method ? curl_method.to_s.downcase.to_sym : :get request_opts[:url] = api_path request_opts[:headers] = options[:headers] if options[:headers] request_opts[:params] = query_params request_opts[:payload] = payload # if [:post, :put].include?(request_opts[:method]) request_opts[:parse_json] = false @api_client.setopts(options) if options[:dry_run] print_dry_run @api_client.dry.execute(request_opts) return end api_response = nil json_response = nil begin api_response = @api_client.execute(request_opts) rescue ::RestClient::Exception => e exit_code = 1 err = e.message #raise e api_response = e.response # did not get a response? if api_response.nil? print_rest_exception(e, options) return 1, e.message end end if api_response.nil? print_rest_exception(e, options) return 1, e.message end response_is_ok = (api_response.code.to_i >= 200 && api_response.code.to_i < 400) response_is_json = api_response.headers[:content_type].to_s.start_with?("application/json") if response_is_json && options[:inspect_response] != true # render as json by default, so -f just works # options[:json] = true unless options[:csv] || options[:yaml] begin json_response = JSON.parse(api_response.body.to_s) rescue => e puts_error "Failed to parse response as JSON. Error: #{e}" # json_response = {} end # this should be default behavior, but use the first key if it is a Hash or Array object_key = nil if json_response && json_response.keys.first && [Hash,Array].include?(json_response[json_response.keys.first].class) object_key = json_response.keys.first end render_response(json_response, options, object_key) do output = "" output << red if !response_is_ok # just render the json by default, non pretty.. output << JSON.fast_generate(json_response) output << "\n" output << reset if exit_code == 1 print output elsif print_error output end end else output = "" output << red if !response_is_ok if options[:inspect_response] # instead http response (version and headers) output << "HTTP/#{api_response.net_http_res.http_version} #{api_response.code}\n" api_response.net_http_res.each_capitalized.each do |k,v| output << "#{k}: #{v}\n" end output << "\n" output << api_response.body.to_s else output << api_response.body.to_s end output << "\n" output << reset if exit_code == 0 print output elsif print_error output end end return exit_code, err end