Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/vmfloaty.rb
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ def run # rubocop:disable Metrics/AbcSize

FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1

service.ssh(verbose, host_os, use_token)
service.ssh(verbose, host_os, use_token, options.ondemand)
exit 0
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/vmfloaty/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def wait_for_request(verbose, requestid)
@service_object.wait_for_request verbose, requestid, url
end

def ssh(verbose, host_os, use_token = true)
def ssh(verbose, host_os, use_token = true, ondemand = nil)
token_value = nil
if use_token
begin
Expand All @@ -97,7 +97,7 @@ def ssh(verbose, host_os, use_token = true)
FloatyLogger.info 'Could not get token... requesting vm without a token anyway...'
end
end
Ssh.ssh(verbose, self, host_os, token_value)
Ssh.ssh(verbose, self, host_os, token_value, ondemand)
end

def query(verbose, hostname)
Expand Down
36 changes: 27 additions & 9 deletions lib/vmfloaty/ssh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,45 @@ def self.which(cmd)
nil
end

def self.command_string(verbose, service, host_os, use_token)
def self.command_string(verbose, service, host_os, use_token, ondemand = nil)
ssh_path = which('ssh')
raise 'Could not determine path to ssh' unless ssh_path

os_types = {}
os_types = Utils.generate_os_hash([host_os])
os_types[host_os] = 1

response = service.retrieve(verbose, os_types, use_token)
response = service.retrieve(verbose, os_types, use_token, ondemand)
raise "Could not get vm from #{service.type}:\n #{response}" unless response['ok']

user = /win/.match?(host_os) ? 'Administrator' : 'root'

hostname = response[host_os]['hostname']
hostname = response[host_os]['hostname'][0] if response[host_os]['hostname'].is_a?(Array)
hostname = "#{hostname}.#{response['domain']}" unless hostname.end_with?('puppetlabs.net')
if ondemand
requestid = response['request_id']
service.wait_for_request(verbose, requestid)
hosts = service.check_ondemandvm(verbose, requestid, service.url)
if hosts['domain'].nil?
hostname = hosts[host_os]['hostname']
hostname = hosts[host_os]['hostname'][0] if hosts[host_os]['hostname'].is_a?(Array)
else
# Provides backwards compatibility with VMPooler API v1
hostname = "#{hosts[host_os]['hostname']}.#{hosts['domain']}"
hostname = "#{hosts[host_os]['hostname'][0]}.#{hosts['domain']}" if hosts[host_os]['hostname'].is_a?(Array)
end
else
if response['domain'].nil?
hostname = response[host_os]['hostname']
hostname = response[host_os]['hostname'][0] if response[host_os]['hostname'].is_a?(Array)
else
# Provides backwards compatibility with VMPooler API v1
hostname = "#{response[host_os]['hostname']}.#{response['domain']}"
hostname = "#{response[host_os]['hostname'][0]}.#{response['domain']}" if response[host_os]['hostname'].is_a?(Array)
end
end

"#{ssh_path} #{user}@#{hostname}"
end

def self.ssh(verbose, service, host_os, use_token)
cmd = command_string(verbose, service, host_os, use_token)
def self.ssh(verbose, service, host_os, use_token, ondemand)
cmd = command_string(verbose, service, host_os, use_token, ondemand)
# TODO: Should this respect more ssh settings? Can it be configured
# by users ssh config and does this respect those settings?
Kernel.exec(cmd)
Expand Down
19 changes: 17 additions & 2 deletions lib/vmfloaty/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Utils
# TODO: Takes the json response body from an HTTP GET
# request and "pretty prints" it
def self.standardize_hostnames(response_body)
# vmpooler response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`:
# vmpooler api v1 response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`:
# {
# "ok": true,
# "domain": "delivery.mycompany.net",
Expand All @@ -21,6 +21,17 @@ def self.standardize_hostnames(response_body)
# }
# }

# vmpooler api v2 response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`:
# {
# "ok": true,
# "ubuntu-1610-x86_64": {
# "hostname": ["gdoy8q3nckuob0i.pooler.example.com", "ctnktsd0u11p9tm.pooler.example.com"]
# },
# "centos-7-x86_64": {
# "hostname": "dlgietfmgeegry2.pooler.example.com"
# }
# }

# nonstandard pooler response body example when `floaty get` arguments are `solaris-11-sparc=2 ubuntu-16.04-power8`:
# {
# "ok": true,
Expand Down Expand Up @@ -98,7 +109,11 @@ def self.print_fqdn_for_host(service, hostname, host_data)

puts abs_hostnames.join("\n")
when 'Pooler'
puts "#{hostname}.#{host_data['domain']}"
if host_data['domain'].nil?
puts hostname
else
puts "#{hostname}.#{host_data['domain']}"
end
when 'NonstandardPooler'
puts host_data['fqdn']
else
Expand Down
107 changes: 85 additions & 22 deletions spec/vmfloaty/ssh_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,109 @@
require 'vmfloaty/ssh'

class ServiceStub
def retrieve(_verbose, os_types, _use_token)
def retrieve(_verbose, os_types, _use_token, ondemand)
if os_types.keys[0] == 'abs_host_string'
return {
os_types.keys[0] => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net'] },
'ok' => true
}
end

{
os_types.keys[0] => { 'hostname' => 'vmpooler-hostname' },
'domain' => 'delivery.puppetlabs.net',
'ok' => true
}
elsif os_types.keys[0] == 'vmpooler_api_v2_host_string'
return {
os_types.keys[0] => { 'hostname' => ['vmpooler-v2-hostname.delivery.puppetlabs.net'] },
'ok' => true
}

else
return {
os_types.keys[0] => { 'hostname' => 'vmpooler-v1-hostname' },
'domain' => 'delivery.puppetlabs.net',
'ok' => true
}
end
end

def type
return 'abs' if os_types == 'abs_host_string'
return 'vmpooler' if os_types == 'vmpooler_host_string'
return 'vmpooler' if os_types == 'vmpooler_api_v1_host_string' || os_types == 'vmpooler_api_v2_host_string'
end

def wait_for_request(verbose, requestid)
return true
end
end

describe Ssh do
before :each do
end

it 'gets a hostname string for abs' do
verbose = false
service = ServiceStub.new
host_os = 'abs_host_string'
use_token = false
cmd = Ssh.command_string(verbose, service, host_os, use_token)
expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/)
context "for pooled requests" do
it 'gets a hostname string for abs' do
verbose = false
service = ServiceStub.new
host_os = 'abs_host_string'
use_token = false
cmd = Ssh.command_string(verbose, service, host_os, use_token)
expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/)
end

it 'gets a hostname string for vmpooler api v1' do
verbose = true
service = ServiceStub.new
host_os = 'vmpooler_api_v1_host_string'
use_token = false
cmd = Ssh.command_string(verbose, service, host_os, use_token)
expect(cmd).to match(/ssh root@vmpooler-v1-hostname.delivery.puppetlabs.net/)
end

it 'gets a hostname string for vmpooler api v2' do
verbose = false
service = ServiceStub.new
host_os = 'vmpooler_api_v2_host_string'
use_token = false
cmd = Ssh.command_string(verbose, service, host_os, use_token)
expect(cmd).to match(/ssh root@vmpooler-v2-hostname.delivery.puppetlabs.net/)
end
end

it 'gets a hostname string for vmpooler' do
verbose = false
service = ServiceStub.new
host_os = 'vmpooler_host_string'
use_token = false
cmd = Ssh.command_string(verbose, service, host_os, use_token)
expect(cmd).to match(/ssh root@vmpooler-hostname.delivery.puppetlabs.net/)
context "for ondemand requests" do
let(:service) { ServiceStub.new }
let(:url) { 'http://pooler.example.com' }

it 'gets a hostname string for abs' do
verbose = false
host_os = 'abs_host_string'
use_token = false
ondemand = true
response = {'abs_host_string' => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net']}}
allow(service).to receive(:url)
allow(service).to receive(:check_ondemandvm).and_return(response)
cmd = Ssh.command_string(verbose, service, host_os, use_token, ondemand)
expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/)
end

it 'gets a hostname string for abs' do
verbose = false
host_os = 'vmpooler_api_v1_host_string'
use_token = false
ondemand = true
response = {'vmpooler_api_v1_host_string' => { 'hostname' => ['vmpooler_api_v1_host_string.delivery.puppetlabs.net']}}
allow(service).to receive(:url)
allow(service).to receive(:check_ondemandvm).and_return(response)
cmd = Ssh.command_string(verbose, service, host_os, use_token, ondemand)
expect(cmd).to match(/ssh root@vmpooler_api_v1_host_string.delivery.puppetlabs.net/)
end

it 'gets a hostname string for abs' do
verbose = false
host_os = 'vmpooler_api_v2_host_string'
use_token = false
ondemand = true
response = {'vmpooler_api_v2_host_string' => { 'hostname' => ['vmpooler_api_v2_host_string.delivery.puppetlabs.net']}}
allow(service).to receive(:url)
allow(service).to receive(:check_ondemandvm).and_return(response)
cmd = Ssh.command_string(verbose, service, host_os, use_token, ondemand)
expect(cmd).to match(/ssh root@vmpooler_api_v2_host_string.delivery.puppetlabs.net/)
end
end
end
22 changes: 19 additions & 3 deletions spec/vmfloaty/utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Service
describe Utils do
describe '#standardize_hostnames' do
before :each do
@vmpooler_response_body = '{
@vmpooler_api_v1_response_body = '{
"ok": true,
"domain": "delivery.mycompany.net",
"ubuntu-1610-x86_64": {
Expand All @@ -23,6 +23,15 @@ class Service
"hostname": "dlgietfmgeegry2"
}
}'
@vmpooler_api_v2_response_body = '{
"ok": true,
"ubuntu-1610-x86_64": {
"hostname": ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"]
},
"centos-7-x86_64": {
"hostname": "dlgietfmgeegry2.delivery.mycompany.net"
}
}'
@nonstandard_response_body = '{
"ok": true,
"solaris-10-sparc": {
Expand All @@ -34,8 +43,15 @@ class Service
}'
end

it 'formats a result from vmpooler into a hash of os to hostnames' do
result = Utils.standardize_hostnames(JSON.parse(@vmpooler_response_body))
it 'formats a result from vmpooler v1 api into a hash of os to hostnames' do
result = Utils.standardize_hostnames(JSON.parse(@vmpooler_api_v1_response_body))
expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'],
'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net',
'ctnktsd0u11p9tm.delivery.mycompany.net'])
end

it 'formats a result from vmpooler v2 api into a hash of os to hostnames' do
result = Utils.standardize_hostnames(JSON.parse(@vmpooler_api_v2_response_body))
expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'],
'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net',
'ctnktsd0u11p9tm.delivery.mycompany.net'])
Expand Down