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