Merge pull request #49 from rodjek/rubocop

Rubocop cleanup
This commit is contained in:
Brian Cain 2019-02-04 09:38:02 -08:00 committed by GitHub
commit d57b168153
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 689 additions and 689 deletions

20
.rubocop.yml Normal file
View file

@ -0,0 +1,20 @@
inherit_from: .rubocop_todo.yml
AllCops:
TargetRubyVersion: 2.4
Style/Documentation:
Enabled: False
Style/HashSyntax:
EnforcedStyle: hash_rockets
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArguments:
EnforcedStyleForMultiline: comma
Layout/AlignHash:
EnforcedHashRocketStyle: table
Layout/IndentHash:
EnforcedStyle: consistent

46
.rubocop_todo.yml Normal file
View file

@ -0,0 +1,46 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2019-02-03 15:31:20 +1100 using RuboCop version 0.63.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 8
Metrics/AbcSize:
Max: 319
# Offense count: 25
# Configuration parameters: CountComments, ExcludedMethods.
# ExcludedMethods: refine
Metrics/BlockLength:
Max: 278
# Offense count: 1
# Configuration parameters: CountBlocks.
Metrics/BlockNesting:
Max: 4
# Offense count: 4
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 394
# Offense count: 4
Metrics/CyclomaticComplexity:
Max: 55
# Offense count: 13
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
Max: 391
# Offense count: 3
Metrics/PerceivedComplexity:
Max: 63
# Offense count: 193
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
Metrics/LineLength:
Max: 285

View file

@ -2,4 +2,4 @@ sudo: false
language: ruby language: ruby
rvm: rvm:
- 2.4 - 2.4
script: rspec spec script: bundle exec rake rubocop spec

View file

@ -1,8 +1,10 @@
# frozen_string_literal: true
source 'https://rubygems.org' source 'https://rubygems.org'
gemspec gemspec
gem 'rake', require: false gem 'rake', :require => false
group :test do group :test do
gem 'rspec', '~> 3.5.0' gem 'rspec', '~> 3.5.0'

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'rubygems' require 'rubygems'
require 'bundler/setup' require 'bundler/setup'
require 'rspec/core/rake_task' require 'rspec/core/rake_task'
@ -9,7 +11,7 @@ $stdout.sync = true
$stderr.sync = true $stderr.sync = true
# Change to the directory of this file. # Change to the directory of this file.
Dir.chdir(File.expand_path('../', __FILE__)) Dir.chdir(File.expand_path(__dir__))
# This installs the tasks that help with gem creation and # This installs the tasks that help with gem creation and
# publishing. # publishing.
@ -26,4 +28,4 @@ RuboCop::RakeTask.new(:rubocop) do |task|
end end
# Default task is to run the unit tests # Default task is to run the unit tests
task default: :spec task :default => :spec

View file

@ -1,6 +1,7 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
require 'vmfloaty' require 'vmfloaty'

View file

@ -1,4 +1,4 @@
#!/usr/bin/env ruby # frozen_string_literal: true
require 'rubygems' require 'rubygems'
require 'commander' require 'commander'
@ -43,22 +43,22 @@ class Vmfloaty
force = options.force force = options.force
if args.empty? if args.empty?
STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs." STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
exit 1 exit 1
end end
os_types = Utils.generate_os_hash(args) os_types = Utils.generate_os_hash(args)
max_pool_request = 5 max_pool_request = 5
large_pool_requests = os_types.select{|_,v| v > max_pool_request} large_pool_requests = os_types.select { |_, v| v > max_pool_request }
if ! large_pool_requests.empty? and ! force if !large_pool_requests.empty? && !force
STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag."
STDERR.puts "Try again with `floaty get --force`" STDERR.puts 'Try again with `floaty get --force`'
exit 1 exit 1
end end
if os_types.empty? if os_types.empty?
STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs." STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
exit 1 exit 1
end end
@ -143,18 +143,18 @@ class Vmfloaty
hostname = args[0] hostname = args[0]
modify_all = options.all modify_all = options.all
if hostname.nil? and !modify_all if hostname.nil? && !modify_all
STDERR.puts "ERROR: Provide a hostname or specify --all." STDERR.puts 'ERROR: Provide a hostname or specify --all.'
exit 1 exit 1
end end
running_vms = modify_all ? service.list_active(verbose) : hostname.split(",") running_vms = modify_all ? service.list_active(verbose) : hostname.split(',')
tags = options.tags ? JSON.parse(options.tags) : nil tags = options.tags ? JSON.parse(options.tags) : nil
modify_hash = { modify_hash = {
lifetime: options.lifetime, :lifetime => options.lifetime,
disk: options.disk, :disk => options.disk,
tags: tags, :tags => tags,
reason: options.reason :reason => options.reason,
} }
modify_hash.delete_if { |_, value| value.nil? } modify_hash.delete_if { |_, value| value.nil? }
@ -171,11 +171,11 @@ class Vmfloaty
end end
if ok if ok
if modify_all if modify_all
puts "Successfully modified all VMs." puts 'Successfully modified all VMs.'
else else
puts "Successfully modified VM #{hostname}." puts "Successfully modified VM #{hostname}."
end end
puts "Use `floaty list --active` to see the results." puts 'Use `floaty list --active` to see the results.'
end end
end end
end end
@ -205,15 +205,13 @@ class Vmfloaty
if delete_all if delete_all
running_vms = service.list_active(verbose) running_vms = service.list_active(verbose)
if running_vms.empty? if running_vms.empty?
STDERR.puts "You have no running VMs." STDERR.puts 'You have no running VMs.'
else else
Utils.pretty_print_hosts(verbose, service, running_vms) Utils.pretty_print_hosts(verbose, service, running_vms)
# Confirm deletion # Confirm deletion
puts puts
confirmed = true confirmed = true
unless force confirmed = agree('Delete all these VMs? [y/N]') unless force
confirmed = agree('Delete all these VMs? [y/N]')
end
if confirmed if confirmed
response = service.delete(verbose, running_vms) response = service.delete(verbose, running_vms)
response.each do |hostname, result| response.each do |hostname, result|
@ -236,7 +234,7 @@ class Vmfloaty
end end
end end
else else
STDERR.puts "You did not provide any hosts to delete" STDERR.puts 'You did not provide any hosts to delete'
exit 1 exit 1
end end
@ -302,9 +300,7 @@ class Vmfloaty
hostname = args[0] hostname = args[0]
snapshot_sha = args[1] || options.snapshot snapshot_sha = args[1] || options.snapshot
if args[1] && options.snapshot STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}"
end
begin begin
revert_req = service.revert(verbose, hostname, snapshot_sha) revert_req = service.revert(verbose, hostname, snapshot_sha)
@ -380,9 +376,7 @@ class Vmfloaty
puts result puts result
when 'status' when 'status'
token_value = options.token token_value = options.token
if token_value.nil? token_value = args[1] if token_value.nil?
token_value = args[1]
end
status = service.token_status(verbose, token_value) status = service.token_status(verbose, token_value)
puts status puts status
when nil when nil
@ -417,15 +411,13 @@ class Vmfloaty
use_token = !options.notoken use_token = !options.notoken
if args.empty? if args.empty?
STDERR.puts "No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs." STDERR.puts 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
exit 1 exit 1
end end
host_os = args.first host_os = args.first
if args.length > 1 STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..."
end
service.ssh(verbose, host_os, use_token) service.ssh(verbose, host_os, use_token)
exit 0 exit 0
@ -435,13 +427,13 @@ class Vmfloaty
command :completion do |c| command :completion do |c|
c.syntax = 'floaty completion [options]' c.syntax = 'floaty completion [options]'
c.summary = 'Outputs path to completion script' c.summary = 'Outputs path to completion script'
c.description = Utils.strip_heredoc(<<-EOF) c.description = Utils.strip_heredoc(<<-DESCRIPTION)
Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile: Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile:
source $(floaty completion --shell bash) source $(floaty completion --shell bash)
This subcommand will exit non-zero with an error message if no completion script is available for the requested shell. This subcommand will exit non-zero with an error message if no completion script is available for the requested shell.
EOF DESCRIPTION
c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash' c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash'
c.option '--shell STRING', String, 'Shell to request completion script for' c.option '--shell STRING', String, 'Shell to request completion script for'
c.action do |_, options| c.action do |_, options|

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'faraday' require 'faraday'
require 'json' require 'json'
require 'vmfloaty/http' require 'vmfloaty/http'
@ -7,46 +9,36 @@ class Auth
def self.get_token(verbose, url, user, password) def self.get_token(verbose, url, user, password)
conn = Http.get_conn_with_auth(verbose, url, user, password) conn = Http.get_conn_with_auth(verbose, url, user, password)
resp = conn.post "token" resp = conn.post 'token'
res_body = JSON.parse(resp.body) res_body = JSON.parse(resp.body)
if res_body["ok"] return res_body['token'] if res_body['ok']
return res_body["token"]
else
raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}" raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}"
end end
end
def self.delete_token(verbose, url, user, password, token) def self.delete_token(verbose, url, user, password, token)
if token.nil? raise TokenError, 'You did not provide a token' if token.nil?
raise TokenError, 'You did not provide a token'
end
conn = Http.get_conn_with_auth(verbose, url, user, password) conn = Http.get_conn_with_auth(verbose, url, user, password)
response = conn.delete "token/#{token}" response = conn.delete "token/#{token}"
res_body = JSON.parse(response.body) res_body = JSON.parse(response.body)
if res_body["ok"] return res_body if res_body['ok']
return res_body
else
raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}" raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}"
end end
end
def self.token_status(verbose, url, token) def self.token_status(verbose, url, token)
if token.nil? raise TokenError, 'You did not provide a token' if token.nil?
raise TokenError, 'You did not provide a token'
end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
response = conn.get "token/#{token}" response = conn.get "token/#{token}"
res_body = JSON.parse(response.body) res_body = JSON.parse(response.body)
if res_body["ok"] return res_body if res_body['ok']
return res_body
else
raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}" raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}"
end end
end
end end

View file

@ -1,12 +1,13 @@
# frozen_string_literal: true
require 'yaml' require 'yaml'
class Conf class Conf
def self.read_config def self.read_config
conf = {} conf = {}
begin begin
conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml") conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml")
rescue rescue StandardError
STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml"
end end
conf conf

View file

@ -1,23 +1,25 @@
# frozen_string_literal: true
class AuthError < StandardError class AuthError < StandardError
def initialize(msg="Could not authenticate to pooler") def initialize(msg = 'Could not authenticate to pooler')
super super
end end
end end
class TokenError < StandardError class TokenError < StandardError
def initialize(msg="Could not do operation with token provided") def initialize(msg = 'Could not do operation with token provided')
super super
end end
end end
class MissingParamError < StandardError class MissingParamError < StandardError
def initialize(msg="Argument provided to function is missing") def initialize(msg = 'Argument provided to function is missing')
super super
end end
end end
class ModifyError < StandardError class ModifyError < StandardError
def initialize(msg="Could not modify VM") def initialize(msg = 'Could not modify VM')
super super
end end
end end

View file

@ -1,60 +1,49 @@
# frozen_string_literal: true
require 'faraday' require 'faraday'
require 'uri' require 'uri'
class Http class Http
def self.is_url(url) def self.url?(url)
# This method exists because it seems like Farady # This method exists because it seems like Farady
# has no handling around if a user gives us a URI # has no handling around if a user gives us a URI
# with no protocol on the beginning of the URL # with no protocol on the beginning of the URL
uri = URI.parse(url) uri = URI.parse(url)
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS) return true if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
return true
end
return false false
end end
def self.get_conn(verbose, url) def self.get_conn(verbose, url)
if url.nil? raise 'Did not provide a url to connect to' if url.nil?
raise "Did not provide a url to connect to"
end
unless is_url(url) url = "https://#{url}" unless url?(url)
url = "https://#{url}"
end
conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday| conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday|
faraday.request :url_encoded faraday.request :url_encoded
faraday.response :logger if verbose faraday.response :logger if verbose
faraday.adapter Faraday.default_adapter faraday.adapter Faraday.default_adapter
end end
return conn conn
end end
def self.get_conn_with_auth(verbose, url, user, password) def self.get_conn_with_auth(verbose, url, user, password)
if url.nil? raise 'Did not provide a url to connect to' if url.nil?
raise "Did not provide a url to connect to"
end
if user.nil? raise 'You did not provide a user to authenticate with' if user.nil?
raise "You did not provide a user to authenticate with"
end
unless is_url(url) url = "https://#{url}" unless url?(url)
url = "https://#{url}"
end
conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday| conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday|
faraday.request :url_encoded faraday.request :url_encoded
faraday.request :basic_auth, user, password faraday.request :basic_auth, user, password
faraday.response :logger if verbose faraday.response :logger if verbose
faraday.adapter Faraday.default_adapter faraday.adapter Faraday.default_adapter
end end
return conn conn
end end
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'vmfloaty/errors' require 'vmfloaty/errors'
require 'vmfloaty/http' require 'vmfloaty/http'
require 'faraday' require 'faraday'
@ -24,18 +26,8 @@ class NonstandardPooler
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token conn.headers['X-AUTH-TOKEN'] = token if token
os_string = '' os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
os_type.each do |os, num| raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
num.times do |_i|
os_string << os + '+'
end
end
os_string = os_string.chomp('+')
if os_string.empty?
raise MissingParamError, 'No operating systems provided to obtain.'
end
response = conn.post "host/#{os_string}" response = conn.post "host/#{os_string}"
@ -51,14 +43,10 @@ class NonstandardPooler
end end
def self.modify(verbose, url, hostname, token, modify_hash) def self.modify(verbose, url, hostname, token, modify_hash)
if token.nil? raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' if token.nil?
raise TokenError, 'Token provided was nil; Request cannot be made to modify VM'
end
modify_hash.each do |key, value| modify_hash.each do |key, _value|
unless [:reason, :reserved_for_reason].include? key raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason reserved_for_reason].include? key
raise ModifyError, "Configured service type does not support modification of #{key}"
end
end end
if modify_hash[:reason] if modify_hash[:reason]
@ -77,22 +65,20 @@ class NonstandardPooler
response.body.empty? ? {} : JSON.parse(response.body) response.body.empty? ? {} : JSON.parse(response.body)
end end
def self.disk(verbose, url, hostname, token, disk) def self.disk(_verbose, _url, _hostname, _token, _disk)
raise ModifyError, 'Configured service type does not support modification of disk space' raise ModifyError, 'Configured service type does not support modification of disk space'
end end
def self.snapshot(verbose, url, hostname, token) def self.snapshot(_verbose, _url, _hostname, _token)
raise ModifyError, 'Configured service type does not support snapshots' raise ModifyError, 'Configured service type does not support snapshots'
end end
def self.revert(verbose, url, hostname, token, snapshot_sha) def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha)
raise ModifyError, 'Configured service type does not support snapshots' raise ModifyError, 'Configured service type does not support snapshots'
end end
def self.delete(verbose, url, hosts, token) def self.delete(verbose, url, hosts, token)
if token.nil? raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil?
raise TokenError, 'Token provided was nil; Request cannot be made to delete VM'
end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
@ -100,9 +86,7 @@ class NonstandardPooler
response_body = {} response_body = {}
unless hosts.is_a? Array hosts = hosts.split(',') unless hosts.is_a? Array
hosts = hosts.split(',')
end
hosts.each do |host| hosts.each do |host|
response = conn.delete "host/#{host}" response = conn.delete "host/#{host}"
res_body = JSON.parse(response.body) res_body = JSON.parse(response.body)

View file

@ -1,19 +1,21 @@
# frozen_string_literal: true
require 'faraday' require 'faraday'
require 'vmfloaty/http' require 'vmfloaty/http'
require 'json' require 'json'
require 'vmfloaty/errors' require 'vmfloaty/errors'
class Pooler class Pooler
def self.list(verbose, url, os_filter=nil) def self.list(verbose, url, os_filter = nil)
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
response = conn.get 'vm' response = conn.get 'vm'
response_body = JSON.parse(response.body) response_body = JSON.parse(response.body)
if os_filter hosts = if os_filter
hosts = response_body.select { |i| i[/#{os_filter}/] } response_body.select { |i| i[/#{os_filter}/] }
else else
hosts = response_body response_body
end end
hosts hosts
@ -22,9 +24,7 @@ class Pooler
def self.list_active(verbose, url, token) def self.list_active(verbose, url, token)
status = Auth.token_status(verbose, url, token) status = Auth.token_status(verbose, url, token)
vms = [] vms = []
if status[token] && status[token]['vms'] vms = status[token]['vms']['running'] if status[token] && status[token]['vms']
vms = status[token]['vms']['running']
end
vms vms
end end
@ -33,28 +33,16 @@ class Pooler
# Developers can use `Utils.generate_os_hash` to # Developers can use `Utils.generate_os_hash` to
# generate the os_type param. # generate the os_type param.
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
if token conn.headers['X-AUTH-TOKEN'] = token if token
conn.headers['X-AUTH-TOKEN'] = token
end
os_string = "" os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
os_type.each do |os,num| raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
num.times do |i|
os_string << os+"+"
end
end
os_string = os_string.chomp("+")
if os_string.size == 0
raise MissingParamError, "No operating systems provided to obtain."
end
response = conn.post "vm/#{os_string}" response = conn.post "vm/#{os_string}"
res_body = JSON.parse(response.body) res_body = JSON.parse(response.body)
if res_body["ok"] if res_body['ok']
res_body res_body
elsif response.status == 401 elsif response.status == 401
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
@ -64,14 +52,10 @@ class Pooler
end end
def self.modify(verbose, url, hostname, token, modify_hash) def self.modify(verbose, url, hostname, token, modify_hash)
if token.nil? raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to modify vm"
end
modify_hash.keys.each do |key| modify_hash.keys.each do |key|
unless [:tags, :lifetime, :disk].include? key raise ModifyError, "Configured service type does not support modification of #{key}." unless %i[tags lifetime disk].include? key
raise ModifyError, "Configured service type does not support modification of #{key}."
end
end end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
@ -92,9 +76,7 @@ class Pooler
end end
def self.disk(verbose, url, hostname, token, disk) def self.disk(verbose, url, hostname, token, disk)
if token.nil? raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to modify vm"
end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token conn.headers['X-AUTH-TOKEN'] = token
@ -106,15 +88,11 @@ class Pooler
end end
def self.delete(verbose, url, hosts, token) def self.delete(verbose, url, hosts, token)
if token.nil? raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to delete vm"
end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
if token conn.headers['X-AUTH-TOKEN'] = token if token
conn.headers['X-AUTH-TOKEN'] = token
end
response_body = {} response_body = {}
@ -153,9 +131,7 @@ class Pooler
end end
def self.snapshot(verbose, url, hostname, token) def self.snapshot(verbose, url, hostname, token)
if token.nil? raise TokenError, 'Token provided was nil. Request cannot be made to snapshot vm' if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to snapshot vm"
end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token conn.headers['X-AUTH-TOKEN'] = token
@ -166,16 +142,12 @@ class Pooler
end end
def self.revert(verbose, url, hostname, token, snapshot_sha) def self.revert(verbose, url, hostname, token, snapshot_sha)
if token.nil? raise TokenError, 'Token provided was nil. Request cannot be made to revert vm' if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to revert vm"
end
conn = Http.get_conn(verbose, url) conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token conn.headers['X-AUTH-TOKEN'] = token
if snapshot_sha.nil? raise "Snapshot SHA provided was nil, could not revert #{hostname}" if snapshot_sha.nil?
raise "Snapshot SHA provided was nil, could not revert #{hostname}"
end
response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}" response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}"
res_body = JSON.parse(response.body) res_body = JSON.parse(response.body)

View file

@ -1,10 +1,11 @@
# frozen_string_literal: true
require 'commander/user_interaction' require 'commander/user_interaction'
require 'commander/command' require 'commander/command'
require 'vmfloaty/utils' require 'vmfloaty/utils'
require 'vmfloaty/ssh' require 'vmfloaty/ssh'
class Service class Service
attr_reader :config attr_reader :config
def initialize(options, config_hash = {}) def initialize(options, config_hash = {})
@ -13,14 +14,18 @@ class Service
@service_object = Utils.get_service_object @config['type'] @service_object = Utils.get_service_object @config['type']
end end
def method_missing(m, *args, &block) def method_missing(method_name, *args, &block)
if @service_object.respond_to? m if @service_object.respond_to?(method_name)
@service_object.send(m, *args, &block) @service_object.send(method_name, *args, &block)
else else
super super
end end
end end
def respond_to_missing?(method_name, *)
@service_object.respond_to?(method_name) || super
end
def url def url
@config['url'] @config['url']
end end
@ -31,7 +36,7 @@ class Service
def user def user
unless @config['user'] unless @config['user']
puts "Enter your pooler service username:" puts 'Enter your pooler service username:'
@config['user'] = STDIN.gets.chomp @config['user'] = STDIN.gets.chomp
end end
@config['user'] @config['user']
@ -39,7 +44,7 @@ class Service
def token def token
unless @config['token'] unless @config['token']
puts "No token found. Retrieving a token..." puts 'No token found. Retrieving a token...'
@config['token'] = get_new_token(nil) @config['token'] = get_new_token(nil)
end end
@config['token'] @config['token']
@ -47,13 +52,13 @@ class Service
def get_new_token(verbose) def get_new_token(verbose)
username = user username = user
pass = Commander::UI::password "Enter your pooler service password:", '*' pass = Commander::UI.password 'Enter your pooler service password:', '*'
Auth.get_token(verbose, url, username, pass) Auth.get_token(verbose, url, username, pass)
end end
def delete_token(verbose, token_value = @config['token']) def delete_token(verbose, token_value = @config['token'])
username = user username = user
pass = Commander::UI::password "Enter your pooler service password:", '*' pass = Commander::UI.password 'Enter your pooler service password:', '*'
Auth.delete_token(verbose, url, username, pass, token_value) Auth.delete_token(verbose, url, username, pass, token_value)
end end
@ -91,9 +96,9 @@ class Service
def pretty_print_running(verbose, hostnames = []) def pretty_print_running(verbose, hostnames = [])
if hostnames.empty? if hostnames.empty?
puts "You have no running VMs." puts 'You have no running VMs.'
else else
puts "Running VMs:" puts 'Running VMs:'
@service_object.pretty_print_hosts(verbose, hostnames, url) @service_object.pretty_print_hosts(verbose, hostnames, url)
end end
end end
@ -129,5 +134,4 @@ class Service
def disk(verbose, hostname, disk) def disk(verbose, hostname, disk)
@service_object.disk(verbose, url, hostname, token, disk) @service_object.disk(verbose, url, hostname, token, disk)
end end
end end

View file

@ -1,43 +1,37 @@
class Ssh # frozen_string_literal: true
class Ssh
def self.which(cmd) def self.which(cmd)
# Gets path of executable for given command # Gets path of executable for given command
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each { |ext| exts.each do |ext|
exe = File.join(path, "#{cmd}#{ext}") exe = File.join(path, "#{cmd}#{ext}")
return exe if File.executable?(exe) && !File.directory?(exe) return exe if File.executable?(exe) && !File.directory?(exe)
}
end end
return nil end
nil
end end
def self.ssh(verbose, host_os, token, url) def self.ssh(verbose, host_os, token, url)
ssh_path = which("ssh") ssh_path = which('ssh')
if !ssh_path raise 'Could not determine path to ssh' unless ssh_path
raise "Could not determine path to ssh"
end
os_types = {} os_types = {}
os_types[host_os] = 1 os_types[host_os] = 1
response = Pooler.retrieve(verbose, os_types, token, url) response = Pooler.retrieve(verbose, os_types, token, url)
if response["ok"] == true raise "Could not get vm from vmpooler:\n #{response}" unless response['ok']
if host_os =~ /win/
user = "Administrator"
else
user = "root"
end
hostname = "#{response[host_os]["hostname"]}.#{response["domain"]}" user = /win/.match?(host_os) ? 'Administrator' : 'root'
hostname = "#{response[host_os]['hostname']}.#{response['domain']}"
cmd = "#{ssh_path} #{user}@#{hostname}" cmd = "#{ssh_path} #{user}@#{hostname}"
# TODO: Should this respect more ssh settings? Can it be configured # TODO: Should this respect more ssh settings? Can it be configured
# by users ssh config and does this respect those settings? # by users ssh config and does this respect those settings?
Kernel.exec(cmd) Kernel.exec(cmd)
else nil
raise "Could not get vm from vmpooler:\n #{response}"
end
return
end end
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'vmfloaty/pooler' require 'vmfloaty/pooler'
require 'vmfloaty/nonstandard_pooler' require 'vmfloaty/nonstandard_pooler'
@ -28,9 +30,7 @@ class Utils
# } # }
# } # }
unless response_body.delete('ok') raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok')
raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}"
end
# vmpooler reports the domain separately from the hostname # vmpooler reports the domain separately from the hostname
domain = response_body.delete('domain') domain = response_body.delete('domain')
@ -39,9 +39,7 @@ class Utils
response_body.each do |os, value| response_body.each do |os, value|
hostnames = Array(value['hostname']) hostnames = Array(value['hostname'])
if domain hostnames.map! { |host| "#{host}.#{domain}" } if domain
hostnames.map! {|host| "#{host}.#{domain}"}
end
result[os] = hostnames result[os] = hostnames
end end
@ -65,13 +63,8 @@ class Utils
# ...] # ...]
os_types = {} os_types = {}
os_args.each do |arg| os_args.each do |arg|
os_arr = arg.split("=") os_arr = arg.split('=')
if os_arr.size == 1 os_types[os_arr[0]] = os_arr.size == 1 ? 1 : os_arr[1].to_i
# assume they didn't specify an = sign if split returns 1 size
os_types[os_arr[0]] = 1
else
os_types[os_arr[0]] = os_arr[1].to_i
end
end end
os_types os_types
end end
@ -86,24 +79,20 @@ class Utils
case service.type case service.type
when 'Pooler' when 'Pooler'
tag_pairs = [] tag_pairs = []
unless host_data['tags'].nil? tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil?
tag_pairs = host_data['tags'].map {|key, value| "#{key}: #{value}"}
end
duration = "#{host_data['running']}/#{host_data['lifetime']} hours" duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
metadata = [host_data['template'], duration, *tag_pairs] metadata = [host_data['template'], duration, *tag_pairs]
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(", ")})" puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})"
when 'NonstandardPooler' when 'NonstandardPooler'
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
line += ", #{host_data['hours_left_on_reservation']}h remaining" line += ", #{host_data['hours_left_on_reservation']}h remaining"
unless host_data['reserved_for_reason'].empty? line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty?
line += ", reason: #{host_data['reserved_for_reason']}"
end
line += ')' line += ')'
puts line puts line
else else
raise "Invalid service type #{service.type}" raise "Invalid service type #{service.type}"
end end
rescue => e rescue StandardError => e
STDERR.puts("Something went wrong while trying to gather information on #{hostname}:") STDERR.puts("Something went wrong while trying to gather information on #{hostname}:")
STDERR.puts(e) STDERR.puts(e)
end end
@ -117,7 +106,7 @@ class Utils
when 'Pooler' when 'Pooler'
message = status_response['status']['message'] message = status_response['status']['message']
pools = status_response['pools'] pools = status_response['pools']
pools.select! {|_, pool| pool['ready'] < pool['max']} unless verbose pools.select! { |_, pool| pool['ready'] < pool['max'] } unless verbose
width = pools.keys.map(&:length).max width = pools.keys.map(&:length).max
pools.each do |name, pool| pools.each do |name, pool|
@ -127,8 +116,8 @@ class Utils
pending = pool['pending'] pending = pool['pending']
missing = max - ready - pending missing = max - ready - pending
char = 'o' char = 'o'
puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}" puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
rescue => e rescue StandardError => e
puts "#{name.ljust(width)} #{e.red}" puts "#{name.ljust(width)} #{e.red}"
end end
end end
@ -136,7 +125,7 @@ class Utils
when 'NonstandardPooler' when 'NonstandardPooler'
pools = status_response pools = status_response
pools.delete 'ok' pools.delete 'ok'
pools.select! {|_, pool| pool['available_hosts'] < pool['total_hosts']} unless verbose pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose
width = pools.keys.map(&:length).max width = pools.keys.map(&:length).max
pools.each do |name, pool| pools.each do |name, pool|
@ -146,8 +135,8 @@ class Utils
pending = pool['pending'] || 0 # not available for nspooler pending = pool['pending'] || 0 # not available for nspooler
missing = max - ready - pending missing = max - ready - pending
char = 'o' char = 'o'
puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}" puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
rescue => e rescue StandardError => e
puts "#{name.ljust(width)} #{e.red}" puts "#{name.ljust(width)} #{e.red}"
end end
end end
@ -165,7 +154,7 @@ class Utils
end end
def self.get_service_object(type = '') def self.get_service_object(type = '')
nspooler_strings = ['ns', 'nspooler', 'nonstandard', 'nonstandard_pooler'] nspooler_strings = %w[ns nspooler nonstandard nonstandard_pooler]
if nspooler_strings.include? type.downcase if nspooler_strings.include? type.downcase
NonstandardPooler NonstandardPooler
else else
@ -179,7 +168,7 @@ class Utils
'url' => config['url'], 'url' => config['url'],
'user' => config['user'], 'user' => config['user'],
'token' => config['token'], 'token' => config['token'],
'type' => config['type'] || 'vmpooler' 'type' => config['type'] || 'vmpooler',
} }
if config['services'] if config['services']
@ -190,12 +179,10 @@ class Utils
service_config.merge! values service_config.merge! values
else else
# If the user provided a service name at the command line, use that service if posible, or fail # If the user provided a service name at the command line, use that service if posible, or fail
if config['services'][options.service] raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" unless config['services'][options.service]
# If the service is configured but some values are missing, use the top-level defaults to fill them in # If the service is configured but some values are missing, use the top-level defaults to fill them in
service_config.merge! config['services'][options.service] service_config.merge! config['services'][options.service]
else
raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml"
end
end end
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Vmfloaty class Vmfloaty
VERSION = '0.8.2'.freeze VERSION = '0.8.2'
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'vmfloaty' require 'vmfloaty'
require 'webmock/rspec' require 'webmock/rspec'

View file

@ -1,86 +1,88 @@
# frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
require_relative '../../lib/vmfloaty/auth' require_relative '../../lib/vmfloaty/auth'
describe Pooler do describe Pooler do
before :each do before :each do
@vmpooler_url = "https://vmpooler.example.com" @vmpooler_url = 'https://vmpooler.example.com'
end end
describe "#get_token" do describe '#get_token' do
before :each do before :each do
@get_token_response = "{\"ok\": true,\"token\":\"utpg2i2xswor6h8ttjhu3d47z53yy47y\"}" @get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}'
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y" @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end end
it "returns a token from vmpooler" do it 'returns a token from vmpooler' do
stub_request(:post, "https://first.last:password@vmpooler.example.com/token"). stub_request(:post, 'https://first.last:password@vmpooler.example.com/token')
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 200, :body => @get_token_response, :headers => {}) .to_return(:status => 200, :body => @get_token_response, :headers => {})
token = Auth.get_token(false, @vmpooler_url, "first.last", "password") token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password')
expect(token).to eq @token expect(token).to eq @token
end end
it "raises a token error if something goes wrong" do it 'raises a token error if something goes wrong' do
stub_request(:post, "https://first.last:password@vmpooler.example.com/token"). stub_request(:post, 'https://first.last:password@vmpooler.example.com/token')
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {}) .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
expect{ Auth.get_token(false, @vmpooler_url, "first.last", "password") }.to raise_error(TokenError) expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError)
end end
end end
describe "#delete_token" do describe '#delete_token' do
before :each do before :each do
@delete_token_response = "{\"ok\":true}" @delete_token_response = '{"ok":true}'
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y" @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end end
it "deletes the specified token" do it 'deletes the specified token' do
stub_request(:delete, "https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 200, :body => @delete_token_response, :headers => {}) .to_return(:status => 200, :body => @delete_token_response, :headers => {})
expect(Auth.delete_token(false, @vmpooler_url, "first.last", "password", @token)).to eq JSON.parse(@delete_token_response) expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response)
end end
it "raises a token error if something goes wrong" do it 'raises a token error if something goes wrong' do
stub_request(:delete, "https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {}) .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
expect{ Auth.delete_token(false, @vmpooler_url, "first.last", "password", @token) }.to raise_error(TokenError) expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
end end
it "raises a token error if no token provided" do it 'raises a token error if no token provided' do
expect{ Auth.delete_token(false, @vmpooler_url, "first.last", "password", nil) }.to raise_error(TokenError) expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', nil) }.to raise_error(TokenError)
end end
end end
describe "#token_status" do describe '#token_status' do
before :each do before :each do
@token_status_response = "{\"ok\":true,\"utpg2i2xswor6h8ttjhu3d47z53yy47y\":{\"created\":\"2015-04-28 19:17:47 -0700\"}}" @token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}'
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y" @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end end
it "checks the status of a token" do it 'checks the status of a token' do
stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 200, :body => @token_status_response, :headers => {}) .to_return(:status => 200, :body => @token_status_response, :headers => {})
expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response) expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response)
end end
it "raises a token error if something goes wrong" do it 'raises a token error if something goes wrong' do
stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {}) .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
expect{ Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError)
end end
it "raises a token error if no token provided" do it 'raises a token error if no token provided' do
expect{ Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError) expect { Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError)
end end
end end
end end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
require 'vmfloaty/utils' require 'vmfloaty/utils'
require 'vmfloaty/errors' require 'vmfloaty/errors'
@ -10,24 +12,23 @@ describe NonstandardPooler do
'Accept' => '*/*', 'Accept' => '*/*',
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'User-Agent' => 'Faraday v0.9.2', 'User-Agent' => 'Faraday v0.9.2',
'X-Auth-Token' => 'token-value' 'X-Auth-Token' => 'token-value',
} }
@get_request_headers = { @get_request_headers = {
'Accept' => '*/*', 'Accept' => '*/*',
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'User-Agent' => 'Faraday v0.9.2', 'User-Agent' => 'Faraday v0.9.2',
'X-Auth-Token' => 'token-value' 'X-Auth-Token' => 'token-value',
} }
@get_request_headers_notoken = @get_request_headers.tap do |headers| @get_request_headers_notoken = @get_request_headers.tap do |headers|
headers.delete('X-Auth-Token') headers.delete('X-Auth-Token')
end end
end end
describe '#list' do describe '#list' do
before :each do before :each do
@status_response_body = <<-BODY @status_response_body = <<~BODY
{ {
"ok": true, "ok": true,
"solaris-10-sparc": { "solaris-10-sparc": {
"total_hosts": 11, "total_hosts": 11,
@ -41,13 +42,13 @@ describe NonstandardPooler do
"total_hosts": 5, "total_hosts": 5,
"available_hosts": 4 "available_hosts": 4
} }
} }
BODY BODY
end end
it 'returns an array with operating systems from the pooler' do it 'returns an array with operating systems from the pooler' do
stub_request(:get, "#{@nspooler_url}/status") stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 200, body: @status_response_body, headers: {}) .to_return(:status => 200, :body => @status_response_body, :headers => {})
list = NonstandardPooler.list(false, @nspooler_url, nil) list = NonstandardPooler.list(false, @nspooler_url, nil)
expect(list).to be_an_instance_of Array expect(list).to be_an_instance_of Array
@ -55,7 +56,7 @@ describe NonstandardPooler do
it 'filters operating systems based on the filter param' do it 'filters operating systems based on the filter param' do
stub_request(:get, "#{@nspooler_url}/status") stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 200, body: @status_response_body, headers: {}) .to_return(:status => 200, :body => @status_response_body, :headers => {})
list = NonstandardPooler.list(false, @nspooler_url, 'aix') list = NonstandardPooler.list(false, @nspooler_url, 'aix')
expect(list).to be_an_instance_of Array expect(list).to be_an_instance_of Array
@ -64,7 +65,7 @@ describe NonstandardPooler do
it 'returns nothing if the filter does not match' do it 'returns nothing if the filter does not match' do
stub_request(:get, "#{@nspooler_url}/status") stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 199, body: @status_response_body, headers: {}) .to_return(:status => 199, :body => @status_response_body, :headers => {})
list = NonstandardPooler.list(false, @nspooler_url, 'windows') list = NonstandardPooler.list(false, @nspooler_url, 'windows')
expect(list).to be_an_instance_of Array expect(list).to be_an_instance_of Array
@ -74,24 +75,24 @@ describe NonstandardPooler do
describe '#list_active' do describe '#list_active' do
before :each do before :each do
@token_status_body_active = <<-BODY @token_status_body_active = <<~BODY
{ {
"ok": true, "ok": true,
"user": "first.last", "user": "first.last",
"created": "2017-09-18 01:25:41 +0000", "created": "2017-09-18 01:25:41 +0000",
"last_accessed": "2017-09-21 19:46:25 +0000", "last_accessed": "2017-09-21 19:46:25 +0000",
"reserved_hosts": ["sol10-9", "sol10-11"] "reserved_hosts": ["sol10-9", "sol10-11"]
} }
BODY BODY
@token_status_body_empty = <<-BODY @token_status_body_empty = <<~BODY
{ {
"ok": true, "ok": true,
"user": "first.last", "user": "first.last",
"created": "2017-09-18 01:25:41 +0000", "created": "2017-09-18 01:25:41 +0000",
"last_accessed": "2017-09-21 19:46:25 +0000", "last_accessed": "2017-09-21 19:46:25 +0000",
"reserved_hosts": [] "reserved_hosts": []
} }
BODY BODY
end end
it 'prints an output of fqdn, template, and duration' do it 'prints an output of fqdn, template, and duration' do
@ -106,16 +107,16 @@ BODY
describe '#retrieve' do describe '#retrieve' do
before :each do before :each do
@retrieve_response_body_single = <<-BODY @retrieve_response_body_single = <<~BODY
{ {
"ok": true, "ok": true,
"solaris-11-sparc": { "solaris-11-sparc": {
"hostname": "sol11-4.delivery.puppetlabs.net" "hostname": "sol11-4.delivery.puppetlabs.net"
} }
} }
BODY BODY
@retrieve_response_body_many = <<-BODY @retrieve_response_body_many = <<~BODY
{ {
"ok": true, "ok": true,
"solaris-10-sparc": { "solaris-10-sparc": {
"hostname": [ "hostname": [
@ -126,14 +127,14 @@ BODY
"aix-7.1-power": { "aix-7.1-power": {
"hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net" "hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net"
} }
} }
BODY BODY
end end
it 'raises an AuthError if the token is invalid' do it 'raises an AuthError if the token is invalid' do
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
.with(headers: @post_request_headers) .with(:headers => @post_request_headers)
.to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {}) .to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {})
vm_hash = { 'solaris-11-sparc' => 1 } vm_hash = { 'solaris-11-sparc' => 1 }
expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.to raise_error(AuthError) expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.to raise_error(AuthError)
@ -141,8 +142,8 @@ BODY
it 'retrieves a single vm with a token' do it 'retrieves a single vm with a token' do
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
.with(headers: @post_request_headers) .with(:headers => @post_request_headers)
.to_return(status: 200, body: @retrieve_response_body_single, headers: {}) .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
vm_hash = { 'solaris-11-sparc' => 1 } vm_hash = { 'solaris-11-sparc' => 1 }
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
@ -152,9 +153,9 @@ BODY
end end
it 'retrieves a multiple vms with a token' do it 'retrieves a multiple vms with a token' do
stub_request(:post,"#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc") stub_request(:post, "#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc")
.with(headers: @post_request_headers) .with(:headers => @post_request_headers)
.to_return(status: 200, body: @retrieve_response_body_many, headers: {}) .to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {})
vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 } vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 }
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
@ -172,11 +173,11 @@ BODY
end end
it 'raises an error if the user tries to modify an unsupported attribute' do it 'raises an error if the user tries to modify an unsupported attribute' do
stub_request(:put, "https://nspooler.example.com/host/myfakehost"). stub_request(:put, 'https://nspooler.example.com/host/myfakehost')
with(body: {"{}"=>true}, .with(:body => { '{}' => true },
headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'token-value'}). :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' })
to_return(status: 200, body: "", headers: {}) .to_return(:status => 200, :body => '', :headers => {})
details = { lifetime: 12 } details = { :lifetime => 12 }
expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) }
.to raise_error(ModifyError) .to raise_error(ModifyError)
end end
@ -184,11 +185,11 @@ BODY
it 'modifies the reason of a vm' do it 'modifies the reason of a vm' do
modify_request_body = { '{"reserved_for_reason":"testing"}' => true } modify_request_body = { '{"reserved_for_reason":"testing"}' => true }
stub_request(:put, "#{@nspooler_url}/host/myfakehost") stub_request(:put, "#{@nspooler_url}/host/myfakehost")
.with(body: modify_request_body, .with(:body => modify_request_body,
headers: @post_request_headers) :headers => @post_request_headers)
.to_return(status: 200, body: '{"ok": true}', headers: {}) .to_return(:status => 200, :body => '{"ok": true}', :headers => {})
modify_hash = { reason: "testing" } modify_hash = { :reason => 'testing' }
modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash) modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash)
expect(modify_req['ok']).to be true expect(modify_req['ok']).to be true
end end
@ -198,8 +199,8 @@ BODY
before :each do before :each do
@status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}' @status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}'
# TODO: make this report stuff like 'broken' # TODO: make this report stuff like 'broken'
@status_response_body = <<-BODY @status_response_body = <<~BODY
{ {
"ok": true, "ok": true,
"solaris-10-sparc": { "solaris-10-sparc": {
"total_hosts": 11, "total_hosts": 11,
@ -213,14 +214,14 @@ BODY
"total_hosts": 5, "total_hosts": 5,
"available_hosts": 4 "available_hosts": 4
} }
} }
BODY BODY
end end
it 'prints the status' do it 'prints the status' do
stub_request(:get, "#{@nspooler_url}/status") stub_request(:get, "#{@nspooler_url}/status")
.with(headers: @get_request_headers) .with(:headers => @get_request_headers)
.to_return(status: 200, body: @status_response_body, headers: {}) .to_return(:status => 200, :body => @status_response_body, :headers => {})
status = NonstandardPooler.status(false, @nspooler_url) status = NonstandardPooler.status(false, @nspooler_url)
expect(status).to be_an_instance_of Hash expect(status).to be_an_instance_of Hash
@ -229,22 +230,22 @@ BODY
describe '#summary' do describe '#summary' do
before :each do before :each do
@status_response_body = <<-BODY @status_response_body = <<~BODY
{ {
"ok": true, "ok": true,
"total": 57, "total": 57,
"available": 39, "available": 39,
"in_use": 16, "in_use": 16,
"resetting": 2, "resetting": 2,
"broken": 0 "broken": 0
} }
BODY BODY
end end
it 'prints the summary' do it 'prints the summary' do
stub_request(:get, "#{@nspooler_url}/summary") stub_request(:get, "#{@nspooler_url}/summary")
.with(headers: @get_request_headers) .with(:headers => @get_request_headers)
.to_return(status: 200, body: @status_response_body, headers: {}) .to_return(:status => 200, :body => @status_response_body, :headers => {})
summary = NonstandardPooler.summary(false, @nspooler_url) summary = NonstandardPooler.summary(false, @nspooler_url)
expect(summary).to be_an_instance_of Hash expect(summary).to be_an_instance_of Hash
@ -253,8 +254,8 @@ BODY
describe '#query' do describe '#query' do
before :each do before :each do
@query_response_body = <<-BODY @query_response_body = <<~BODY
{ {
"ok": true, "ok": true,
"sol10-11": { "sol10-11": {
"fqdn": "sol10-11.delivery.puppetlabs.net", "fqdn": "sol10-11.delivery.puppetlabs.net",
@ -263,14 +264,14 @@ BODY
"reserved_for_reason": "testing", "reserved_for_reason": "testing",
"hours_left_on_reservation": 29.12 "hours_left_on_reservation": 29.12
} }
} }
BODY BODY
end end
it 'makes a query about a vm' do it 'makes a query about a vm' do
stub_request(:get, "#{@nspooler_url}/host/sol10-11") stub_request(:get, "#{@nspooler_url}/host/sol10-11")
.with(headers: @get_request_headers_notoken) .with(:headers => @get_request_headers_notoken)
.to_return(status: 200, body: @query_response_body, headers: {}) .to_return(:status => 200, :body => @query_response_body, :headers => {})
query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11') query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11')
expect(query_req).to be_an_instance_of Hash expect(query_req).to be_an_instance_of Hash
@ -285,8 +286,8 @@ BODY
it 'deletes a single existing vm' do it 'deletes a single existing vm' do
stub_request(:delete, "#{@nspooler_url}/host/sol11-7") stub_request(:delete, "#{@nspooler_url}/host/sol11-7")
.with(headers: @post_request_headers) .with(:headers => @post_request_headers)
.to_return(status: 200, body: @delete_response_success, headers: {}) .to_return(:status => 200, :body => @delete_response_success, :headers => {})
request = NonstandardPooler.delete(false, @nspooler_url, 'sol11-7', 'token-value') request = NonstandardPooler.delete(false, @nspooler_url, 'sol11-7', 'token-value')
expect(request['sol11-7']['ok']).to be true expect(request['sol11-7']['ok']).to be true
@ -294,8 +295,8 @@ BODY
it 'does not delete a nonexistant vm' do it 'does not delete a nonexistant vm' do
stub_request(:delete, "#{@nspooler_url}/host/fakehost") stub_request(:delete, "#{@nspooler_url}/host/fakehost")
.with(headers: @post_request_headers) .with(:headers => @post_request_headers)
.to_return(status: 401, body: @delete_response_failure, headers: {}) .to_return(:status => 401, :body => @delete_response_failure, :headers => {})
request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value') request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value')
expect(request['fakehost']['ok']).to be false expect(request['fakehost']['ok']).to be false

View file

@ -1,224 +1,226 @@
# frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
require_relative '../../lib/vmfloaty/pooler' require_relative '../../lib/vmfloaty/pooler'
describe Pooler do describe Pooler do
before :each do before :each do
@vmpooler_url = "https://vmpooler.example.com" @vmpooler_url = 'https://vmpooler.example.com'
end end
describe "#list" do describe '#list' do
before :each do before :each do
@list_response_body = "[\"debian-7-i386\",\"debian-7-x86_64\",\"centos-7-x86_64\"]" @list_response_body = '["debian-7-i386","debian-7-x86_64","centos-7-x86_64"]'
end end
it "returns a hash with operating systems from the pooler" do it 'returns a hash with operating systems from the pooler' do
stub_request(:get, "#{@vmpooler_url}/vm"). stub_request(:get, "#{@vmpooler_url}/vm")
to_return(:status => 200, :body => @list_response_body, :headers => {}) .to_return(:status => 200, :body => @list_response_body, :headers => {})
list = Pooler.list(false, @vmpooler_url, nil) list = Pooler.list(false, @vmpooler_url, nil)
expect(list).to be_an_instance_of Array expect(list).to be_an_instance_of Array
end end
it "filters operating systems based on the filter param" do it 'filters operating systems based on the filter param' do
stub_request(:get, "#{@vmpooler_url}/vm"). stub_request(:get, "#{@vmpooler_url}/vm")
to_return(:status => 200, :body => @list_response_body, :headers => {}) .to_return(:status => 200, :body => @list_response_body, :headers => {})
list = Pooler.list(false, @vmpooler_url, "deb") list = Pooler.list(false, @vmpooler_url, 'deb')
expect(list).to be_an_instance_of Array expect(list).to be_an_instance_of Array
expect(list.size).to equal 2 expect(list.size).to equal 2
end end
it "returns nothing if the filter does not match" do it 'returns nothing if the filter does not match' do
stub_request(:get, "#{@vmpooler_url}/vm"). stub_request(:get, "#{@vmpooler_url}/vm")
to_return(:status => 200, :body => @list_response_body, :headers => {}) .to_return(:status => 200, :body => @list_response_body, :headers => {})
list = Pooler.list(false, @vmpooler_url, "windows") list = Pooler.list(false, @vmpooler_url, 'windows')
expect(list).to be_an_instance_of Array expect(list).to be_an_instance_of Array
expect(list.size).to equal 0 expect(list.size).to equal 0
end end
end end
describe "#retrieve" do describe '#retrieve' do
before :each do before :each do
@retrieve_response_body_single = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":\"fq6qlpjlsskycq6\"}}" @retrieve_response_body_single = '{"ok":true,"debian-7-i386":{"hostname":"fq6qlpjlsskycq6"}}'
@retrieve_response_body_double = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":[\"sc0o4xqtodlul5w\",\"4m4dkhqiufnjmxy\"]},\"centos-7-x86_64\":{\"hostname\":\"zb91y9qbrbf6d3q\"}}" @retrieve_response_body_double = '{"ok":true,"debian-7-i386":{"hostname":["sc0o4xqtodlul5w","4m4dkhqiufnjmxy"]},"centos-7-x86_64":{"hostname":"zb91y9qbrbf6d3q"}}'
end end
it "raises an AuthError if the token is invalid" do it 'raises an AuthError if the token is invalid' do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 401, :body => "{\"ok\":false}", :headers => {}) .to_return(:status => 401, :body => '{"ok":false}', :headers => {})
vm_hash = {} vm_hash = {}
vm_hash['debian-7-i386'] = 1 vm_hash['debian-7-i386'] = 1
expect{ Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError) expect { Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError)
end end
it "retrieves a single vm with a token" do it 'retrieves a single vm with a token' do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
vm_hash = {} vm_hash = {}
vm_hash['debian-7-i386'] = 1 vm_hash['debian-7-i386'] = 1
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url)
expect(vm_req).to be_an_instance_of Hash expect(vm_req).to be_an_instance_of Hash
expect(vm_req["ok"]).to equal true expect(vm_req['ok']).to equal true
expect(vm_req["debian-7-i386"]["hostname"]).to eq "fq6qlpjlsskycq6" expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6'
end end
it "retrieves a multiple vms with a token" do it 'retrieves a multiple vms with a token' do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64"). stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {}) .to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {})
vm_hash = {} vm_hash = {}
vm_hash['debian-7-i386'] = 2 vm_hash['debian-7-i386'] = 2
vm_hash['centos-7-x86_64'] = 1 vm_hash['centos-7-x86_64'] = 1
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url)
expect(vm_req).to be_an_instance_of Hash expect(vm_req).to be_an_instance_of Hash
expect(vm_req["ok"]).to equal true expect(vm_req['ok']).to equal true
expect(vm_req["debian-7-i386"]["hostname"]).to be_an_instance_of Array expect(vm_req['debian-7-i386']['hostname']).to be_an_instance_of Array
expect(vm_req["debian-7-i386"]["hostname"]).to eq ["sc0o4xqtodlul5w", "4m4dkhqiufnjmxy"] expect(vm_req['debian-7-i386']['hostname']).to eq %w[sc0o4xqtodlul5w 4m4dkhqiufnjmxy]
expect(vm_req["centos-7-x86_64"]["hostname"]).to eq "zb91y9qbrbf6d3q" expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q'
end end
end end
describe "#modify" do describe '#modify' do
before :each do before :each do
@modify_response_body_success = "{\"ok\":true}" @modify_response_body_success = '{"ok":true}'
@modify_response_body_fail = "{\"ok\":false}" @modify_response_body_fail = '{"ok":false}'
end end
it "raises a TokenError if token provided is nil" do it 'raises a TokenError if token provided is nil' do
expect{ Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError) expect { Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError)
end end
it "modifies the TTL of a vm" do it 'modifies the TTL of a vm' do
modify_hash = { :lifetime => 12 } modify_hash = { :lifetime => 12 }
stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6")
with(:body => {'{"lifetime":12}'=>true}, .with(:body => { '{"lifetime":12}' => true },
:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) .to_return(:status => 200, :body => @modify_response_body_success, :headers => {})
modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash)
expect(modify_req["ok"]).to be true expect(modify_req['ok']).to be true
end end
end end
describe "#delete" do describe '#delete' do
before :each do before :each do
@delete_response_body_success = "{\"ok\":true}" @delete_response_body_success = '{"ok":true}'
@delete_response = {"fq6qlpjlsskycq6"=>{"ok"=>true}} @delete_response = { 'fq6qlpjlsskycq6' => { 'ok' => true } }
end end
it "deletes a specified vm" do it 'deletes a specified vm' do
stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) .to_return(:status => 200, :body => @delete_response_body_success, :headers => {})
expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response
end end
it "raises a token error if no token provided" do it 'raises a token error if no token provided' do
expect{ Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil) }.to raise_error(TokenError) expect { Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil) }.to raise_error(TokenError)
end end
end end
describe "#status" do describe '#status' do
before :each do before :each do
#smaller version # smaller version
@status_response_body = "{\"capacity\":{\"current\":716,\"total\":717,\"percent\": 99.9},\"status\":{\"ok\":true,\"message\":\"Battle station fully armed and operational.\"}}" @status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}'
end end
it "prints the status" do it 'prints the status' do
stub_request(:get, "#{@vmpooler_url}/status"). stub_request(:get, "#{@vmpooler_url}/status")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 200, :body => @status_response_body, :headers => {}) .to_return(:status => 200, :body => @status_response_body, :headers => {})
status = Pooler.status(false, @vmpooler_url) status = Pooler.status(false, @vmpooler_url)
expect(status).to be_an_instance_of Hash expect(status).to be_an_instance_of Hash
end end
end end
describe "#summary" do describe '#summary' do
before :each do before :each do
@status_response_body = "" @status_response_body = ''
it "prints the summary" do it 'prints the summary' do
end end
end end
end end
describe "#query" do describe '#query' do
before :each do before :each do
@query_response_body = "{\"ok\": true,\"fq6qlpjlsskycq6\":{\"template\":\"debian-7-x86_64\",\"lifetime\": 2,\"running\": 0.08,\"state\":\"running\",\"snapshots\":[\"n4eb4kdtp7rwv4x158366vd9jhac8btq\" ],\"domain\": \"delivery.puppetlabs.net\"}}" @query_response_body = '{"ok": true,"fq6qlpjlsskycq6":{"template":"debian-7-x86_64","lifetime": 2,"running": 0.08,"state":"running","snapshots":["n4eb4kdtp7rwv4x158366vd9jhac8btq" ],"domain": "delivery.puppetlabs.net"}}'
end end
it "makes a query about a vm" do it 'makes a query about a vm' do
stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
to_return(:status => 200, :body => @query_response_body, :headers => {}) .to_return(:status => 200, :body => @query_response_body, :headers => {})
query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6') query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6')
expect(query_req).to be_an_instance_of Hash expect(query_req).to be_an_instance_of Hash
end end
end end
describe "#snapshot" do describe '#snapshot' do
before :each do before :each do
@snapshot_response_body = "{\"ok\":true}" @snapshot_response_body = '{"ok":true}'
end end
it "makes a snapshot for a single vm" do it 'makes a snapshot for a single vm' do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot"). stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) .to_return(:status => 200, :body => @snapshot_response_body, :headers => {})
snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile')
expect(snapshot_req["ok"]).to be true expect(snapshot_req['ok']).to be true
end end
end end
describe "#revert" do describe '#revert' do
before :each do before :each do
@revert_response_body = "{\"ok\":true}" @revert_response_body = '{"ok":true}'
end end
it "makes a request to revert a vm from a snapshot" do it 'makes a request to revert a vm from a snapshot' do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve"). stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' })
to_return(:status => 200, :body => @revert_response_body, :headers => {}) .to_return(:status => 200, :body => @revert_response_body, :headers => {})
revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve')
expect(revert_req["ok"]).to be true expect(revert_req['ok']).to be true
end end
it "doesn't make a request to revert a vm if snapshot is not provided" do it "doesn't make a request to revert a vm if snapshot is not provided" do
expect{ Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, "Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6") expect { Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6')
end end
it "raises a TokenError if no token was provided" do it 'raises a TokenError if no token was provided' do
expect{ Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError) expect { Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError)
end end
end end
describe "#disk" do describe '#disk' do
before :each do before :each do
@disk_response_body_success = "{\"ok\":true}" @disk_response_body_success = '{"ok":true}'
@disk_response_body_fail = "{\"ok\":false}" @disk_response_body_fail = '{"ok":false}'
end end
it "makes a request to extend disk space of a vm" do it 'makes a request to extend disk space of a vm' do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12"). stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12")
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @disk_response_body_success, :headers => {}) .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @disk_response_body_success, :headers => {})
disk_req = Pooler.disk(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12) disk_req = Pooler.disk(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12)
expect(disk_req["ok"]).to be true expect(disk_req['ok']).to be true
end end
it "raises a TokenError if no token was provided" do it 'raises a TokenError if no token was provided' do
expect{ Pooler.disk(false, @vmpooler_url, 'myfakehost', nil, 12) }.to raise_error(TokenError) expect { Pooler.disk(false, @vmpooler_url, 'myfakehost', nil, 12) }.to raise_error(TokenError)
end end
end end
end end

View file

@ -1,11 +1,12 @@
# frozen_string_literal: true
require_relative '../../lib/vmfloaty/service' require_relative '../../lib/vmfloaty/service'
describe Service do describe Service do
describe '#initialize' do describe '#initialize' do
it 'store configuration options' do it 'store configuration options' do
options = MockOptions.new({}) options = MockOptions.new({})
config = {'url' => 'http://example.url'} config = { 'url' => 'http://example.url' }
service = Service.new(options, config) service = Service.new(options, config)
expect(service.config).to include config expect(service.config).to include config
end end
@ -43,14 +44,14 @@ describe Service do
describe '#delete_token' do describe '#delete_token' do
it 'deletes a token' do it 'deletes a token' do
service = Service.new(MockOptions.new,{'user' => 'first.last', 'url' => 'http://default.url'}) service = Service.new(MockOptions.new, 'user' => 'first.last', 'url' => 'http://default.url')
allow(Commander::UI).to(receive(:password) allow(Commander::UI).to(receive(:password)
.with('Enter your pooler service password:', '*') .with('Enter your pooler service password:', '*')
.and_return('hunter2')) .and_return('hunter2'))
allow(Auth).to(receive(:delete_token) allow(Auth).to(receive(:delete_token)
.with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value') .with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value')
.and_return('ok' => true)) .and_return('ok' => true))
expect(service.delete_token(nil, 'token-value')).to eql({'ok' => true}) expect(service.delete_token(nil, 'token-value')).to eql('ok' => true)
end end
end end
@ -58,7 +59,7 @@ describe Service do
it 'reports the status of a token' do it 'reports the status of a token' do
config = { config = {
'user' => 'first.last', 'user' => 'first.last',
'url' => 'http://default.url' 'url' => 'http://default.url',
} }
options = MockOptions.new('token' => 'token-value') options = MockOptions.new('token' => 'token-value')
service = Service.new(options, config) service = Service.new(options, config)
@ -67,7 +68,7 @@ describe Service do
'user' => config['user'], 'user' => config['user'],
'created' => '2017-09-22 02:04:18 +0000', 'created' => '2017-09-22 02:04:18 +0000',
'last_accessed' => '2017-09-22 02:04:28 +0000', 'last_accessed' => '2017-09-22 02:04:28 +0000',
'reserved_hosts' => [] 'reserved_hosts' => [],
} }
allow(Auth).to(receive(:token_status) allow(Auth).to(receive(:token_status)
.with(nil, config['url'], 'token-value') .with(nil, config['url'], 'token-value')
@ -75,5 +76,4 @@ describe Service do
expect(service.token_status(nil, 'token-value')).to eql(status) expect(service.token_status(nil, 'token-value')).to eql(status)
end end
end end
end end

View file

@ -1,13 +1,14 @@
# frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
require 'json' require 'json'
require 'commander/command' require 'commander/command'
require_relative '../../lib/vmfloaty/utils' require_relative '../../lib/vmfloaty/utils'
describe Utils do describe Utils do
describe '#standardize_hostnames' do
describe "#standardize_hostnames" do
before :each do before :each do
@vmpooler_response_body ='{ @vmpooler_response_body = '{
"ok": true, "ok": true,
"domain": "delivery.mycompany.net", "domain": "delivery.mycompany.net",
"ubuntu-1610-x86_64": { "ubuntu-1610-x86_64": {
@ -28,79 +29,79 @@ describe Utils do
}' }'
end end
it "formats a result from vmpooler into a hash of os to hostnames" do it 'formats a result from vmpooler into a hash of os to hostnames' do
result = Utils.standardize_hostnames(JSON.parse(@vmpooler_response_body)) result = Utils.standardize_hostnames(JSON.parse(@vmpooler_response_body))
expect(result).to eq('centos-7-x86_64' => ["dlgietfmgeegry2.delivery.mycompany.net"], expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'],
'ubuntu-1610-x86_64' => ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"]) 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net'])
end end
it "formats a result from the nonstandard pooler into a hash of os to hostnames" do it 'formats a result from the nonstandard pooler into a hash of os to hostnames' do
result = Utils.standardize_hostnames(JSON.parse(@nonstandard_response_body)) result = Utils.standardize_hostnames(JSON.parse(@nonstandard_response_body))
expect(result).to eq('solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], expect(result).to eq('solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'],
'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net']) 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'])
end end
end end
describe "#format_host_output" do describe '#format_host_output' do
before :each do before :each do
@vmpooler_results = { @vmpooler_results = {
'centos-7-x86_64' => ["dlgietfmgeegry2.delivery.mycompany.net"], 'centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'],
'ubuntu-1610-x86_64' => ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"] 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net'],
} }
@nonstandard_results = { @nonstandard_results = {
'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], 'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'],
'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'] 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'],
} }
@vmpooler_output = <<-OUT.chomp @vmpooler_output = <<~OUT.chomp
- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) - dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64)
- gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64) - gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64)
- ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64) - ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64)
OUT OUT
@nonstandard_output = <<-OUT.chomp @nonstandard_output = <<~OUT.chomp
- sol10-10.delivery.mycompany.net (solaris-10-sparc) - sol10-10.delivery.mycompany.net (solaris-10-sparc)
- sol10-11.delivery.mycompany.net (solaris-10-sparc) - sol10-11.delivery.mycompany.net (solaris-10-sparc)
- power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8) - power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8)
OUT OUT
end end
it "formats a hostname hash from vmpooler into a list that includes the os" do it 'formats a hostname hash from vmpooler into a list that includes the os' do
expect(Utils.format_host_output(@vmpooler_results)).to eq(@vmpooler_output) expect(Utils.format_host_output(@vmpooler_results)).to eq(@vmpooler_output)
end end
it "formats a hostname hash from the nonstandard pooler into a list that includes the os" do it 'formats a hostname hash from the nonstandard pooler into a list that includes the os' do
expect(Utils.format_host_output(@nonstandard_results)).to eq(@nonstandard_output) expect(Utils.format_host_output(@nonstandard_results)).to eq(@nonstandard_output)
end end
end end
describe "#get_service_object" do describe '#get_service_object' do
it "assumes vmpooler by default" do it 'assumes vmpooler by default' do
expect(Utils.get_service_object).to be Pooler expect(Utils.get_service_object).to be Pooler
end end
it "uses nspooler when told explicitly" do it 'uses nspooler when told explicitly' do
expect(Utils.get_service_object "nspooler").to be NonstandardPooler expect(Utils.get_service_object('nspooler')).to be NonstandardPooler
end end
end end
describe "#get_service_config" do describe '#get_service_config' do
before :each do before :each do
@default_config = { @default_config = {
"url" => "http://default.url", 'url' => 'http://default.url',
"user" => "first.last.default", 'user' => 'first.last.default',
"token" => "default-token", 'token' => 'default-token',
} }
@services_config = { @services_config = {
"services" => { 'services' => {
"vm" => { 'vm' => {
"url" => "http://vmpooler.url", 'url' => 'http://vmpooler.url',
"user" => "first.last.vmpooler", 'user' => 'first.last.vmpooler',
"token" => "vmpooler-token" 'token' => 'vmpooler-token',
},
'ns' => {
'url' => 'http://nspooler.url',
'user' => 'first.last.nspooler',
'token' => 'nspooler-token',
},
}, },
"ns" => {
"url" => "http://nspooler.url",
"user" => "first.last.nspooler",
"token" => "nspooler-token"
}
}
} }
end end
@ -110,44 +111,44 @@ describe Utils do
expect(Utils.get_service_config(config, options)).to include @services_config['services']['vm'] expect(Utils.get_service_config(config, options)).to include @services_config['services']['vm']
end end
it "allows selection by configured service key" do it 'allows selection by configured service key' do
config = @default_config.merge @services_config config = @default_config.merge @services_config
options = MockOptions.new({:service => "ns"}) options = MockOptions.new(:service => 'ns')
expect(Utils.get_service_config(config, options)).to include @services_config['services']['ns'] expect(Utils.get_service_config(config, options)).to include @services_config['services']['ns']
end end
it "uses top-level service config values as defaults when configured service values are missing" do it 'uses top-level service config values as defaults when configured service values are missing' do
config = @default_config.merge @services_config config = @default_config.merge @services_config
config["services"]['vm'].delete 'url' config['services']['vm'].delete 'url'
options = MockOptions.new({:service => "vm"}) options = MockOptions.new(:service => 'vm')
expect(Utils.get_service_config(config, options)['url']).to eq 'http://default.url' expect(Utils.get_service_config(config, options)['url']).to eq 'http://default.url'
end end
it "raises an error if passed a service name that hasn't been configured" do it "raises an error if passed a service name that hasn't been configured" do
config = @default_config.merge @services_config config = @default_config.merge @services_config
options = MockOptions.new({:service => "none"}) options = MockOptions.new(:service => 'none')
expect { Utils.get_service_config(config, options) }.to raise_error ArgumentError expect { Utils.get_service_config(config, options) }.to raise_error ArgumentError
end end
it "prioritizes values passed as command line options over configuration options" do it 'prioritizes values passed as command line options over configuration options' do
config = @default_config config = @default_config
options = MockOptions.new({:url => "http://alternate.url", :token => "alternate-token"}) options = MockOptions.new(:url => 'http://alternate.url', :token => 'alternate-token')
expected = config.merge({"url" => "http://alternate.url", "token" => "alternate-token"}) expected = config.merge('url' => 'http://alternate.url', 'token' => 'alternate-token')
expect(Utils.get_service_config(config, options)).to include expected expect(Utils.get_service_config(config, options)).to include expected
end end
end end
describe "#generate_os_hash" do describe '#generate_os_hash' do
before :each do before :each do
@host_hash = {"centos"=>1, "debian"=>5, "windows"=>1} @host_hash = { 'centos' => 1, 'debian' => 5, 'windows' => 1 }
end end
it "takes an array of os arguments and returns a formatted hash" do it 'takes an array of os arguments and returns a formatted hash' do
host_arg = ["centos", "debian=5", "windows=1"] host_arg = ['centos', 'debian=5', 'windows=1']
expect(Utils.generate_os_hash(host_arg)).to eq @host_hash expect(Utils.generate_os_hash(host_arg)).to eq @host_hash
end end
it "returns an empty hash if there are no arguments provided" do it 'returns an empty hash if there are no arguments provided' do
host_arg = [] host_arg = []
expect(Utils.generate_os_hash(host_arg)).to be_empty expect(Utils.generate_os_hash(host_arg)).to be_empty
end end
@ -164,13 +165,13 @@ describe Utils do
'running' => 9.66, 'running' => 9.66,
'state' => 'running', 'state' => 'running',
'ip' => '127.0.0.1', 'ip' => '127.0.0.1',
'domain' => 'delivery.mycompany.net' 'domain' => 'delivery.mycompany.net',
}} } }
output = "- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)" output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)'
expect(Utils).to receive(:puts).with(output) expect(Utils).to receive(:puts).with(output)
service = Service.new(MockOptions.new, {'url' => url}) service = Service.new(MockOptions.new, 'url' => url)
allow(service).to receive(:query) allow(service).to receive(:query)
.with(nil, hostname) .with(nil, hostname)
.and_return(response_body) .and_return(response_body)
@ -187,16 +188,16 @@ describe Utils do
'state' => 'running', 'state' => 'running',
'tags' => { 'tags' => {
'user' => 'bob', 'user' => 'bob',
'role' => 'agent' 'role' => 'agent',
}, },
'ip' => '127.0.0.1', 'ip' => '127.0.0.1',
'domain' => 'delivery.mycompany.net' 'domain' => 'delivery.mycompany.net',
}} } }
output = "- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)'
expect(Utils).to receive(:puts).with(output) expect(Utils).to receive(:puts).with(output)
service = Service.new(MockOptions.new, {'url' => url}) service = Service.new(MockOptions.new, 'url' => url)
allow(service).to receive(:query) allow(service).to receive(:query)
.with(nil, hostname) .with(nil, hostname)
.and_return(response_body) .and_return(response_body)
@ -205,19 +206,19 @@ describe Utils do
end end
it 'prints a nonstandard pooler output with host, template, and time remaining' do it 'prints a nonstandard pooler output with host, template, and time remaining' do
hostname = "sol11-9.delivery.mycompany.net" hostname = 'sol11-9.delivery.mycompany.net'
response_body = { hostname => { response_body = { hostname => {
'fqdn' => hostname, 'fqdn' => hostname,
'os_triple' => 'solaris-11-sparc', 'os_triple' => 'solaris-11-sparc',
'reserved_by_user' => 'first.last', 'reserved_by_user' => 'first.last',
'reserved_for_reason' => '', 'reserved_for_reason' => '',
'hours_left_on_reservation' => 35.89 'hours_left_on_reservation' => 35.89,
}} } }
output = "- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)" output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)'
expect(Utils).to receive(:puts).with(output) expect(Utils).to receive(:puts).with(output)
service = Service.new(MockOptions.new, {'url' => url, 'type' => 'ns'}) service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
allow(service).to receive(:query) allow(service).to receive(:query)
.with(nil, hostname) .with(nil, hostname)
.and_return(response_body) .and_return(response_body)
@ -232,13 +233,13 @@ describe Utils do
'os_triple' => 'solaris-11-sparc', 'os_triple' => 'solaris-11-sparc',
'reserved_by_user' => 'first.last', 'reserved_by_user' => 'first.last',
'reserved_for_reason' => 'testing', 'reserved_for_reason' => 'testing',
'hours_left_on_reservation' => 35.89 'hours_left_on_reservation' => 35.89,
}} } }
output = "- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)" output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)'
expect(Utils).to receive(:puts).with(output) expect(Utils).to receive(:puts).with(output)
service = Service.new(MockOptions.new, {'url' => url, 'type' => 'ns'}) service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
allow(service).to receive(:query) allow(service).to receive(:query)
.with(nil, hostname) .with(nil, hostname)
.and_return(response_body) .and_return(response_body)

View file

@ -1,4 +1,6 @@
$LOAD_PATH.push File.expand_path('../lib', __FILE__) # frozen_string_literal: true
$LOAD_PATH.push File.expand_path('lib', __dir__)
require 'vmfloaty/version' require 'vmfloaty/version'
Gem::Specification.new do |s| Gem::Specification.new do |s|
@ -16,7 +18,7 @@ Gem::Specification.new do |s|
s.test_files = Dir['spec/**/*'] s.test_files = Dir['spec/**/*']
s.require_path = 'lib' s.require_path = 'lib'
s.add_dependency 'colorize', '~> 0.8.1'
s.add_dependency 'commander', '~> 4.4.3' s.add_dependency 'commander', '~> 4.4.3'
s.add_dependency 'faraday', '~> 0.9.0' s.add_dependency 'faraday', '~> 0.9.0'
s.add_dependency 'colorize', '~> 0.8.1'
end end