Replace BASH curl with Ruby equivalent - ruby

I am trying to replace piece of shell curl in my ruby with something more native like 'open-uri', but failing and getting: '401 Authorization Required'
I'm trying to replace this:
status = system("curl -Is -w '%{http_code}\\n' --digest -u #{usr}:#{psw} https://#{source}/ -o /dev/null")
With this:
require 'open-uri'
status = open("https://#{source}/", :http_basic_authentication=>[usr, psw])
But still getting 401. Any idea?
Thank you

If you hit any redirects, this could be your problem:
if redirect
...
if options.include? :http_basic_authentication
# send authentication only for the URI directly specified.
options = options.dup
options.delete :http_basic_authentication
end
end

Related

How to get the error summary separately from a response body using curl in shell script

I am trying to get the status code and exit status from the response of an api request using curl in shell script.
status_code=$(curl --write-out %{http_code} --silent --output /dev/null -X POST http://..............)
exit_status="$?"
echo "$status_code"
echo "$exit_status"
I am getting both the things.But now i also want the error summary(if its there any) from the reponse and to be printed.How can i do that?
Below is the example of my response code
{
"errorCode": "E0000014",
"errorSummary": "Update of credentials failed",
"errorLink": "E0000014",
"errorId": "oaeKE7Weyp7RsKYDNR2V0Sw9w",
"errorCauses": [
{
"errorSummary": "Old Password is not correct"
}
]
}
I want to get the errorSummary inside the errorCauses i.e. I want to print the "Old Password is not Correct" string(Or whatever the strings come). I have tried but couldn't find any solution for it
Change curl to store the response document (instead of sending it to /dev/null), and use jq to extract the first components of the errorCauses array.
curl ... -output response.txt -X ...
exit_status="$?"
...
jq '.errorCauses[0].errorSummary' < response.txt

How to pass array as an argument to a Ruby function from command line?

I want to call Ruby function from command line with array as an argument.
Script name is test.rb
In below code Environments are like test,dev,uat.', am passing as ['test','dev','uat']
I have tried as below:
ruby -r "./test.rb" -e "start_services '['dev','test','uat']','developer','welcome123'"
def start_services(environments,node_user_name,node_password)
environments.each do |env|
puts env
end
puts node_user_name
puts node_password
end
Output:
-e:1: syntax error, unexpected tIDENTIFIER, expecting end-of-input start_services '['dev','test','uat']','developer',' ^
You clearly want to pass an array as the first parameter into start_services method, so you should do it like this:
$ ruby -r "./test.rb" -e "start_services ['dev','test','uat'],'developer','welcome123'"
# output:
dev
test
uat
developer
welcome123
What you've been trying so far was attempt to pass '[\'dev\',\'test\',\'uat\']' string, which was malformed, because you didn't escape ' characters.
Don't pass your credentials as arguments, any user on your system would be able to see them.
Instead, you could save them as environment variables or in a config file.
if ARGV.size == 0
puts "Here's how to launch this script : ruby #{__FILE__} env_name1 env_name2 ..."
exit
end
# Define those environment variables before launching the script.
# Alternative : write credentials in a json or yml file.
node_username = ENV["NODE_USERNAME"]
node_password = ENV["NODE_PASSWORD"]
ARGV.each do |env|
puts "Launching environment #{env}"
end

How to print the output on the console?

I am trying to show the "curl's" output on the console when I execute it. Below is what I wrote. It prints the statement that I declared in puts for all the hostnames, which is as per designed.
desc "check_app_version <environment> <project>", "checks the /dev/info page of the app"
def check_app_version(environment, project)
check_environment(environment)
machines = `knife node list`.split
machines.each do |hostname|
puts "checking the app-version for #{hostname}"
system("curl --silent -m 5 #{hostname}:8080/dev/info |grep 'Application\|Build'")
end
end
But I don't see anything for the next line which instructs to perform a curl on my servers.
Use the backtick notation to return a string, then return to puts
puts `curl --silent -m 5 #{hostname}:8080/dev/info |grep 'Application\|Build'`
puts `curl --silent -m 5 #{hostname}:8080/dev/info |grep 'Application\\|Build'`

How can I get the output of an ssh command?

I'd like to programmatically check if someone has their SSH keys set up correctly for GitHub. I understand that I can use `ssh -T git#github.com` in Ruby. However, I'd like to keep the ssh output in a variable.
My current code is:
github_response = `ssh -T git#github.com`
unless github_response.start_with?('Hi')
puts 'Please set up your GitHub ssh keys'
end
`ssh -T git#github.com` outputs the response (starting with "Hi"). However the github_response variable is nil.
How can I assign the output of `ssh -T git#github.com` to github_response?
Your example failed because the Hi xxx! You've successfully authenticated.... message is not from stdout, but stderr.
> require 'open3'
=> true
> stdin, stdout, stderr, wait_thr = Open3.popen3('ssh -T git#github.com')
=> [#<IO:fd 8>, #<IO:fd 9>, #<IO:fd 11>, #<Thread:0x007f89ee1149a8 sleep>]
> stdout.gets
=> nil
> stderr.gets
=> "Hi halfelf! You've successfully authenticated, but GitHub does not provide shell access.\n"
You could add -v for verbose output, it will then dump much of the connection info to stdout. From that log you can scrape to find whether the server accepted any of the keys the ssh client offered

Paste to codepad.org using bash or curl

How can I paste to codepad.org from the commandline using curl?
here's a Python script
import urllib
import urllib2
url = 'http://codepad.org'
content=open("myscript.py").read()
values = {'lang' : 'Python',
'code' : content,
'submit':'Submit'}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
for href in the_page.split("</a>"):
if "Link:" in href:
ind=href.index('Link:')
found = href[ind+5:]
for i in found.split('">'):
if '<a href=' in i:
print "The link: " ,i.replace('<a href="',"").strip()
output
$ python python.py
The link: http://codepad.org/W0G8HIzM
Yes, you can do it with curl. Assuming your code is Python and in myfile.python, you can do it like this:
$ curl -d "lang=Python&submit=Submit" --data-urlencode code#myfile.py codepad.org
(Edited to make it work.)
You can also use reval:
reval test.py
reval -l ruby -e 'p 2+2'
reval prog.hs -p # make private

Resources