Translate Curl to Ruby (New Relic API) - ruby

I am extremly new to ruby, but I am playing around with it. Could someone help me translate this curl command to Ruby ?
I have been having a difficult time trying to adapt other ruby examples to fit my needs.
curl -X GET 'https://api.newrelic.com/v2/servers.json' \
-H 'X-Api-Key:12345689' -i \
-G -d 'filter[host]=server1'
Ruby Code:
require 'net/http'
uri = URI.parse('https://api.newrelic.com/v2/servers.json')
request = Net::HTTP::Get.new uri.request_uri
res = Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https') {|http| http.request request}
request.initialize_http_header({'X-Api-Key' => '12345689'})
request.initialize_http_header({'Accept' => 'application/json'})
request.initialize_http_header({'Content-Type' => 'application/json'})
request.set_form_data({"filter[host]" => "server1"})
response = res.request(request)
Error Message:
test.rb:16:in `<main>': undefined method `request' for #<Net::HTTPUnauthorized 401 Unauthorized readbody=true> (NoMethodError)

Should look something like this:
require 'net/http'
uri = URI('https://api.newrelic.com/v2/servers.json')
uri.query = URI.encode_www_form({ 'filter[host]' => 'server1' })
req = Net::HTTP::Get.new(uri)
req['X-Api-Key'] = '123456789'
http = Net::HTTP.new(uri.hostname, uri.port)
http.use_ssl = true
response = http.request(req)
p response.read_body

In Ruby, you can simply get the output of a command by using backticks (`), you only had to escape the special characters, like in every other string. So it would be:
`curl -X GET 'https://api.newrelic.com/v2/servers.json' -H 'X-Api-Key:12345689' -i -G -d 'filter[host]=server1'`

Related

Is there any way to directly run our ruby codes from puppet console?

I am new to both Ruby Language and Puppet. I want to run a ruby code which is a converted form of a cURL, from my puppet console.
I am putting the cURL and the converted ruby below.
curl -k -u stg_admin:password -sS -X POST https://www.something.com
As you can see, this is a very basic cURL, and the converted ruby code is-
require 'net/http'
require 'uri'
require 'openssl'
uri = URI.parse("https://www.something.com")
request = Net::HTTP::Post.new(uri)
request.basic_auth("stg_admin", "password")
req_options = {
use_ssl: uri.scheme == "https",
verify_mode: OpenSSL::SSL::VERIFY_NONE,
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
# response.code
# response.body
I know how to exec cURL directly in my puppet class, but my question is "is there any way to call my ruby code directly in puppet's init.pp?"
I'll be greatfull for any suggestion.

Why are the headers skipped in net/http?

If I do the following then the headers are skipped
require 'net/http'
require 'openssl'
require 'ap'
uri = URI("https://test:A234567#www.example.com/data")
http = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https')
request = Net::HTTP::Get.new uri
request['X-appname'] = 'testapp'
request['X-token'] = '1854fac3'
response = http.request request # Net::HTTPResponse object
ap response.body
I get the exact same error if I comment the header lines, so that is why I say they are skipped.
The error is
"<Fault xmlns=\"http://schemas.microsoft.com/ws/2005/05/envelope/none\">
<Code><Value>Receiver</Value><Subcode><Value>NotAuthorized</Value>
</Subcode></Code><Reason><Text xml:lang=\"en-US\">Wrong username or
password.</Text></Reason></Fault>"
If I in Bash do
curl -H 'X-appname: testapp' -H 'X-token: 1854fac3' https://test:A234567#www.example.com/data
then it works.
Question
Can anyone see why it doesn't wotk in by Ruby script?
Looks like the URL requires HTTP Basic Auth. The error in your case is with respect to user/password - Wrong username or password., and not related to missing headers
You should have something like this in your code:
request.basic_auth 'test', 'A234567'
and URI should be
uri = URI("https://www.example.com/data")

Header information getting lost in POST response

In a ruby POST call I am expecting some custom header named 'Authentication-Token', which is received when called from any other REST client. But when called from ruby script I am getting all headers except this required header.
Below is the code
require 'net/http'
require 'json'
require 'uri'
uri = URI.parse('http://ashish-1:9090/csm/login')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data({"username" => 'test', "password" => 'test'})
request.add_field("Authentication-Token", "")
request.add_field("Authorization", "")
request.add_field("Content-Type", "application/json")
response = http.request(request)
puts response
puts response.code
puts "Headers: #{response.to_hash}" #prints all headers except Authentication-Token
puts response["session-id"] # get printed
puts response["Authentication-Token"] # blank
Any idea what is missing?
Thanks,
Ashish

Post png image to pngcrush with Ruby

In ruby, I want to get the same result than the code below but without using curl:
curl_output = `curl -X POST -s --form "input=##{png_image_file};type=image/png" http://pngcrush.com/crush > #{compressed_png_file}`
I tried this:
#!/usr/bin/env ruby
require "net/http"
require "uri"
# Image to crush
png_image_path = "./media/images/foo.png"
# Crush with http://pngcrush.com/
png_compress_uri = URI.parse("http://pngcrush.com/crush")
png_image_data = File.read(png_image_path)
req = Net::HTTP.new(png_compress_uri.host, png_compress_uri.port)
headers = {"Content-Type" => "image/png" }
response = req.post(png_compress_uri.path, png_image_data, headers)
p response.body
# => "Input is empty, provide a PNG image."
The problem with your code is you do not send required parameter to the server ("input" for http://pngcrush.com/crush). This works for me:
require 'net/http'
require 'uri'
uri = URI.parse('http://pngcrush.com/crush')
form_data = [
['input', File.open('filename.png')]
]
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new uri
# prepare request parameters
request.set_form(form_data, 'multipart/form-data')
response = http.request(request)
# save crushed image
open('crushed.png', 'wb') do |file|
file.write(response.body)
end
But I suggest you to use RestClient. It encapsulates net/http with cool features like multipart form data and you need just a few lines of code to do the job:
require 'rest_client'
resp = RestClient.post('http://pngcrush.com/crush',
:input => File.new('filename.png'))
# save crushed image
open('crushed.png', 'wb') do |file|
file.write(resp)
end
Install it with gem install rest-client

REST HTTPS login with Ruby - Connection Reset by peer

I am trying to do a REST API login over HTTPS. I keep getting Connection reset by peer (Errno::ECONNRESET):
require 'net/http'
require 'net/https'
uri = URI.parse("https://.../login.jsp")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path)
req['userid'] = 'myemail%40hostname.com'
req['passwd'] = 'mypassword'
res = https.request(req)
puts res.body
I'm not sure what I'm doing wrong. The corresponding cURL command that works without a hitch is:
curl --user-agent "MyUserAgent" --cookie-jar cookiefile -o - --data 'userid=myemail%40hostname.com&passwd=mypassword' https://.../login.jsp
(I haven't gotten to dealing with capturing the cookie file yet, I'm just trying to get the login to work)
Suggestions appreciated! Thanks!!
Turned out that I needed to set form data for this work.
require 'net/http'
require 'openssl'
uri = URI.parse("https://.../login.jsp")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri)
req.set_form_data('userid' => 'myemail#hostname.com', 'passwd' => 'mypassword')
res = https.request(req)
puts res

Resources