mirror of
https://github.com/puppetlabs/vmfloaty.git
synced 2026-01-26 05:28:40 -05:00
commit
d57b168153
24 changed files with 689 additions and 689 deletions
20
.rubocop.yml
Normal file
20
.rubocop.yml
Normal 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
46
.rubocop_todo.yml
Normal 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
|
||||
|
|
@ -2,4 +2,4 @@ sudo: false
|
|||
language: ruby
|
||||
rvm:
|
||||
- 2.4
|
||||
script: rspec spec
|
||||
script: bundle exec rake rubocop spec
|
||||
|
|
|
|||
4
Gemfile
4
Gemfile
|
|
@ -1,8 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gemspec
|
||||
|
||||
gem 'rake', require: false
|
||||
gem 'rake', :require => false
|
||||
|
||||
group :test do
|
||||
gem 'rspec', '~> 3.5.0'
|
||||
|
|
|
|||
6
Rakefile
6
Rakefile
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
require 'rspec/core/rake_task'
|
||||
|
|
@ -9,7 +11,7 @@ $stdout.sync = true
|
|||
$stderr.sync = true
|
||||
|
||||
# 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
|
||||
# publishing.
|
||||
|
|
@ -26,4 +28,4 @@ RuboCop::RakeTask.new(:rubocop) do |task|
|
|||
end
|
||||
|
||||
# Default task is to run the unit tests
|
||||
task default: :spec
|
||||
task :default => :spec
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/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'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rubygems'
|
||||
require 'commander'
|
||||
|
|
@ -43,22 +43,22 @@ class Vmfloaty
|
|||
force = options.force
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
os_types = Utils.generate_os_hash(args)
|
||||
|
||||
max_pool_request = 5
|
||||
large_pool_requests = os_types.select{|_,v| v > max_pool_request}
|
||||
if ! large_pool_requests.empty? and ! force
|
||||
large_pool_requests = os_types.select { |_, v| v > max_pool_request }
|
||||
if !large_pool_requests.empty? && !force
|
||||
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
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
|
|
@ -143,18 +143,18 @@ class Vmfloaty
|
|||
hostname = args[0]
|
||||
modify_all = options.all
|
||||
|
||||
if hostname.nil? and !modify_all
|
||||
STDERR.puts "ERROR: Provide a hostname or specify --all."
|
||||
if hostname.nil? && !modify_all
|
||||
STDERR.puts 'ERROR: Provide a hostname or specify --all.'
|
||||
exit 1
|
||||
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
|
||||
modify_hash = {
|
||||
lifetime: options.lifetime,
|
||||
disk: options.disk,
|
||||
tags: tags,
|
||||
reason: options.reason
|
||||
:lifetime => options.lifetime,
|
||||
:disk => options.disk,
|
||||
:tags => tags,
|
||||
:reason => options.reason,
|
||||
}
|
||||
modify_hash.delete_if { |_, value| value.nil? }
|
||||
|
||||
|
|
@ -171,11 +171,11 @@ class Vmfloaty
|
|||
end
|
||||
if ok
|
||||
if modify_all
|
||||
puts "Successfully modified all VMs."
|
||||
puts 'Successfully modified all VMs.'
|
||||
else
|
||||
puts "Successfully modified VM #{hostname}."
|
||||
end
|
||||
puts "Use `floaty list --active` to see the results."
|
||||
puts 'Use `floaty list --active` to see the results.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -205,15 +205,13 @@ class Vmfloaty
|
|||
if delete_all
|
||||
running_vms = service.list_active(verbose)
|
||||
if running_vms.empty?
|
||||
STDERR.puts "You have no running VMs."
|
||||
STDERR.puts 'You have no running VMs.'
|
||||
else
|
||||
Utils.pretty_print_hosts(verbose, service, running_vms)
|
||||
# Confirm deletion
|
||||
puts
|
||||
confirmed = true
|
||||
unless force
|
||||
confirmed = agree('Delete all these VMs? [y/N]')
|
||||
end
|
||||
confirmed = agree('Delete all these VMs? [y/N]') unless force
|
||||
if confirmed
|
||||
response = service.delete(verbose, running_vms)
|
||||
response.each do |hostname, result|
|
||||
|
|
@ -236,7 +234,7 @@ class Vmfloaty
|
|||
end
|
||||
end
|
||||
else
|
||||
STDERR.puts "You did not provide any hosts to delete"
|
||||
STDERR.puts 'You did not provide any hosts to delete'
|
||||
exit 1
|
||||
end
|
||||
|
||||
|
|
@ -302,9 +300,7 @@ class Vmfloaty
|
|||
hostname = args[0]
|
||||
snapshot_sha = args[1] || options.snapshot
|
||||
|
||||
if args[1] && options.snapshot
|
||||
STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}"
|
||||
end
|
||||
STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
|
||||
|
||||
begin
|
||||
revert_req = service.revert(verbose, hostname, snapshot_sha)
|
||||
|
|
@ -372,25 +368,23 @@ class Vmfloaty
|
|||
|
||||
begin
|
||||
case action
|
||||
when 'get'
|
||||
token = service.get_new_token(verbose)
|
||||
puts token
|
||||
when 'delete'
|
||||
result = service.delete_token(verbose, options.token)
|
||||
puts result
|
||||
when 'status'
|
||||
token_value = options.token
|
||||
if token_value.nil?
|
||||
token_value = args[1]
|
||||
end
|
||||
status = service.token_status(verbose, token_value)
|
||||
puts status
|
||||
when nil
|
||||
STDERR.puts 'No action provided'
|
||||
exit 1
|
||||
else
|
||||
STDERR.puts "Unknown action: #{action}"
|
||||
exit 1
|
||||
when 'get'
|
||||
token = service.get_new_token(verbose)
|
||||
puts token
|
||||
when 'delete'
|
||||
result = service.delete_token(verbose, options.token)
|
||||
puts result
|
||||
when 'status'
|
||||
token_value = options.token
|
||||
token_value = args[1] if token_value.nil?
|
||||
status = service.token_status(verbose, token_value)
|
||||
puts status
|
||||
when nil
|
||||
STDERR.puts 'No action provided'
|
||||
exit 1
|
||||
else
|
||||
STDERR.puts "Unknown action: #{action}"
|
||||
exit 1
|
||||
end
|
||||
rescue TokenError => e
|
||||
STDERR.puts e
|
||||
|
|
@ -417,15 +411,13 @@ class Vmfloaty
|
|||
use_token = !options.notoken
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
host_os = args.first
|
||||
|
||||
if args.length > 1
|
||||
STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..."
|
||||
end
|
||||
STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
|
||||
|
||||
service.ssh(verbose, host_os, use_token)
|
||||
exit 0
|
||||
|
|
@ -435,13 +427,13 @@ class Vmfloaty
|
|||
command :completion do |c|
|
||||
c.syntax = 'floaty completion [options]'
|
||||
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:
|
||||
|
||||
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.
|
||||
EOF
|
||||
DESCRIPTION
|
||||
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.action do |_, options|
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'faraday'
|
||||
require 'json'
|
||||
require 'vmfloaty/http'
|
||||
|
|
@ -7,46 +9,36 @@ class Auth
|
|||
def self.get_token(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)
|
||||
if res_body["ok"]
|
||||
return res_body["token"]
|
||||
else
|
||||
raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}"
|
||||
end
|
||||
return res_body['token'] if res_body['ok']
|
||||
|
||||
raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}"
|
||||
end
|
||||
|
||||
def self.delete_token(verbose, url, user, password, token)
|
||||
if token.nil?
|
||||
raise TokenError, 'You did not provide a token'
|
||||
end
|
||||
raise TokenError, 'You did not provide a token' if token.nil?
|
||||
|
||||
conn = Http.get_conn_with_auth(verbose, url, user, password)
|
||||
|
||||
response = conn.delete "token/#{token}"
|
||||
res_body = JSON.parse(response.body)
|
||||
if res_body["ok"]
|
||||
return res_body
|
||||
else
|
||||
raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}"
|
||||
end
|
||||
return res_body if res_body['ok']
|
||||
|
||||
raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}"
|
||||
end
|
||||
|
||||
def self.token_status(verbose, url, token)
|
||||
if token.nil?
|
||||
raise TokenError, 'You did not provide a token'
|
||||
end
|
||||
raise TokenError, 'You did not provide a token' if token.nil?
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
|
||||
response = conn.get "token/#{token}"
|
||||
res_body = JSON.parse(response.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}"
|
||||
end
|
||||
return res_body if res_body['ok']
|
||||
|
||||
raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'yaml'
|
||||
|
||||
class Conf
|
||||
|
||||
def self.read_config
|
||||
conf = {}
|
||||
begin
|
||||
conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml")
|
||||
rescue
|
||||
rescue StandardError
|
||||
STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml"
|
||||
end
|
||||
conf
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AuthError < StandardError
|
||||
def initialize(msg="Could not authenticate to pooler")
|
||||
def initialize(msg = 'Could not authenticate to pooler')
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
class TokenError < StandardError
|
||||
def initialize(msg="Could not do operation with token provided")
|
||||
def initialize(msg = 'Could not do operation with token provided')
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
class MissingParamError < StandardError
|
||||
def initialize(msg="Argument provided to function is missing")
|
||||
def initialize(msg = 'Argument provided to function is missing')
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
class ModifyError < StandardError
|
||||
def initialize(msg="Could not modify VM")
|
||||
def initialize(msg = 'Could not modify VM')
|
||||
super
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,60 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'faraday'
|
||||
require 'uri'
|
||||
|
||||
class Http
|
||||
def self.is_url(url)
|
||||
def self.url?(url)
|
||||
# This method exists because it seems like Farady
|
||||
# has no handling around if a user gives us a URI
|
||||
# with no protocol on the beginning of the URL
|
||||
|
||||
uri = URI.parse(url)
|
||||
|
||||
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS)
|
||||
return true
|
||||
end
|
||||
return true if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
|
||||
|
||||
return false
|
||||
false
|
||||
end
|
||||
|
||||
def self.get_conn(verbose, url)
|
||||
if url.nil?
|
||||
raise "Did not provide a url to connect to"
|
||||
end
|
||||
raise 'Did not provide a url to connect to' if url.nil?
|
||||
|
||||
unless is_url(url)
|
||||
url = "https://#{url}"
|
||||
end
|
||||
url = "https://#{url}" unless url?(url)
|
||||
|
||||
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.response :logger if verbose
|
||||
faraday.adapter Faraday.default_adapter
|
||||
end
|
||||
|
||||
return conn
|
||||
conn
|
||||
end
|
||||
|
||||
def self.get_conn_with_auth(verbose, url, user, password)
|
||||
if url.nil?
|
||||
raise "Did not provide a url to connect to"
|
||||
end
|
||||
raise 'Did not provide a url to connect to' if url.nil?
|
||||
|
||||
if user.nil?
|
||||
raise "You did not provide a user to authenticate with"
|
||||
end
|
||||
raise 'You did not provide a user to authenticate with' if user.nil?
|
||||
|
||||
unless is_url(url)
|
||||
url = "https://#{url}"
|
||||
end
|
||||
url = "https://#{url}" unless url?(url)
|
||||
|
||||
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 :basic_auth, user, password
|
||||
faraday.response :logger if verbose
|
||||
faraday.adapter Faraday.default_adapter
|
||||
end
|
||||
|
||||
return conn
|
||||
conn
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'vmfloaty/errors'
|
||||
require 'vmfloaty/http'
|
||||
require 'faraday'
|
||||
|
|
@ -24,18 +26,8 @@ class NonstandardPooler
|
|||
conn = Http.get_conn(verbose, url)
|
||||
conn.headers['X-AUTH-TOKEN'] = token if token
|
||||
|
||||
os_string = ''
|
||||
os_type.each do |os, num|
|
||||
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
|
||||
os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
|
||||
raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
|
||||
|
||||
response = conn.post "host/#{os_string}"
|
||||
|
||||
|
|
@ -51,14 +43,10 @@ class NonstandardPooler
|
|||
end
|
||||
|
||||
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'
|
||||
end
|
||||
raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' if token.nil?
|
||||
|
||||
modify_hash.each do |key, value|
|
||||
unless [:reason, :reserved_for_reason].include? key
|
||||
raise ModifyError, "Configured service type does not support modification of #{key}"
|
||||
end
|
||||
modify_hash.each do |key, _value|
|
||||
raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason reserved_for_reason].include? key
|
||||
end
|
||||
|
||||
if modify_hash[:reason]
|
||||
|
|
@ -77,22 +65,20 @@ class NonstandardPooler
|
|||
response.body.empty? ? {} : JSON.parse(response.body)
|
||||
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'
|
||||
end
|
||||
|
||||
def self.snapshot(verbose, url, hostname, token)
|
||||
def self.snapshot(_verbose, _url, _hostname, _token)
|
||||
raise ModifyError, 'Configured service type does not support snapshots'
|
||||
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'
|
||||
end
|
||||
|
||||
def self.delete(verbose, url, hosts, token)
|
||||
if token.nil?
|
||||
raise TokenError, 'Token provided was nil; Request cannot be made to delete VM'
|
||||
end
|
||||
raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil?
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
|
||||
|
|
@ -100,9 +86,7 @@ class NonstandardPooler
|
|||
|
||||
response_body = {}
|
||||
|
||||
unless hosts.is_a? Array
|
||||
hosts = hosts.split(',')
|
||||
end
|
||||
hosts = hosts.split(',') unless hosts.is_a? Array
|
||||
hosts.each do |host|
|
||||
response = conn.delete "host/#{host}"
|
||||
res_body = JSON.parse(response.body)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'faraday'
|
||||
require 'vmfloaty/http'
|
||||
require 'json'
|
||||
require 'vmfloaty/errors'
|
||||
|
||||
class Pooler
|
||||
def self.list(verbose, url, os_filter=nil)
|
||||
def self.list(verbose, url, os_filter = nil)
|
||||
conn = Http.get_conn(verbose, url)
|
||||
|
||||
response = conn.get 'vm'
|
||||
response_body = JSON.parse(response.body)
|
||||
|
||||
if os_filter
|
||||
hosts = response_body.select { |i| i[/#{os_filter}/] }
|
||||
else
|
||||
hosts = response_body
|
||||
end
|
||||
hosts = if os_filter
|
||||
response_body.select { |i| i[/#{os_filter}/] }
|
||||
else
|
||||
response_body
|
||||
end
|
||||
|
||||
hosts
|
||||
end
|
||||
|
|
@ -22,9 +24,7 @@ class Pooler
|
|||
def self.list_active(verbose, url, token)
|
||||
status = Auth.token_status(verbose, url, token)
|
||||
vms = []
|
||||
if status[token] && status[token]['vms']
|
||||
vms = status[token]['vms']['running']
|
||||
end
|
||||
vms = status[token]['vms']['running'] if status[token] && status[token]['vms']
|
||||
vms
|
||||
end
|
||||
|
||||
|
|
@ -33,28 +33,16 @@ class Pooler
|
|||
# Developers can use `Utils.generate_os_hash` to
|
||||
# generate the os_type param.
|
||||
conn = Http.get_conn(verbose, url)
|
||||
if token
|
||||
conn.headers['X-AUTH-TOKEN'] = token
|
||||
end
|
||||
conn.headers['X-AUTH-TOKEN'] = token if token
|
||||
|
||||
os_string = ""
|
||||
os_type.each do |os,num|
|
||||
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
|
||||
os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
|
||||
raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
|
||||
|
||||
response = conn.post "vm/#{os_string}"
|
||||
|
||||
res_body = JSON.parse(response.body)
|
||||
|
||||
if res_body["ok"]
|
||||
if res_body['ok']
|
||||
res_body
|
||||
elsif response.status == 401
|
||||
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
|
||||
|
|
@ -64,14 +52,10 @@ class Pooler
|
|||
end
|
||||
|
||||
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"
|
||||
end
|
||||
raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil?
|
||||
|
||||
modify_hash.keys.each do |key|
|
||||
unless [:tags, :lifetime, :disk].include? key
|
||||
raise ModifyError, "Configured service type does not support modification of #{key}."
|
||||
end
|
||||
raise ModifyError, "Configured service type does not support modification of #{key}." unless %i[tags lifetime disk].include? key
|
||||
end
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
|
|
@ -92,9 +76,7 @@ class Pooler
|
|||
end
|
||||
|
||||
def self.disk(verbose, url, hostname, token, disk)
|
||||
if token.nil?
|
||||
raise TokenError, "Token provided was nil. Request cannot be made to modify vm"
|
||||
end
|
||||
raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil?
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
conn.headers['X-AUTH-TOKEN'] = token
|
||||
|
|
@ -106,15 +88,11 @@ class Pooler
|
|||
end
|
||||
|
||||
def self.delete(verbose, url, hosts, token)
|
||||
if token.nil?
|
||||
raise TokenError, "Token provided was nil. Request cannot be made to delete vm"
|
||||
end
|
||||
raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' if token.nil?
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
|
||||
if token
|
||||
conn.headers['X-AUTH-TOKEN'] = token
|
||||
end
|
||||
conn.headers['X-AUTH-TOKEN'] = token if token
|
||||
|
||||
response_body = {}
|
||||
|
||||
|
|
@ -153,9 +131,7 @@ class Pooler
|
|||
end
|
||||
|
||||
def self.snapshot(verbose, url, hostname, token)
|
||||
if token.nil?
|
||||
raise TokenError, "Token provided was nil. Request cannot be made to snapshot vm"
|
||||
end
|
||||
raise TokenError, 'Token provided was nil. Request cannot be made to snapshot vm' if token.nil?
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
conn.headers['X-AUTH-TOKEN'] = token
|
||||
|
|
@ -166,16 +142,12 @@ class Pooler
|
|||
end
|
||||
|
||||
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"
|
||||
end
|
||||
raise TokenError, 'Token provided was nil. Request cannot be made to revert vm' if token.nil?
|
||||
|
||||
conn = Http.get_conn(verbose, url)
|
||||
conn.headers['X-AUTH-TOKEN'] = token
|
||||
|
||||
if snapshot_sha.nil?
|
||||
raise "Snapshot SHA provided was nil, could not revert #{hostname}"
|
||||
end
|
||||
raise "Snapshot SHA provided was nil, could not revert #{hostname}" if snapshot_sha.nil?
|
||||
|
||||
response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}"
|
||||
res_body = JSON.parse(response.body)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'commander/user_interaction'
|
||||
require 'commander/command'
|
||||
require 'vmfloaty/utils'
|
||||
require 'vmfloaty/ssh'
|
||||
|
||||
class Service
|
||||
|
||||
attr_reader :config
|
||||
|
||||
def initialize(options, config_hash = {})
|
||||
|
|
@ -13,14 +14,18 @@ class Service
|
|||
@service_object = Utils.get_service_object @config['type']
|
||||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
if @service_object.respond_to? m
|
||||
@service_object.send(m, *args, &block)
|
||||
def method_missing(method_name, *args, &block)
|
||||
if @service_object.respond_to?(method_name)
|
||||
@service_object.send(method_name, *args, &block)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def respond_to_missing?(method_name, *)
|
||||
@service_object.respond_to?(method_name) || super
|
||||
end
|
||||
|
||||
def url
|
||||
@config['url']
|
||||
end
|
||||
|
|
@ -31,7 +36,7 @@ class Service
|
|||
|
||||
def user
|
||||
unless @config['user']
|
||||
puts "Enter your pooler service username:"
|
||||
puts 'Enter your pooler service username:'
|
||||
@config['user'] = STDIN.gets.chomp
|
||||
end
|
||||
@config['user']
|
||||
|
|
@ -39,7 +44,7 @@ class Service
|
|||
|
||||
def token
|
||||
unless @config['token']
|
||||
puts "No token found. Retrieving a token..."
|
||||
puts 'No token found. Retrieving a token...'
|
||||
@config['token'] = get_new_token(nil)
|
||||
end
|
||||
@config['token']
|
||||
|
|
@ -47,13 +52,13 @@ class Service
|
|||
|
||||
def get_new_token(verbose)
|
||||
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)
|
||||
end
|
||||
|
||||
def delete_token(verbose, token_value = @config['token'])
|
||||
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)
|
||||
end
|
||||
|
||||
|
|
@ -91,9 +96,9 @@ class Service
|
|||
|
||||
def pretty_print_running(verbose, hostnames = [])
|
||||
if hostnames.empty?
|
||||
puts "You have no running VMs."
|
||||
puts 'You have no running VMs.'
|
||||
else
|
||||
puts "Running VMs:"
|
||||
puts 'Running VMs:'
|
||||
@service_object.pretty_print_hosts(verbose, hostnames, url)
|
||||
end
|
||||
end
|
||||
|
|
@ -129,5 +134,4 @@ class Service
|
|||
def disk(verbose, hostname, disk)
|
||||
@service_object.disk(verbose, url, hostname, token, disk)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,43 +1,37 @@
|
|||
class Ssh
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Ssh
|
||||
def self.which(cmd)
|
||||
# Gets path of executable for given command
|
||||
|
||||
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
||||
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
||||
exts.each { |ext|
|
||||
exts.each do |ext|
|
||||
exe = File.join(path, "#{cmd}#{ext}")
|
||||
return exe if File.executable?(exe) && !File.directory?(exe)
|
||||
}
|
||||
end
|
||||
end
|
||||
return nil
|
||||
nil
|
||||
end
|
||||
|
||||
def self.ssh(verbose, host_os, token, url)
|
||||
ssh_path = which("ssh")
|
||||
if !ssh_path
|
||||
raise "Could not determine path to ssh"
|
||||
end
|
||||
ssh_path = which('ssh')
|
||||
raise 'Could not determine path to ssh' unless ssh_path
|
||||
|
||||
os_types = {}
|
||||
os_types[host_os] = 1
|
||||
|
||||
response = Pooler.retrieve(verbose, os_types, token, url)
|
||||
if response["ok"] == true
|
||||
if host_os =~ /win/
|
||||
user = "Administrator"
|
||||
else
|
||||
user = "root"
|
||||
end
|
||||
raise "Could not get vm from vmpooler:\n #{response}" unless response['ok']
|
||||
|
||||
hostname = "#{response[host_os]["hostname"]}.#{response["domain"]}"
|
||||
cmd = "#{ssh_path} #{user}@#{hostname}"
|
||||
user = /win/.match?(host_os) ? 'Administrator' : 'root'
|
||||
|
||||
# TODO: Should this respect more ssh settings? Can it be configured
|
||||
# by users ssh config and does this respect those settings?
|
||||
Kernel.exec(cmd)
|
||||
else
|
||||
raise "Could not get vm from vmpooler:\n #{response}"
|
||||
end
|
||||
return
|
||||
hostname = "#{response[host_os]['hostname']}.#{response['domain']}"
|
||||
cmd = "#{ssh_path} #{user}@#{hostname}"
|
||||
|
||||
# TODO: Should this respect more ssh settings? Can it be configured
|
||||
# by users ssh config and does this respect those settings?
|
||||
Kernel.exec(cmd)
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'vmfloaty/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}"
|
||||
end
|
||||
raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok')
|
||||
|
||||
# vmpooler reports the domain separately from the hostname
|
||||
domain = response_body.delete('domain')
|
||||
|
|
@ -39,9 +39,7 @@ class Utils
|
|||
|
||||
response_body.each do |os, value|
|
||||
hostnames = Array(value['hostname'])
|
||||
if domain
|
||||
hostnames.map! {|host| "#{host}.#{domain}"}
|
||||
end
|
||||
hostnames.map! { |host| "#{host}.#{domain}" } if domain
|
||||
result[os] = hostnames
|
||||
end
|
||||
|
||||
|
|
@ -65,13 +63,8 @@ class Utils
|
|||
# ...]
|
||||
os_types = {}
|
||||
os_args.each do |arg|
|
||||
os_arr = arg.split("=")
|
||||
if os_arr.size == 1
|
||||
# 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
|
||||
os_arr = arg.split('=')
|
||||
os_types[os_arr[0]] = os_arr.size == 1 ? 1 : os_arr[1].to_i
|
||||
end
|
||||
os_types
|
||||
end
|
||||
|
|
@ -84,26 +77,22 @@ class Utils
|
|||
host_data = response[hostname]
|
||||
|
||||
case service.type
|
||||
when 'Pooler'
|
||||
tag_pairs = []
|
||||
unless host_data['tags'].nil?
|
||||
tag_pairs = host_data['tags'].map {|key, value| "#{key}: #{value}"}
|
||||
end
|
||||
duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
|
||||
metadata = [host_data['template'], duration, *tag_pairs]
|
||||
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(", ")})"
|
||||
when 'NonstandardPooler'
|
||||
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
|
||||
line += ", #{host_data['hours_left_on_reservation']}h remaining"
|
||||
unless host_data['reserved_for_reason'].empty?
|
||||
line += ", reason: #{host_data['reserved_for_reason']}"
|
||||
end
|
||||
line += ')'
|
||||
puts line
|
||||
else
|
||||
raise "Invalid service type #{service.type}"
|
||||
when 'Pooler'
|
||||
tag_pairs = []
|
||||
tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil?
|
||||
duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
|
||||
metadata = [host_data['template'], duration, *tag_pairs]
|
||||
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})"
|
||||
when 'NonstandardPooler'
|
||||
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
|
||||
line += ", #{host_data['hours_left_on_reservation']}h remaining"
|
||||
line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty?
|
||||
line += ')'
|
||||
puts line
|
||||
else
|
||||
raise "Invalid service type #{service.type}"
|
||||
end
|
||||
rescue => e
|
||||
rescue StandardError => e
|
||||
STDERR.puts("Something went wrong while trying to gather information on #{hostname}:")
|
||||
STDERR.puts(e)
|
||||
end
|
||||
|
|
@ -114,45 +103,45 @@ class Utils
|
|||
status_response = service.status(verbose)
|
||||
|
||||
case service.type
|
||||
when 'Pooler'
|
||||
message = status_response['status']['message']
|
||||
pools = status_response['pools']
|
||||
pools.select! {|_, pool| pool['ready'] < pool['max']} unless verbose
|
||||
when 'Pooler'
|
||||
message = status_response['status']['message']
|
||||
pools = status_response['pools']
|
||||
pools.select! { |_, pool| pool['ready'] < pool['max'] } unless verbose
|
||||
|
||||
width = pools.keys.map(&:length).max
|
||||
pools.each do |name, pool|
|
||||
begin
|
||||
max = pool['max']
|
||||
ready = pool['ready']
|
||||
pending = pool['pending']
|
||||
missing = max - ready - pending
|
||||
char = 'o'
|
||||
puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}"
|
||||
rescue => e
|
||||
puts "#{name.ljust(width)} #{e.red}"
|
||||
end
|
||||
width = pools.keys.map(&:length).max
|
||||
pools.each do |name, pool|
|
||||
begin
|
||||
max = pool['max']
|
||||
ready = pool['ready']
|
||||
pending = pool['pending']
|
||||
missing = max - ready - pending
|
||||
char = 'o'
|
||||
puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
|
||||
rescue StandardError => e
|
||||
puts "#{name.ljust(width)} #{e.red}"
|
||||
end
|
||||
puts message.colorize(status_response['status']['ok'] ? :default : :red)
|
||||
when 'NonstandardPooler'
|
||||
pools = status_response
|
||||
pools.delete 'ok'
|
||||
pools.select! {|_, pool| pool['available_hosts'] < pool['total_hosts']} unless verbose
|
||||
end
|
||||
puts message.colorize(status_response['status']['ok'] ? :default : :red)
|
||||
when 'NonstandardPooler'
|
||||
pools = status_response
|
||||
pools.delete 'ok'
|
||||
pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose
|
||||
|
||||
width = pools.keys.map(&:length).max
|
||||
pools.each do |name, pool|
|
||||
begin
|
||||
max = pool['total_hosts']
|
||||
ready = pool['available_hosts']
|
||||
pending = pool['pending'] || 0 # not available for nspooler
|
||||
missing = max - ready - pending
|
||||
char = 'o'
|
||||
puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}"
|
||||
rescue => e
|
||||
puts "#{name.ljust(width)} #{e.red}"
|
||||
end
|
||||
width = pools.keys.map(&:length).max
|
||||
pools.each do |name, pool|
|
||||
begin
|
||||
max = pool['total_hosts']
|
||||
ready = pool['available_hosts']
|
||||
pending = pool['pending'] || 0 # not available for nspooler
|
||||
missing = max - ready - pending
|
||||
char = 'o'
|
||||
puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
|
||||
rescue StandardError => e
|
||||
puts "#{name.ljust(width)} #{e.red}"
|
||||
end
|
||||
else
|
||||
raise "Invalid service type #{service.type}"
|
||||
end
|
||||
else
|
||||
raise "Invalid service type #{service.type}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -165,7 +154,7 @@ class Utils
|
|||
end
|
||||
|
||||
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
|
||||
NonstandardPooler
|
||||
else
|
||||
|
|
@ -176,10 +165,10 @@ class Utils
|
|||
def self.get_service_config(config, options)
|
||||
# The top-level url, user, and token values in the config file are treated as defaults
|
||||
service_config = {
|
||||
'url' => config['url'],
|
||||
'user' => config['user'],
|
||||
'token' => config['token'],
|
||||
'type' => config['type'] || 'vmpooler'
|
||||
'url' => config['url'],
|
||||
'user' => config['user'],
|
||||
'token' => config['token'],
|
||||
'type' => config['type'] || 'vmpooler',
|
||||
}
|
||||
|
||||
if config['services']
|
||||
|
|
@ -190,12 +179,10 @@ class Utils
|
|||
service_config.merge! values
|
||||
else
|
||||
# If the user provided a service name at the command line, use that service if posible, or fail
|
||||
if config['services'][options.service]
|
||||
# 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]
|
||||
else
|
||||
raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml"
|
||||
end
|
||||
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
|
||||
service_config.merge! config['services'][options.service]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Vmfloaty
|
||||
VERSION = '0.8.2'.freeze
|
||||
VERSION = '0.8.2'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'vmfloaty'
|
||||
require 'webmock/rspec'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,86 +1,88 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_relative '../../lib/vmfloaty/auth'
|
||||
|
||||
describe Pooler do
|
||||
before :each do
|
||||
@vmpooler_url = "https://vmpooler.example.com"
|
||||
@vmpooler_url = 'https://vmpooler.example.com'
|
||||
end
|
||||
|
||||
describe "#get_token" do
|
||||
describe '#get_token' do
|
||||
before :each do
|
||||
@get_token_response = "{\"ok\": true,\"token\":\"utpg2i2xswor6h8ttjhu3d47z53yy47y\"}"
|
||||
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y"
|
||||
@get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}'
|
||||
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
||||
end
|
||||
|
||||
it "returns a token from vmpooler" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @get_token_response, :headers => {})
|
||||
it 'returns a token from vmpooler' do
|
||||
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' })
|
||||
.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
|
||||
end
|
||||
|
||||
it "raises a token error if something goes wrong" do
|
||||
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'}).
|
||||
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {})
|
||||
it 'raises a token error if something goes wrong' do
|
||||
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' })
|
||||
.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
|
||||
|
||||
describe "#delete_token" do
|
||||
describe '#delete_token' do
|
||||
before :each do
|
||||
@delete_token_response = "{\"ok\":true}"
|
||||
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y"
|
||||
@delete_token_response = '{"ok":true}'
|
||||
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
||||
end
|
||||
|
||||
it "deletes the specified token" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @delete_token_response, :headers => {})
|
||||
it 'deletes the specified token' do
|
||||
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' })
|
||||
.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
|
||||
|
||||
it "raises a token error if something goes wrong" do
|
||||
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'}).
|
||||
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {})
|
||||
it 'raises a token error if something goes wrong' do
|
||||
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' })
|
||||
.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
|
||||
|
||||
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)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#token_status" do
|
||||
describe '#token_status' do
|
||||
before :each do
|
||||
@token_status_response = "{\"ok\":true,\"utpg2i2xswor6h8ttjhu3d47z53yy47y\":{\"created\":\"2015-04-28 19:17:47 -0700\"}}"
|
||||
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y"
|
||||
@token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}'
|
||||
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
||||
end
|
||||
|
||||
it "checks the status of a token" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @token_status_response, :headers => {})
|
||||
it 'checks the status of a token' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @token_status_response, :headers => {})
|
||||
|
||||
expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response)
|
||||
end
|
||||
|
||||
it "raises a token error if something goes wrong" do
|
||||
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'}).
|
||||
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {})
|
||||
it 'raises a token error if something goes wrong' do
|
||||
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' })
|
||||
.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
|
||||
|
||||
it "raises a token error if no token provided" do
|
||||
expect{ Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError)
|
||||
it 'raises a token error if no token provided' do
|
||||
expect { Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'vmfloaty/utils'
|
||||
require 'vmfloaty/errors'
|
||||
|
|
@ -7,47 +9,46 @@ describe NonstandardPooler do
|
|||
before :each do
|
||||
@nspooler_url = 'https://nspooler.example.com'
|
||||
@post_request_headers = {
|
||||
'Accept' => '*/*',
|
||||
'Accept' => '*/*',
|
||||
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
|
||||
'User-Agent' => 'Faraday v0.9.2',
|
||||
'X-Auth-Token' => 'token-value'
|
||||
'User-Agent' => 'Faraday v0.9.2',
|
||||
'X-Auth-Token' => 'token-value',
|
||||
}
|
||||
@get_request_headers = {
|
||||
'Accept' => '*/*',
|
||||
'Accept' => '*/*',
|
||||
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
|
||||
'User-Agent' => 'Faraday v0.9.2',
|
||||
'X-Auth-Token' => 'token-value'
|
||||
'User-Agent' => 'Faraday v0.9.2',
|
||||
'X-Auth-Token' => 'token-value',
|
||||
}
|
||||
@get_request_headers_notoken = @get_request_headers.tap do |headers|
|
||||
headers.delete('X-Auth-Token')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#list' do
|
||||
before :each do
|
||||
@status_response_body = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-10-sparc": {
|
||||
"total_hosts": 11,
|
||||
"available_hosts": 11
|
||||
},
|
||||
"ubuntu-16.04-power8": {
|
||||
"total_hosts": 10,
|
||||
"available_hosts": 10
|
||||
},
|
||||
"aix-7.2-power": {
|
||||
"total_hosts": 5,
|
||||
"available_hosts": 4
|
||||
}
|
||||
}
|
||||
@status_response_body = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-10-sparc": {
|
||||
"total_hosts": 11,
|
||||
"available_hosts": 11
|
||||
},
|
||||
"ubuntu-16.04-power8": {
|
||||
"total_hosts": 10,
|
||||
"available_hosts": 10
|
||||
},
|
||||
"aix-7.2-power": {
|
||||
"total_hosts": 5,
|
||||
"available_hosts": 4
|
||||
}
|
||||
}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'returns an array with operating systems from the pooler' do
|
||||
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)
|
||||
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
|
||||
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')
|
||||
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
|
||||
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')
|
||||
expect(list).to be_an_instance_of Array
|
||||
|
|
@ -74,24 +75,24 @@ describe NonstandardPooler do
|
|||
|
||||
describe '#list_active' do
|
||||
before :each do
|
||||
@token_status_body_active = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"user": "first.last",
|
||||
"created": "2017-09-18 01:25:41 +0000",
|
||||
"last_accessed": "2017-09-21 19:46:25 +0000",
|
||||
"reserved_hosts": ["sol10-9", "sol10-11"]
|
||||
}
|
||||
BODY
|
||||
@token_status_body_empty = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"user": "first.last",
|
||||
"created": "2017-09-18 01:25:41 +0000",
|
||||
"last_accessed": "2017-09-21 19:46:25 +0000",
|
||||
"reserved_hosts": []
|
||||
}
|
||||
BODY
|
||||
@token_status_body_active = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"user": "first.last",
|
||||
"created": "2017-09-18 01:25:41 +0000",
|
||||
"last_accessed": "2017-09-21 19:46:25 +0000",
|
||||
"reserved_hosts": ["sol10-9", "sol10-11"]
|
||||
}
|
||||
BODY
|
||||
@token_status_body_empty = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"user": "first.last",
|
||||
"created": "2017-09-18 01:25:41 +0000",
|
||||
"last_accessed": "2017-09-21 19:46:25 +0000",
|
||||
"reserved_hosts": []
|
||||
}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'prints an output of fqdn, template, and duration' do
|
||||
|
|
@ -106,34 +107,34 @@ BODY
|
|||
|
||||
describe '#retrieve' do
|
||||
before :each do
|
||||
@retrieve_response_body_single = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-11-sparc": {
|
||||
"hostname": "sol11-4.delivery.puppetlabs.net"
|
||||
}
|
||||
}
|
||||
BODY
|
||||
@retrieve_response_body_many = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-10-sparc": {
|
||||
"hostname": [
|
||||
"sol10-9.delivery.puppetlabs.net",
|
||||
"sol10-10.delivery.puppetlabs.net"
|
||||
]
|
||||
},
|
||||
"aix-7.1-power": {
|
||||
"hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net"
|
||||
}
|
||||
}
|
||||
BODY
|
||||
@retrieve_response_body_single = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-11-sparc": {
|
||||
"hostname": "sol11-4.delivery.puppetlabs.net"
|
||||
}
|
||||
}
|
||||
BODY
|
||||
@retrieve_response_body_many = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-10-sparc": {
|
||||
"hostname": [
|
||||
"sol10-9.delivery.puppetlabs.net",
|
||||
"sol10-10.delivery.puppetlabs.net"
|
||||
]
|
||||
},
|
||||
"aix-7.1-power": {
|
||||
"hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net"
|
||||
}
|
||||
}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'raises an AuthError if the token is invalid' do
|
||||
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
|
||||
.with(headers: @post_request_headers)
|
||||
.to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {})
|
||||
.with(:headers => @post_request_headers)
|
||||
.to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {})
|
||||
|
||||
vm_hash = { 'solaris-11-sparc' => 1 }
|
||||
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
|
||||
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
|
||||
.with(headers: @post_request_headers)
|
||||
.to_return(status: 200, body: @retrieve_response_body_single, headers: {})
|
||||
.with(:headers => @post_request_headers)
|
||||
.to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
|
||||
|
||||
vm_hash = { 'solaris-11-sparc' => 1 }
|
||||
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
|
||||
|
|
@ -152,9 +153,9 @@ BODY
|
|||
end
|
||||
|
||||
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")
|
||||
.with(headers: @post_request_headers)
|
||||
.to_return(status: 200, body: @retrieve_response_body_many, headers: {})
|
||||
stub_request(:post, "#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc")
|
||||
.with(:headers => @post_request_headers)
|
||||
.to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {})
|
||||
|
||||
vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 }
|
||||
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
|
||||
|
|
@ -172,23 +173,23 @@ BODY
|
|||
end
|
||||
|
||||
it 'raises an error if the user tries to modify an unsupported attribute' do
|
||||
stub_request(:put, "https://nspooler.example.com/host/myfakehost").
|
||||
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'}).
|
||||
to_return(status: 200, body: "", headers: {})
|
||||
details = { lifetime: 12 }
|
||||
stub_request(:put, 'https://nspooler.example.com/host/myfakehost')
|
||||
.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' })
|
||||
.to_return(:status => 200, :body => '', :headers => {})
|
||||
details = { :lifetime => 12 }
|
||||
expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) }
|
||||
.to raise_error(ModifyError)
|
||||
.to raise_error(ModifyError)
|
||||
end
|
||||
|
||||
it 'modifies the reason of a vm' do
|
||||
modify_request_body = { '{"reserved_for_reason":"testing"}' => true }
|
||||
stub_request(:put, "#{@nspooler_url}/host/myfakehost")
|
||||
.with(body: modify_request_body,
|
||||
headers: @post_request_headers)
|
||||
.to_return(status: 200, body: '{"ok": true}', headers: {})
|
||||
.with(:body => modify_request_body,
|
||||
:headers => @post_request_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)
|
||||
expect(modify_req['ok']).to be true
|
||||
end
|
||||
|
|
@ -198,29 +199,29 @@ BODY
|
|||
before :each do
|
||||
@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'
|
||||
@status_response_body = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-10-sparc": {
|
||||
"total_hosts": 11,
|
||||
"available_hosts": 10
|
||||
},
|
||||
"ubuntu-16.04-power8": {
|
||||
"total_hosts": 10,
|
||||
"available_hosts": 10
|
||||
},
|
||||
"aix-7.2-power": {
|
||||
"total_hosts": 5,
|
||||
"available_hosts": 4
|
||||
}
|
||||
}
|
||||
BODY
|
||||
@status_response_body = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"solaris-10-sparc": {
|
||||
"total_hosts": 11,
|
||||
"available_hosts": 10
|
||||
},
|
||||
"ubuntu-16.04-power8": {
|
||||
"total_hosts": 10,
|
||||
"available_hosts": 10
|
||||
},
|
||||
"aix-7.2-power": {
|
||||
"total_hosts": 5,
|
||||
"available_hosts": 4
|
||||
}
|
||||
}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'prints the status' do
|
||||
stub_request(:get, "#{@nspooler_url}/status")
|
||||
.with(headers: @get_request_headers)
|
||||
.to_return(status: 200, body: @status_response_body, headers: {})
|
||||
.with(:headers => @get_request_headers)
|
||||
.to_return(:status => 200, :body => @status_response_body, :headers => {})
|
||||
|
||||
status = NonstandardPooler.status(false, @nspooler_url)
|
||||
expect(status).to be_an_instance_of Hash
|
||||
|
|
@ -229,22 +230,22 @@ BODY
|
|||
|
||||
describe '#summary' do
|
||||
before :each do
|
||||
@status_response_body = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"total": 57,
|
||||
"available": 39,
|
||||
"in_use": 16,
|
||||
"resetting": 2,
|
||||
"broken": 0
|
||||
}
|
||||
BODY
|
||||
@status_response_body = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"total": 57,
|
||||
"available": 39,
|
||||
"in_use": 16,
|
||||
"resetting": 2,
|
||||
"broken": 0
|
||||
}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'prints the summary' do
|
||||
stub_request(:get, "#{@nspooler_url}/summary")
|
||||
.with(headers: @get_request_headers)
|
||||
.to_return(status: 200, body: @status_response_body, headers: {})
|
||||
.with(:headers => @get_request_headers)
|
||||
.to_return(:status => 200, :body => @status_response_body, :headers => {})
|
||||
|
||||
summary = NonstandardPooler.summary(false, @nspooler_url)
|
||||
expect(summary).to be_an_instance_of Hash
|
||||
|
|
@ -253,24 +254,24 @@ BODY
|
|||
|
||||
describe '#query' do
|
||||
before :each do
|
||||
@query_response_body = <<-BODY
|
||||
{
|
||||
"ok": true,
|
||||
"sol10-11": {
|
||||
"fqdn": "sol10-11.delivery.puppetlabs.net",
|
||||
"os_triple": "solaris-10-sparc",
|
||||
"reserved_by_user": "first.last",
|
||||
"reserved_for_reason": "testing",
|
||||
"hours_left_on_reservation": 29.12
|
||||
}
|
||||
}
|
||||
BODY
|
||||
@query_response_body = <<~BODY
|
||||
{
|
||||
"ok": true,
|
||||
"sol10-11": {
|
||||
"fqdn": "sol10-11.delivery.puppetlabs.net",
|
||||
"os_triple": "solaris-10-sparc",
|
||||
"reserved_by_user": "first.last",
|
||||
"reserved_for_reason": "testing",
|
||||
"hours_left_on_reservation": 29.12
|
||||
}
|
||||
}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'makes a query about a vm' do
|
||||
stub_request(:get, "#{@nspooler_url}/host/sol10-11")
|
||||
.with(headers: @get_request_headers_notoken)
|
||||
.to_return(status: 200, body: @query_response_body, headers: {})
|
||||
.with(:headers => @get_request_headers_notoken)
|
||||
.to_return(:status => 200, :body => @query_response_body, :headers => {})
|
||||
|
||||
query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11')
|
||||
expect(query_req).to be_an_instance_of Hash
|
||||
|
|
@ -285,8 +286,8 @@ BODY
|
|||
|
||||
it 'deletes a single existing vm' do
|
||||
stub_request(:delete, "#{@nspooler_url}/host/sol11-7")
|
||||
.with(headers: @post_request_headers)
|
||||
.to_return(status: 200, body: @delete_response_success, headers: {})
|
||||
.with(:headers => @post_request_headers)
|
||||
.to_return(:status => 200, :body => @delete_response_success, :headers => {})
|
||||
|
||||
request = NonstandardPooler.delete(false, @nspooler_url, 'sol11-7', 'token-value')
|
||||
expect(request['sol11-7']['ok']).to be true
|
||||
|
|
@ -294,8 +295,8 @@ BODY
|
|||
|
||||
it 'does not delete a nonexistant vm' do
|
||||
stub_request(:delete, "#{@nspooler_url}/host/fakehost")
|
||||
.with(headers: @post_request_headers)
|
||||
.to_return(status: 401, body: @delete_response_failure, headers: {})
|
||||
.with(:headers => @post_request_headers)
|
||||
.to_return(:status => 401, :body => @delete_response_failure, :headers => {})
|
||||
|
||||
request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value')
|
||||
expect(request['fakehost']['ok']).to be false
|
||||
|
|
|
|||
|
|
@ -1,224 +1,226 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_relative '../../lib/vmfloaty/pooler'
|
||||
|
||||
describe Pooler do
|
||||
before :each do
|
||||
@vmpooler_url = "https://vmpooler.example.com"
|
||||
@vmpooler_url = 'https://vmpooler.example.com'
|
||||
end
|
||||
|
||||
describe "#list" do
|
||||
describe '#list' 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
|
||||
|
||||
it "returns a hash with operating systems from the pooler" do
|
||||
stub_request(:get, "#{@vmpooler_url}/vm").
|
||||
to_return(:status => 200, :body => @list_response_body, :headers => {})
|
||||
it 'returns a hash with operating systems from the pooler' do
|
||||
stub_request(:get, "#{@vmpooler_url}/vm")
|
||||
.to_return(:status => 200, :body => @list_response_body, :headers => {})
|
||||
|
||||
list = Pooler.list(false, @vmpooler_url, nil)
|
||||
expect(list).to be_an_instance_of Array
|
||||
end
|
||||
|
||||
it "filters operating systems based on the filter param" do
|
||||
stub_request(:get, "#{@vmpooler_url}/vm").
|
||||
to_return(:status => 200, :body => @list_response_body, :headers => {})
|
||||
it 'filters operating systems based on the filter param' do
|
||||
stub_request(:get, "#{@vmpooler_url}/vm")
|
||||
.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.size).to equal 2
|
||||
end
|
||||
|
||||
it "returns nothing if the filter does not match" do
|
||||
stub_request(:get, "#{@vmpooler_url}/vm").
|
||||
to_return(:status => 200, :body => @list_response_body, :headers => {})
|
||||
it 'returns nothing if the filter does not match' do
|
||||
stub_request(:get, "#{@vmpooler_url}/vm")
|
||||
.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.size).to equal 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "#retrieve" do
|
||||
describe '#retrieve' do
|
||||
before :each do
|
||||
@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_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"}}'
|
||||
end
|
||||
|
||||
it "raises an AuthError if the token is invalid" do
|
||||
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'}).
|
||||
to_return(:status => 401, :body => "{\"ok\":false}", :headers => {})
|
||||
it 'raises an AuthError if the token is invalid' do
|
||||
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' })
|
||||
.to_return(:status => 401, :body => '{"ok":false}', :headers => {})
|
||||
|
||||
vm_hash = {}
|
||||
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
|
||||
|
||||
it "retrieves a single vm with a token" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
|
||||
it 'retrieves a single vm with a token' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
|
||||
|
||||
vm_hash = {}
|
||||
vm_hash['debian-7-i386'] = 1
|
||||
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url)
|
||||
expect(vm_req).to be_an_instance_of Hash
|
||||
expect(vm_req["ok"]).to equal true
|
||||
expect(vm_req["debian-7-i386"]["hostname"]).to eq "fq6qlpjlsskycq6"
|
||||
expect(vm_req['ok']).to equal true
|
||||
expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6'
|
||||
end
|
||||
|
||||
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").
|
||||
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 => {})
|
||||
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")
|
||||
.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 => {})
|
||||
|
||||
vm_hash = {}
|
||||
vm_hash['debian-7-i386'] = 2
|
||||
vm_hash['centos-7-x86_64'] = 1
|
||||
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url)
|
||||
expect(vm_req).to be_an_instance_of Hash
|
||||
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 eq ["sc0o4xqtodlul5w", "4m4dkhqiufnjmxy"]
|
||||
expect(vm_req["centos-7-x86_64"]["hostname"]).to eq "zb91y9qbrbf6d3q"
|
||||
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 eq %w[sc0o4xqtodlul5w 4m4dkhqiufnjmxy]
|
||||
expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q'
|
||||
end
|
||||
end
|
||||
|
||||
describe "#modify" do
|
||||
describe '#modify' do
|
||||
before :each do
|
||||
@modify_response_body_success = "{\"ok\":true}"
|
||||
@modify_response_body_fail = "{\"ok\":false}"
|
||||
@modify_response_body_success = '{"ok":true}'
|
||||
@modify_response_body_fail = '{"ok":false}'
|
||||
end
|
||||
|
||||
it "raises a TokenError if token provided is nil" do
|
||||
expect{ Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError)
|
||||
it 'raises a TokenError if token provided is nil' do
|
||||
expect { Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError)
|
||||
end
|
||||
|
||||
it "modifies the TTL of a vm" do
|
||||
it 'modifies the TTL of a vm' do
|
||||
modify_hash = { :lifetime => 12 }
|
||||
stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6").
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @modify_response_body_success, :headers => {})
|
||||
stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6")
|
||||
.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' })
|
||||
.to_return(:status => 200, :body => @modify_response_body_success, :headers => {})
|
||||
|
||||
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
|
||||
|
||||
describe "#delete" do
|
||||
describe '#delete' do
|
||||
before :each do
|
||||
@delete_response_body_success = "{\"ok\":true}"
|
||||
@delete_response = {"fq6qlpjlsskycq6"=>{"ok"=>true}}
|
||||
@delete_response_body_success = '{"ok":true}'
|
||||
@delete_response = { 'fq6qlpjlsskycq6' => { 'ok' => true } }
|
||||
end
|
||||
|
||||
it "deletes a specified vm" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @delete_response_body_success, :headers => {})
|
||||
it 'deletes a specified vm' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @delete_response_body_success, :headers => {})
|
||||
|
||||
expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response
|
||||
end
|
||||
|
||||
it "raises a token error if no token provided" do
|
||||
expect{ Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil) }.to raise_error(TokenError)
|
||||
it 'raises a token error if no token provided' do
|
||||
expect { Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil) }.to raise_error(TokenError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#status" do
|
||||
describe '#status' do
|
||||
before :each do
|
||||
#smaller version
|
||||
@status_response_body = "{\"capacity\":{\"current\":716,\"total\":717,\"percent\": 99.9},\"status\":{\"ok\":true,\"message\":\"Battle station fully armed and operational.\"}}"
|
||||
# smaller version
|
||||
@status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}'
|
||||
end
|
||||
|
||||
it "prints the status" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @status_response_body, :headers => {})
|
||||
it 'prints the status' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @status_response_body, :headers => {})
|
||||
|
||||
status = Pooler.status(false, @vmpooler_url)
|
||||
expect(status).to be_an_instance_of Hash
|
||||
end
|
||||
end
|
||||
|
||||
describe "#summary" do
|
||||
describe '#summary' do
|
||||
before :each do
|
||||
@status_response_body = ""
|
||||
@status_response_body = ''
|
||||
|
||||
it "prints the summary" do
|
||||
it 'prints the summary' do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#query" do
|
||||
describe '#query' 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
|
||||
|
||||
it "makes a query about a vm" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @query_response_body, :headers => {})
|
||||
it 'makes a query about a vm' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @query_response_body, :headers => {})
|
||||
|
||||
query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6')
|
||||
expect(query_req).to be_an_instance_of Hash
|
||||
end
|
||||
end
|
||||
|
||||
describe "#snapshot" do
|
||||
describe '#snapshot' do
|
||||
before :each do
|
||||
@snapshot_response_body = "{\"ok\":true}"
|
||||
@snapshot_response_body = '{"ok":true}'
|
||||
end
|
||||
|
||||
it "makes a snapshot for a single vm" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @snapshot_response_body, :headers => {})
|
||||
it 'makes a snapshot for a single vm' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @snapshot_response_body, :headers => {})
|
||||
|
||||
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
|
||||
|
||||
describe "#revert" do
|
||||
describe '#revert' do
|
||||
before :each do
|
||||
@revert_response_body = "{\"ok\":true}"
|
||||
@revert_response_body = '{"ok":true}'
|
||||
end
|
||||
|
||||
it "makes a request to revert a vm from a snapshot" do
|
||||
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'}).
|
||||
to_return(:status => 200, :body => @revert_response_body, :headers => {})
|
||||
it 'makes a request to revert a vm from a snapshot' do
|
||||
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' })
|
||||
.to_return(:status => 200, :body => @revert_response_body, :headers => {})
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
it "raises a TokenError if no token was provided" do
|
||||
expect{ Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError)
|
||||
it 'raises a TokenError if no token was provided' do
|
||||
expect { Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#disk" do
|
||||
describe '#disk' do
|
||||
before :each do
|
||||
@disk_response_body_success = "{\"ok\":true}"
|
||||
@disk_response_body_fail = "{\"ok\":false}"
|
||||
@disk_response_body_success = '{"ok":true}'
|
||||
@disk_response_body_fail = '{"ok":false}'
|
||||
end
|
||||
|
||||
it "makes a request to extend disk space of a vm" do
|
||||
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 => {})
|
||||
it 'makes a request to extend disk space of a vm' do
|
||||
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 => {})
|
||||
|
||||
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
|
||||
|
||||
it "raises a TokenError if no token was provided" do
|
||||
expect{ Pooler.disk(false, @vmpooler_url, 'myfakehost', nil, 12) }.to raise_error(TokenError)
|
||||
it 'raises a TokenError if no token was provided' do
|
||||
expect { Pooler.disk(false, @vmpooler_url, 'myfakehost', nil, 12) }.to raise_error(TokenError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/vmfloaty/service'
|
||||
|
||||
describe Service do
|
||||
|
||||
describe '#initialize' do
|
||||
it 'store configuration options' do
|
||||
options = MockOptions.new({})
|
||||
config = {'url' => 'http://example.url'}
|
||||
config = { 'url' => 'http://example.url' }
|
||||
service = Service.new(options, config)
|
||||
expect(service.config).to include config
|
||||
end
|
||||
|
|
@ -43,31 +44,31 @@ describe Service do
|
|||
|
||||
describe '#delete_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)
|
||||
.with('Enter your pooler service password:', '*')
|
||||
.and_return('hunter2'))
|
||||
allow(Auth).to(receive(:delete_token)
|
||||
.with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value')
|
||||
.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
|
||||
|
||||
describe '#token_status' do
|
||||
it 'reports the status of a token' do
|
||||
config = {
|
||||
'user' => 'first.last',
|
||||
'url' => 'http://default.url'
|
||||
'user' => 'first.last',
|
||||
'url' => 'http://default.url',
|
||||
}
|
||||
options = MockOptions.new('token' => 'token-value')
|
||||
service = Service.new(options, config)
|
||||
status = {
|
||||
'ok' => true,
|
||||
'user' => config['user'],
|
||||
'created' => '2017-09-22 02:04:18 +0000',
|
||||
'last_accessed' => '2017-09-22 02:04:28 +0000',
|
||||
'reserved_hosts' => []
|
||||
'ok' => true,
|
||||
'user' => config['user'],
|
||||
'created' => '2017-09-22 02:04:18 +0000',
|
||||
'last_accessed' => '2017-09-22 02:04:28 +0000',
|
||||
'reserved_hosts' => [],
|
||||
}
|
||||
allow(Auth).to(receive(:token_status)
|
||||
.with(nil, config['url'], 'token-value')
|
||||
|
|
@ -75,5 +76,4 @@ describe Service do
|
|||
expect(service.token_status(nil, 'token-value')).to eql(status)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'json'
|
||||
require 'commander/command'
|
||||
require_relative '../../lib/vmfloaty/utils'
|
||||
|
||||
describe Utils do
|
||||
|
||||
describe "#standardize_hostnames" do
|
||||
describe '#standardize_hostnames' do
|
||||
before :each do
|
||||
@vmpooler_response_body ='{
|
||||
@vmpooler_response_body = '{
|
||||
"ok": true,
|
||||
"domain": "delivery.mycompany.net",
|
||||
"ubuntu-1610-x86_64": {
|
||||
|
|
@ -28,79 +29,79 @@ describe Utils do
|
|||
}'
|
||||
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))
|
||||
expect(result).to eq('centos-7-x86_64' => ["dlgietfmgeegry2.delivery.mycompany.net"],
|
||||
'ubuntu-1610-x86_64' => ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.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'])
|
||||
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))
|
||||
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'])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format_host_output" do
|
||||
describe '#format_host_output' do
|
||||
before :each do
|
||||
@vmpooler_results = {
|
||||
'centos-7-x86_64' => ["dlgietfmgeegry2.delivery.mycompany.net"],
|
||||
'ubuntu-1610-x86_64' => ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"]
|
||||
'centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'],
|
||||
'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net'],
|
||||
}
|
||||
@nonstandard_results = {
|
||||
'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'],
|
||||
'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.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'],
|
||||
}
|
||||
@vmpooler_output = <<-OUT.chomp
|
||||
- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64)
|
||||
- gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64)
|
||||
- ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64)
|
||||
@vmpooler_output = <<~OUT.chomp
|
||||
- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64)
|
||||
- gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64)
|
||||
- ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64)
|
||||
OUT
|
||||
@nonstandard_output = <<-OUT.chomp
|
||||
- sol10-10.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)
|
||||
@nonstandard_output = <<~OUT.chomp
|
||||
- sol10-10.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)
|
||||
OUT
|
||||
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)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#get_service_object" do
|
||||
it "assumes vmpooler by default" do
|
||||
describe '#get_service_object' do
|
||||
it 'assumes vmpooler by default' do
|
||||
expect(Utils.get_service_object).to be Pooler
|
||||
end
|
||||
|
||||
it "uses nspooler when told explicitly" do
|
||||
expect(Utils.get_service_object "nspooler").to be NonstandardPooler
|
||||
it 'uses nspooler when told explicitly' do
|
||||
expect(Utils.get_service_object('nspooler')).to be NonstandardPooler
|
||||
end
|
||||
end
|
||||
|
||||
describe "#get_service_config" do
|
||||
describe '#get_service_config' do
|
||||
before :each do
|
||||
@default_config = {
|
||||
"url" => "http://default.url",
|
||||
"user" => "first.last.default",
|
||||
"token" => "default-token",
|
||||
'url' => 'http://default.url',
|
||||
'user' => 'first.last.default',
|
||||
'token' => 'default-token',
|
||||
}
|
||||
@services_config = {
|
||||
"services" => {
|
||||
"vm" => {
|
||||
"url" => "http://vmpooler.url",
|
||||
"user" => "first.last.vmpooler",
|
||||
"token" => "vmpooler-token"
|
||||
},
|
||||
"ns" => {
|
||||
"url" => "http://nspooler.url",
|
||||
"user" => "first.last.nspooler",
|
||||
"token" => "nspooler-token"
|
||||
}
|
||||
}
|
||||
'services' => {
|
||||
'vm' => {
|
||||
'url' => 'http://vmpooler.url',
|
||||
'user' => 'first.last.vmpooler',
|
||||
'token' => 'vmpooler-token',
|
||||
},
|
||||
'ns' => {
|
||||
'url' => 'http://nspooler.url',
|
||||
'user' => 'first.last.nspooler',
|
||||
'token' => 'nspooler-token',
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -110,70 +111,70 @@ describe Utils do
|
|||
expect(Utils.get_service_config(config, options)).to include @services_config['services']['vm']
|
||||
end
|
||||
|
||||
it "allows selection by configured service key" do
|
||||
it 'allows selection by configured service key' do
|
||||
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']
|
||||
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["services"]['vm'].delete 'url'
|
||||
options = MockOptions.new({:service => "vm"})
|
||||
config['services']['vm'].delete 'url'
|
||||
options = MockOptions.new(:service => 'vm')
|
||||
expect(Utils.get_service_config(config, options)['url']).to eq 'http://default.url'
|
||||
end
|
||||
|
||||
it "raises an error if passed a service name that hasn't been configured" do
|
||||
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
|
||||
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
|
||||
options = MockOptions.new({:url => "http://alternate.url", :token => "alternate-token"})
|
||||
expected = config.merge({"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')
|
||||
expect(Utils.get_service_config(config, options)).to include expected
|
||||
end
|
||||
end
|
||||
|
||||
describe "#generate_os_hash" do
|
||||
describe '#generate_os_hash' do
|
||||
before :each do
|
||||
@host_hash = {"centos"=>1, "debian"=>5, "windows"=>1}
|
||||
@host_hash = { 'centos' => 1, 'debian' => 5, 'windows' => 1 }
|
||||
end
|
||||
|
||||
it "takes an array of os arguments and returns a formatted hash" do
|
||||
host_arg = ["centos", "debian=5", "windows=1"]
|
||||
it 'takes an array of os arguments and returns a formatted hash' do
|
||||
host_arg = ['centos', 'debian=5', 'windows=1']
|
||||
expect(Utils.generate_os_hash(host_arg)).to eq @host_hash
|
||||
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 = []
|
||||
expect(Utils.generate_os_hash(host_arg)).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pretty_print_hosts' do
|
||||
let(:url) { 'http://pooler.example.com' }
|
||||
let(:url) { 'http://pooler.example.com' }
|
||||
|
||||
it 'prints a vmpooler output with host fqdn, template and duration info' do
|
||||
hostname = 'mcpy42eqjxli9g2'
|
||||
response_body = { hostname => {
|
||||
'template' => 'ubuntu-1604-x86_64',
|
||||
'lifetime' => 12,
|
||||
'running' => 9.66,
|
||||
'state' => 'running',
|
||||
'ip' => '127.0.0.1',
|
||||
'domain' => 'delivery.mycompany.net'
|
||||
}}
|
||||
output = "- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)"
|
||||
'template' => 'ubuntu-1604-x86_64',
|
||||
'lifetime' => 12,
|
||||
'running' => 9.66,
|
||||
'state' => 'running',
|
||||
'ip' => '127.0.0.1',
|
||||
'domain' => 'delivery.mycompany.net',
|
||||
} }
|
||||
output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)'
|
||||
|
||||
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)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
|
||||
Utils.pretty_print_hosts(nil, service, hostname)
|
||||
end
|
||||
|
|
@ -181,46 +182,46 @@ describe Utils do
|
|||
it 'prints a vmpooler output with host fqdn, template, duration info, and tags when supplied' do
|
||||
hostname = 'aiydvzpg23r415q'
|
||||
response_body = { hostname => {
|
||||
'template' => 'redhat-7-x86_64',
|
||||
'lifetime' => 48,
|
||||
'running' => 7.67,
|
||||
'state' => 'running',
|
||||
'tags' => {
|
||||
'user' => 'bob',
|
||||
'role' => 'agent'
|
||||
},
|
||||
'ip' => '127.0.0.1',
|
||||
'domain' => 'delivery.mycompany.net'
|
||||
}}
|
||||
output = "- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)"
|
||||
'template' => 'redhat-7-x86_64',
|
||||
'lifetime' => 48,
|
||||
'running' => 7.67,
|
||||
'state' => 'running',
|
||||
'tags' => {
|
||||
'user' => 'bob',
|
||||
'role' => 'agent',
|
||||
},
|
||||
'ip' => '127.0.0.1',
|
||||
'domain' => 'delivery.mycompany.net',
|
||||
} }
|
||||
output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)'
|
||||
|
||||
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)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
|
||||
Utils.pretty_print_hosts(nil, service, hostname)
|
||||
end
|
||||
|
||||
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 => {
|
||||
'fqdn' => hostname,
|
||||
'os_triple' => 'solaris-11-sparc',
|
||||
'reserved_by_user' => 'first.last',
|
||||
'reserved_for_reason' => '',
|
||||
'hours_left_on_reservation' => 35.89
|
||||
}}
|
||||
output = "- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)"
|
||||
'fqdn' => hostname,
|
||||
'os_triple' => 'solaris-11-sparc',
|
||||
'reserved_by_user' => 'first.last',
|
||||
'reserved_for_reason' => '',
|
||||
'hours_left_on_reservation' => 35.89,
|
||||
} }
|
||||
output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)'
|
||||
|
||||
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)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
|
||||
Utils.pretty_print_hosts(nil, service, hostname)
|
||||
end
|
||||
|
|
@ -228,20 +229,20 @@ describe Utils do
|
|||
it 'prints a nonstandard pooler output with host, template, time remaining, and reason' do
|
||||
hostname = 'sol11-9.delivery.mycompany.net'
|
||||
response_body = { hostname => {
|
||||
'fqdn' => hostname,
|
||||
'os_triple' => 'solaris-11-sparc',
|
||||
'reserved_by_user' => 'first.last',
|
||||
'reserved_for_reason' => 'testing',
|
||||
'hours_left_on_reservation' => 35.89
|
||||
}}
|
||||
output = "- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)"
|
||||
'fqdn' => hostname,
|
||||
'os_triple' => 'solaris-11-sparc',
|
||||
'reserved_by_user' => 'first.last',
|
||||
'reserved_for_reason' => 'testing',
|
||||
'hours_left_on_reservation' => 35.89,
|
||||
} }
|
||||
output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)'
|
||||
|
||||
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)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
.with(nil, hostname)
|
||||
.and_return(response_body)
|
||||
|
||||
Utils.pretty_print_hosts(nil, service, hostname)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
|
|
@ -16,7 +18,7 @@ Gem::Specification.new do |s|
|
|||
s.test_files = Dir['spec/**/*']
|
||||
s.require_path = 'lib'
|
||||
|
||||
s.add_dependency 'colorize', '~> 0.8.1'
|
||||
s.add_dependency 'commander', '~> 4.4.3'
|
||||
s.add_dependency 'faraday', '~> 0.9.0'
|
||||
s.add_dependency 'colorize', '~> 0.8.1'
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue