Why does serverspec connect to the localhost instead of the remote host - ruby

My serverspec example, setup using serverspec-init, then I generated this simple test file ./spec/altspf01/sample_spec.rb
require 'spec_helper'
describe command( '/bin/hostname -s' ) do
its(:stdout) { should match /atlspf01/ }
end
I expect it to ssh to a remote host (atlspf01) and check its hostname (atlspf01). Instead it connects to the localhost (ltipc682).
1) Command "/bin/hostname -s" stdout should match /atlspf01/
Failure/Error: its(:stdout) { should match /atlspf01/ }
expected "ltipc682\n" to match /atlspf01/
Diff:
## -1,2 +1,2 ##
-/atlspf01/
+ltipc682
What have I done wrong?
All code here: https://gist.github.com/neilhwatson/a3f4a26ad8cf27d62307

Serverspec's specs should be run via rake. Otherwise, the spec doesn't know the target host.
However, if you wish to run it via rspec, you could use this workaround:
env TARGET_HOST='atlspf01' rspec spec/atlspf01/sample_spec.rb
Hope this helps.

Related

How to use Net:SSH to upload file from server1 to server2

i have 3 web server : local server 0 ; remote server1 ;remote server2
i want to run local ruby script to upload file in server1 to server2;
how to do it? just use ruby.
i have tried shell util such as expect; it worded but how to use it in ruby?
i also tried
ssh =Net::SSH.start(host,username,:password => password) do |ssh|
remote = Net::SSH.start(host,username,:password=>password)
remote.exec!("mkdir -p path")
result = ssh.exec!("scp local_path root#remote_host:remot_path")
puts result
but this way needs to add ssh_key in each remote web server
how to fix it?

How to mock a 3rd-party library [duplicate]

an important part of my project is to log in into remote server with ssh and do something with files on it:
Net::SSH.start(#host, #username, :password => #password) do |ssh|
ssh.exec!(rename_files_on_remote_server)
end
How to test it?
I think I can have local ssh server on and check file names on it (maybe it could be in my test/spec directory).
Or maybe someone could point me better solution?
I think it's enough to test that you're sending the correct commands to the ssh server. You're application presumably doesn't implement the server - so you have to trust that the server is correctly working and tested.
If you do implement the server then you'd need to test that, but as far as the SSH stuff goes, i'd do some mocking like this (RSpec 2 syntax):
describe "SSH Access" do
let (:ssh_connection) { mock("SSH Connection") }
before (:each) do
Net::SSH.stub(:start) { ssh_connection }
end
it "should send rename commands to the connection" do
ssh_connection.should_receive(:exec!).ordered.with("expected command")
ssh_connection.should_receive(:exec!).ordered.with("next expected command")
SSHAccessClass.rename_files!
end
end
Your suggested solution is similar to how I've done it before:
Log into the local machine. For convenience you could use 'localhost' or '127.0.0.1', but for a better simulation of network activity you might want to use the full hostname. On Mac OS and Linux you can grab the host easily by using:
`hostname`
or
require 'socket'
hostname = Socket.gethostname
which should be universal.
From there create or touch a file on the local machine after logging in, so you can test for the change with your test code.

How to get list of file names from a private remote ip

I am having access to ServerA and don't have access to ServerB.I want to get the list of file names from ServerB via serverA.
I am logging into ServerA using the following command and doing some functions.
Net::SSH.start(url, user, forward_agent: true) do |ssh|
ssh.exec('scp -r source dest')
end
But i want to get the list the file names from ServerB via ServerA. How can i do it ?
Eg: Dir["/path/*.txt"] or ls *.txt
OS: Linux
Language: ruby
You can use ssh to execute a remote command:
ssh username#hostname ls -l /foo/bar
If the ls command is not enough you can always use find or any other command.
EDIT
Here you have a full working script
require 'net/ssh'
Net::SSH.start('localhost', 'user', :password => "password") do |ssh|
stdout = ''
ssh.exec!("ls -l /tmp") do |channel, stream, data|
stdout << data if stream == :stdout
end
puts stdout
end
working with ruby 2.1.2p95
Also make sure you have ruby compiled with OpenSSL:
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
EDIT 2
What you need is a tunnel, for more information check the official documentation.
require 'net/ssh/gateway'
gateway = Net::SSH::Gateway.new('host', 'user')
gateway.ssh("host.private", "user") do |ssh|
puts ssh.exec!("hostname")
end
gateway.open("host.private", 80) do |port|
Net::HTTP.get_print("127.0.0.1", "/path", port)
end
gateway.shutdown!

Net::SSH does not seem to connect to remote host

Following the syntax from http://net-ssh.github.io/net-ssh/
Net::SSH.start('remotehost', 'ava') do |ssh|
puts `hostname`
end
It prints the name of current hostname rather than remote hostname. What is wrong?
You should use as below :
Net::SSH.start('remotehost', 'ava') do |ssh|
puts ssh.host
end
As ssh is an instance of Net::SSH::Connection::Session class And if you browse the documentation,you will get the method #host,which will give you the desired result.

Testing ssh connection

an important part of my project is to log in into remote server with ssh and do something with files on it:
Net::SSH.start(#host, #username, :password => #password) do |ssh|
ssh.exec!(rename_files_on_remote_server)
end
How to test it?
I think I can have local ssh server on and check file names on it (maybe it could be in my test/spec directory).
Or maybe someone could point me better solution?
I think it's enough to test that you're sending the correct commands to the ssh server. You're application presumably doesn't implement the server - so you have to trust that the server is correctly working and tested.
If you do implement the server then you'd need to test that, but as far as the SSH stuff goes, i'd do some mocking like this (RSpec 2 syntax):
describe "SSH Access" do
let (:ssh_connection) { mock("SSH Connection") }
before (:each) do
Net::SSH.stub(:start) { ssh_connection }
end
it "should send rename commands to the connection" do
ssh_connection.should_receive(:exec!).ordered.with("expected command")
ssh_connection.should_receive(:exec!).ordered.with("next expected command")
SSHAccessClass.rename_files!
end
end
Your suggested solution is similar to how I've done it before:
Log into the local machine. For convenience you could use 'localhost' or '127.0.0.1', but for a better simulation of network activity you might want to use the full hostname. On Mac OS and Linux you can grab the host easily by using:
`hostname`
or
require 'socket'
hostname = Socket.gethostname
which should be universal.
From there create or touch a file on the local machine after logging in, so you can test for the change with your test code.

Resources