diff --git a/Gemfile b/Gemfile index ef85ae0..042d6db 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ source 'https://rubygems.org' gemspec -gem 'rake', :require => false +gem 'rake', require: false group :test do gem 'coveralls', '~> 0.8.23' diff --git a/Rakefile b/Rakefile index bde93cf..cdd6c8f 100644 --- a/Rakefile +++ b/Rakefile @@ -28,4 +28,4 @@ RuboCop::RakeTask.new(:rubocop) do |task| end # Default task is to run the unit tests -task :default => :spec +task default: :spec diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 0e1bad5..d7e2196 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -20,7 +20,8 @@ class Vmfloaty def run # rubocop:disable Metrics/AbcSize program :version, Vmfloaty::VERSION - program :description, "A CLI helper tool for Puppet's vmpooler to help you stay afloat.\n\nConfiguration may be placed in a ~/.vmfloaty.yml file." + program :description, + "A CLI helper tool for Puppet's vmpooler to help you stay afloat.\n\nConfiguration may be placed in a ~/.vmfloaty.yml file." config = Conf.read_config @@ -43,9 +44,7 @@ class Vmfloaty c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)' c.action do |args, options| verbose = options.verbose || config['verbose'] - if options.loglevel - FloatyLogger.setlevel = options.loglevel - end + FloatyLogger.setlevel = options.loglevel if options.loglevel service = Service.new(options, config) use_token = !options.notoken force = options.force @@ -100,21 +99,19 @@ class Vmfloaty c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)' c.action do |args, options| verbose = options.verbose || config['verbose'] - if options.loglevel - FloatyLogger.setlevel = options.loglevel - end + FloatyLogger.setlevel = options.loglevel if options.loglevel service = Service.new(options, config) filter = args[0] if options.active # list active vms - if service.type == "ABS" - # this is actually job_ids - running_vms = service.list_active_job_ids(verbose, service.url, service.user) - else - running_vms = service.list_active(verbose) - end + running_vms = if service.type == 'ABS' + # this is actually job_ids + service.list_active_job_ids(verbose, service.url, service.user) + else + service.list_active(verbose) + end host = URI.parse(service.url).host if running_vms.empty? if options.json @@ -122,17 +119,15 @@ class Vmfloaty else FloatyLogger.info "You have no running VMs on #{host}" end - else - if options.json - puts Utils.get_host_data(verbose, service, running_vms).to_json - elsif options.hostnameonly - Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data| - Utils.print_fqdn_for_host(service, hostname, host_data) - end - else - puts "Your VMs on #{host}:" - Utils.pretty_print_hosts(verbose, service, running_vms) + elsif options.json + puts Utils.get_host_data(verbose, service, running_vms).to_json + elsif options.hostnameonly + Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data| + Utils.print_fqdn_for_host(service, hostname, host_data) end + else + puts "Your VMs on #{host}:" + Utils.pretty_print_hosts(verbose, service, running_vms) end else # list available vms from pooler @@ -164,7 +159,8 @@ class Vmfloaty c.syntax = 'floaty modify hostname [options]' c.summary = 'Modify a VM\'s tags, time to live, disk space, or reservation reason' c.description = 'This command makes modifications to the virtual machines state in the pooler service. You can either append tags to the vm, increase how long it stays active for, or increase the amount of disk space.' - c.example 'Modifies myhost1 to have a TTL of 12 hours and adds a custom tag', 'floaty modify myhost1 --lifetime 12 --url https://myurl --token mytokenstring --tags \'{"tag":"myvalue"}\'' + c.example 'Modifies myhost1 to have a TTL of 12 hours and adds a custom tag', + 'floaty modify myhost1 --lifetime 12 --url https://myurl --token mytokenstring --tags \'{"tag":"myvalue"}\'' c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' @@ -185,18 +181,18 @@ class Vmfloaty exit 1 end running_vms = - if modify_all - service.list_active(verbose) - else - hostname.split(',') - end + if modify_all + service.list_active(verbose) + else + hostname.split(',') + end tags = options.tags ? JSON.parse(options.tags) : nil modify_hash = { - :lifetime => options.lifetime, - :disk => options.disk, - :tags => tags, - :reason => options.reason, + lifetime: options.lifetime, + disk: options.disk, + tags: tags, + reason: options.reason } modify_hash.delete_if { |_, value| value.nil? } @@ -204,12 +200,10 @@ class Vmfloaty ok = true modified_hash = {} running_vms.each do |vm| - begin - modified_hash[vm] = service.modify(verbose, vm, modify_hash) - rescue ModifyError => e - FloatyLogger.error e - ok = false - end + modified_hash[vm] = service.modify(verbose, vm, modify_hash) + rescue ModifyError => e + FloatyLogger.error e + ok = false end if ok if modify_all @@ -241,9 +235,7 @@ class Vmfloaty c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)' c.action do |args, options| verbose = options.verbose || config['verbose'] - if options.loglevel - FloatyLogger.setlevel = options.loglevel - end + FloatyLogger.setlevel = options.loglevel if options.loglevel service = Service.new(options, config) hostnames = args[0] @@ -254,17 +246,17 @@ class Vmfloaty successes = [] if delete_all - if service.type == "ABS" - # this is actually job_ids - running_vms = service.list_active_job_ids(verbose, service.url, service.user) - else - running_vms = service.list_active(verbose) - end + running_vms = if service.type == 'ABS' + # this is actually job_ids + service.list_active_job_ids(verbose, service.url, service.user) + else + service.list_active(verbose) + end if running_vms.empty? if options.json puts {}.to_json else - FloatyLogger.info "You have no running VMs." + FloatyLogger.info 'You have no running VMs.' end else confirmed = true @@ -328,7 +320,8 @@ class Vmfloaty c.syntax = 'floaty snapshot hostname [options]' c.summary = 'Takes a snapshot of a given vm' c.description = 'Will request a snapshot be taken of the given hostname in the pooler service. This command is known to take a while depending on how much load is on the pooler service.' - c.example 'Takes a snapshot for a given host', 'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl' + c.example 'Takes a snapshot for a given host', + 'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl' c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' @@ -354,7 +347,8 @@ class Vmfloaty c.syntax = 'floaty revert hostname snapshot [options]' c.summary = 'Reverts a vm to a specified snapshot' c.description = 'Given a snapshot SHA, vmfloaty will request a revert to the pooler service to go back to a previous snapshot.' - c.example 'Reverts to a snapshot for a given host', 'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl' + c.example 'Reverts to a snapshot for a given host', + 'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl' c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' @@ -366,7 +360,9 @@ class Vmfloaty hostname = args[0] snapshot_sha = args[1] || options.snapshot - FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot + if args[1] && options.snapshot + FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" + end begin revert_req = service.revert(verbose, hostname, snapshot_sha) @@ -391,9 +387,7 @@ class Vmfloaty c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)' c.action do |_, options| verbose = options.verbose || config['verbose'] - if options.loglevel - FloatyLogger.setlevel = options.loglevel - end + FloatyLogger.setlevel = options.loglevel if options.loglevel service = Service.new(options, config) if options.json pp service.status(verbose) @@ -527,7 +521,7 @@ class Vmfloaty c.example 'Print a list of the valid service types', 'floaty service types' c.example 'Print a sample config file with multiple services', 'floaty service examples' c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod' - c.action do |args, options| + c.action do |args, _options| action = args.first example_config = Utils.strip_heredoc(<<-CONFIG) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 08027b7..e6769e0 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -53,10 +53,10 @@ class ABS def self.list_active(verbose, url, _token, user) hosts = [] get_active_requests(verbose, url, user).each do |req_hash| - if req_hash.key?('allocated_resources') - req_hash['allocated_resources'].each do |onehost| - hosts.push(onehost['hostname']) - end + next unless req_hash.key?('allocated_resources') + + req_hash['allocated_resources'].each do |onehost| + hosts.push(onehost['hostname']) end end @@ -116,7 +116,7 @@ class ABS ret_status = {} hosts.each do |host| ret_status[host] = { - 'ok' => false, + 'ok' => false } end @@ -132,7 +132,7 @@ class ABS if hosts.include? vm_name['hostname'] if all_job_resources_accounted_for(req_hash['allocated_resources'], hosts) ret_status[vm_name['hostname']] = { - 'ok' => true, + 'ok' => true } jobs_to_delete.push(req_hash) else @@ -147,7 +147,7 @@ class ABS jobs_to_delete.each do |job| req_obj = { 'job_id' => job['request']['job']['id'], - 'hosts' => job['allocated_resources'], + 'hosts' => job['allocated_resources'] } FloatyLogger.info "Deleting #{req_obj}" if verbose @@ -172,11 +172,11 @@ class ABS res_body = JSON.parse(res.body) if res_body.key?('vmpooler_platforms') os_list << '*** VMPOOLER Pools ***' - if res_body['vmpooler_platforms'].is_a?(String) - os_list += JSON.parse(res_body['vmpooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 - else - os_list += res_body['vmpooler_platforms'] - end + os_list += if res_body['vmpooler_platforms'].is_a?(String) + JSON.parse(res_body['vmpooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + else + res_body['vmpooler_platforms'] + end end end @@ -200,11 +200,11 @@ class ABS if res_body.key?('nspooler_platforms') os_list << '' os_list << '*** NSPOOLER Pools ***' - if res_body['nspooler_platforms'].is_a?(String) - os_list += JSON.parse(res_body['nspooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 - else - os_list += res_body['nspooler_platforms'] - end + os_list += if res_body['nspooler_platforms'].is_a?(String) + JSON.parse(res_body['nspooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + else + res_body['nspooler_platforms'] + end end end @@ -214,11 +214,11 @@ class ABS if res_body.key?('aws_platforms') os_list << '' os_list << '*** AWS Pools ***' - if res_body['aws_platforms'].is_a?(String) - os_list += JSON.parse(res_body['aws_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 - else - os_list += res_body['aws_platforms'] - end + os_list += if res_body['aws_platforms'].is_a?(String) + JSON.parse(res_body['aws_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + else + res_body['aws_platforms'] + end end end @@ -248,20 +248,20 @@ class ABS conn = Http.get_conn(verbose, supported_abs_url(url)) conn.headers['X-AUTH-TOKEN'] = token if token - if continue.nil? - saved_job_id = user + "-" + DateTime.now.strftime('%Q') - else - saved_job_id = continue - end + saved_job_id = if continue.nil? + "#{user}-#{DateTime.now.strftime('%Q')}" + else + continue + end req_obj = { - :resources => os_types, - :job => { - :id => saved_job_id, - :tags => { - :user => user, - }, - }, + resources: os_types, + job: { + id: saved_job_id, + tags: { + user: user + } + } } if config['vmpooler_fallback'] # optional and not available as cli flag @@ -271,11 +271,12 @@ class ABS end if config['priority'] - req_obj[:priority] = if config['priority'] == 'high' + req_obj[:priority] = case config['priority'] + when 'high' 1 - elsif config['priority'] == 'medium' + when 'medium' 2 - elsif config['priority'] == 'low' + when 'low' 3 else config['priority'].to_i @@ -291,14 +292,12 @@ class ABS retries = 360 - status = validate_queue_status_response(res.status, res.body, "Initial request", verbose) + status = validate_queue_status_response(res.status, res.body, 'Initial request', verbose) begin (1..retries).each do |i| res_body = check_queue(conn, saved_job_id, req_obj, verbose) - if res_body && res_body.is_a?(Array) # when we get a response with hostnames - return translated(res_body, saved_job_id) - end + return translated(res_body, saved_job_id) if res_body.is_a?(Array) # when we get a response with hostnames sleep_seconds = 10 if i >= 10 sleep_seconds = i if i < 10 @@ -317,10 +316,10 @@ class ABS # We should fix the ABS API to be more like the vmpooler or nspooler api, but for now # def self.translated(res_body, job_id) - vmpooler_formatted_body = {'job_id' => job_id} + vmpooler_formatted_body = { 'job_id' => job_id } res_body.each do |host| - if vmpooler_formatted_body[host['type']] && vmpooler_formatted_body[host['type']]['hostname'].class == Array + if vmpooler_formatted_body[host['type']] && vmpooler_formatted_body[host['type']]['hostname'].instance_of?(Array) vmpooler_formatted_body[host['type']]['hostname'] << host['hostname'] else vmpooler_formatted_body[host['type']] = { 'hostname' => [host['hostname']] } @@ -331,9 +330,9 @@ class ABS vmpooler_formatted_body end - def self.check_queue(conn, job_id, req_obj, verbose) + def self.check_queue(conn, _job_id, req_obj, verbose) res = conn.post 'request', req_obj.to_json - status = validate_queue_status_response(res.status, res.body, "Check queue request", verbose) + status = validate_queue_status_response(res.status, res.body, 'Check queue request', verbose) unless res.body.empty? || !valid_json?(res.body) res_body = JSON.parse(res.body) return res_body @@ -353,7 +352,7 @@ class ABS res.body == 'OK' end - def self.summary(verbose, url) + def self.summary(_verbose, _url) raise NoMethodError, 'summary is not defined for ABS' end @@ -405,17 +404,17 @@ class ABS def self.valid_json?(json) JSON.parse(json) - return true + true rescue TypeError, JSON::ParserError => e - return false + false end # when missing, adds the required api/v2 in the url def self.supported_abs_url(url) - expected_ending = "api/v2" - if !url.include?(expected_ending) + expected_ending = 'api/v2' + unless url.include?(expected_ending) # add a slash if missing - expected_ending = "/#{expected_ending}" if url[-1] != "/" + expected_ending = "/#{expected_ending}" if url[-1] != '/' url = "#{url}#{expected_ending}" end url diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index b1984b8..c1f03f6 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -21,13 +21,11 @@ class Http url = "https://#{url}" unless url?(url) - conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday| + Faraday.new(url: url, ssl: { verify: false }) do |faraday| faraday.request :url_encoded faraday.response :logger if verbose faraday.adapter Faraday.default_adapter end - - conn end def self.get_conn_with_auth(verbose, url, user, password) @@ -37,13 +35,11 @@ class Http url = "https://#{url}" unless url?(url) - conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday| + Faraday.new(url: url, ssl: { verify: false }) do |faraday| faraday.request :url_encoded faraday.request :basic_auth, user, password faraday.response :logger if verbose faraday.adapter Faraday.default_adapter end - - conn end end diff --git a/lib/vmfloaty/logger.rb b/lib/vmfloaty/logger.rb index 88bf5f1..bdc2bb4 100644 --- a/lib/vmfloaty/logger.rb +++ b/lib/vmfloaty/logger.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'logger' class FloatyLogger < ::Logger @@ -19,22 +21,23 @@ class FloatyLogger < ::Logger def self.setlevel=(level) level = level.downcase - if level == "debug" - self.logger.level = ::Logger::DEBUG - elsif level == "info" - self.logger.level = ::Logger::INFO - elsif level == "error" - self.logger.level = ::Logger::ERROR + case level + when 'debug' + logger.level = ::Logger::DEBUG + when 'info' + logger.level = ::Logger::INFO + when 'error' + logger.level = ::Logger::ERROR else - error("set loglevel to debug, info or error") + error('set loglevel to debug, info or error') end end def initialize - super(STDERR) + super($stderr) self.level = ::Logger::INFO - self.formatter = proc do |severity, datetime, progname, msg| - "#{msg}\n" + self.formatter = proc do |_severity, _datetime, _progname, msg| + "#{msg}\n" end end end diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 0746034..eb6c6a7 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -22,7 +22,7 @@ class NonstandardPooler status['reserved_hosts'] || [] end - def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil, _continue = nil) + def self.retrieve(verbose, os_type, token, url, _user, _options, _ondemand = nil, _continue = nil) conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token @@ -46,7 +46,8 @@ class NonstandardPooler raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' if token.nil? modify_hash.each do |key, _value| - raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason reserved_for_reason].include? key + raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason + reserved_for_reason].include? key end if modify_hash[:reason] diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 5b5f65c..855e604 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -12,13 +12,11 @@ class Pooler response = conn.get 'vm' response_body = JSON.parse(response.body) - hosts = if os_filter - response_body.select { |i| i[/#{os_filter}/] } - else - response_body - end - - hosts + if os_filter + response_body.select { |i| i[/#{os_filter}/] } + else + response_body + end end def self.list_active(verbose, url, token, _user) @@ -50,7 +48,10 @@ class Pooler elsif response.status == 403 raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/vm/#{os_string}. Request exceeds the configured per pool maximum. #{res_body}" else - raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/vm/#{os_string}. #{res_body}" unless ondemand + unless ondemand + raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/vm/#{os_string}. #{res_body}" + end + raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/ondemandvm/#{os_string}. #{res_body}" end end @@ -63,7 +64,7 @@ class Pooler FloatyLogger.info "waiting for request #{request_id} to be fulfilled" sleep 5 end - FloatyLogger.info "The request has been fulfilled" + FloatyLogger.info 'The request has been fulfilled' check_ondemandvm(verbose, request_id, url) end @@ -84,8 +85,9 @@ class Pooler def self.modify(verbose, url, hostname, token, modify_hash) raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil? - modify_hash.keys.each do |key| - raise ModifyError, "Configured service type does not support modification of #{key}." unless %i[tags lifetime disk].include? key + modify_hash.each_key do |key| + raise ModifyError, "Configured service type does not support modification of #{key}." unless %i[tags lifetime + disk].include? key end conn = Http.get_conn(verbose, url) @@ -120,8 +122,7 @@ class Pooler response = conn.post "vm/#{hostname}/disk/#{disk}" - res_body = JSON.parse(response.body) - res_body + JSON.parse(response.body) end def self.delete(verbose, url, hosts, token, _user) @@ -146,25 +147,21 @@ class Pooler conn = Http.get_conn(verbose, url) response = conn.get '/status' - res_body = JSON.parse(response.body) - res_body + JSON.parse(response.body) end def self.summary(verbose, url) conn = Http.get_conn(verbose, url) response = conn.get '/summary' - res_body = JSON.parse(response.body) - res_body + JSON.parse(response.body) end def self.query(verbose, url, hostname) conn = Http.get_conn(verbose, url) response = conn.get "vm/#{hostname}" - res_body = JSON.parse(response.body) - - res_body + JSON.parse(response.body) end def self.snapshot(verbose, url, hostname, token) @@ -174,8 +171,7 @@ class Pooler conn.headers['X-AUTH-TOKEN'] = token response = conn.post "vm/#{hostname}/snapshot" - res_body = JSON.parse(response.body) - res_body + JSON.parse(response.body) end def self.revert(verbose, url, hostname, token, snapshot_sha) @@ -187,7 +183,6 @@ class Pooler raise "Snapshot SHA provided was nil, could not revert #{hostname}" if snapshot_sha.nil? response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}" - res_body = JSON.parse(response.body) - res_body + JSON.parse(response.body) end end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 196ac4c..05904a1 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -39,7 +39,7 @@ class Service def user unless @config['user'] FloatyLogger.info "Enter your #{@config['url']} service username:" - @config['user'] = STDIN.gets.chomp + @config['user'] = $stdin.gets.chomp end @config['user'] end @@ -140,8 +140,8 @@ class Service # some methods do not exist for ABS, and if possible should target the Pooler service def maybe_use_vmpooler if @service_object == ABS # this is not an instance - if !self.silent - FloatyLogger.info "The service in use is ABS, but the requested method should run against vmpooler directly, using fallback_vmpooler config from ~/.vmfloaty.yml" + unless silent + FloatyLogger.info 'The service in use is ABS, but the requested method should run against vmpooler directly, using fallback_vmpooler config from ~/.vmfloaty.yml' self.silent = true end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 113a6da..c1c4577 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -39,7 +39,10 @@ class Utils # "engine"=>"vmpooler" # } - raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok') + 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 domain = response_body.delete('domain') @@ -50,7 +53,7 @@ class Utils abs_job_id = response_body.delete('job_id') result['job_id'] = abs_job_id unless abs_job_id.nil? - filtered_response_body = response_body.reject { |key, _| key == 'request_id' || key == 'ready' } + filtered_response_body = response_body.reject { |key, _| %w[request_id ready].include?(key) } filtered_response_body.each do |os, value| hostnames = Array(value['hostname']) hostnames.map! { |host| "#{host}.#{domain}" } if domain @@ -106,7 +109,7 @@ class Utils def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false, indent = 0) output_target = print_to_stderr ? $stderr : $stdout - fetched_data = self.get_host_data(verbose, service, hostnames) + fetched_data = get_host_data(verbose, service, hostnames) fetched_data.each do |hostname, host_data| case service.type when 'ABS' @@ -116,13 +119,14 @@ class Utils output_target.puts "- [JobID:#{host_data['request']['job']['id']}] <#{host_data['state']}>" host_data['allocated_resources'].each do |allocated_resources, _i| - if (allocated_resources['engine'] == "vmpooler" || allocated_resources['engine'] == 'ondemand') && service.config["vmpooler_fallback"] + if (allocated_resources['engine'] == 'vmpooler' || allocated_resources['engine'] == 'ondemand') && service.config['vmpooler_fallback'] vmpooler_service = service.clone vmpooler_service.silent = true vmpooler_service.maybe_use_vmpooler - self.pretty_print_hosts(verbose, vmpooler_service, allocated_resources['hostname'].split('.')[0], print_to_stderr, indent+2) + pretty_print_hosts(verbose, vmpooler_service, allocated_resources['hostname'].split('.')[0], + print_to_stderr, indent + 2) else - #TODO we could add more specific metadata for the other services, nspooler and aws + # TODO: we could add more specific metadata for the other services, nspooler and aws output_target.puts " - #{allocated_resources['hostname']} (#{allocated_resources['type']})" end end @@ -132,7 +136,7 @@ class Utils duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['state'], host_data['template'], duration, *tag_pairs] message = "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) - if host_data['state'] && host_data['state'] == "destroyed" + if host_data['state'] && host_data['state'] == 'destroyed' output_target.puts message.colorize(:red) else output_target.puts message @@ -153,30 +157,26 @@ class Utils result = {} hostnames = [hostnames] unless hostnames.is_a? Array hostnames.each do |hostname| - begin - response = service.query(verbose, hostname) - host_data = response[hostname] - if block_given? - yield host_data result + response = service.query(verbose, hostname) + host_data = response[hostname] + if block_given? + yield host_data result + else + case service.type + when 'ABS' + # For ABS, 'hostname' variable is the jobID + result[hostname] = host_data if host_data['state'] == 'allocated' || host_data['state'] == 'filled' + when 'Pooler' + result[hostname] = host_data + when 'NonstandardPooler' + result[hostname] = host_data else - case service.type - when 'ABS' - # For ABS, 'hostname' variable is the jobID - if host_data['state'] == 'allocated' || host_data['state'] == 'filled' - result[hostname] = host_data - end - when 'Pooler' - result[hostname] = host_data - when 'NonstandardPooler' - result[hostname] = host_data - else - raise "Invalid service type #{service.type}" - end + raise "Invalid service type #{service.type}" end - rescue StandardError => e - FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:") - FloatyLogger.error(e) end + rescue StandardError => e + FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:") + FloatyLogger.error(e) end result end @@ -192,16 +192,14 @@ class Utils width = pools.keys.map(&:length).max pools.each do |name, pool| - begin - max = pool['max'] - ready = pool['ready'] - pending = pool['pending'] - missing = max - ready - pending - char = 'o' - puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" - rescue StandardError => e - FloatyLogger.error "#{name.ljust(width)} #{e.red}" - end + max = pool['max'] + ready = pool['ready'] + pending = pool['pending'] + missing = max - ready - pending + char = 'o' + puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" + rescue StandardError => e + FloatyLogger.error "#{name.ljust(width)} #{e.red}" end puts message.colorize(status_response['status']['ok'] ? :default : :red) when 'NonstandardPooler' @@ -211,16 +209,14 @@ class Utils width = pools.keys.map(&:length).max pools.each do |name, pool| - begin - max = pool['total_hosts'] - ready = pool['available_hosts'] - pending = pool['pending'] || 0 # not available for nspooler - missing = max - ready - pending - char = 'o' - puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" - rescue StandardError => e - FloatyLogger.error "#{name.ljust(width)} #{e.red}" - end + max = pool['total_hosts'] + ready = pool['available_hosts'] + pending = pool['pending'] || 0 # not available for nspooler + missing = max - ready - pending + char = 'o' + puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" + rescue StandardError => e + FloatyLogger.error "#{name.ljust(width)} #{e.red}" end when 'ABS' FloatyLogger.error 'ABS Not OK' unless status_response @@ -256,11 +252,11 @@ class Utils def self.get_service_config(config, options) # The top-level url, user, and token values in the config file are treated as defaults service_config = { - 'url' => config['url'], - 'user' => config['user'], + 'url' => config['url'], + 'user' => config['user'], 'token' => config['token'], 'vmpooler_fallback' => config['vmpooler_fallback'], - 'type' => config['type'] || 'vmpooler', + 'type' => config['type'] || 'vmpooler' } if config['services'] @@ -271,7 +267,10 @@ class Utils service_config.merge! values else # If the user provided a service name at the command line, use that service if posible, or fail - raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" unless config['services'][options.service] + unless config['services'][options.service] + raise ArgumentError, + "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" + end # 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] @@ -295,22 +294,22 @@ class Utils config = Conf.read_config # The top-level url, user, and token values in the config file are treated as defaults service_config = { - 'url' => config['url'], - 'user' => config['user'], - 'token' => config['token'], - 'type' => 'vmpooler', + 'url' => config['url'], + 'user' => config['user'], + 'token' => config['token'], + 'type' => 'vmpooler' } # at a minimum, the url needs to be configured if config['services'] && config['services'][vmpooler_fallback] && config['services'][vmpooler_fallback]['url'] # If the service is configured but some values are missing, use the top-level defaults to fill them in service_config.merge! config['services'][vmpooler_fallback] + elsif vmpooler_fallback.nil? + raise ArgumentError, + "The abs service should have a key named 'vmpooler_fallback' in ~/.vmfloaty.yml with a value that points to a vmpooler service name use this format:\nservices:\n myabs:\n url: 'http://abs.com'\n user: 'superman'\n token: 'kryptonite'\n vmpooler_fallback: 'myvmpooler'\n myvmpooler:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" else - if vmpooler_fallback.nil? - raise ArgumentError, "The abs service should have a key named 'vmpooler_fallback' in ~/.vmfloaty.yml with a value that points to a vmpooler service name use this format:\nservices:\n myabs:\n url: 'http://abs.com'\n user: 'superman'\n token: 'kryptonite'\n vmpooler_fallback: 'myvmpooler'\n myvmpooler:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" - else - raise ArgumentError, "Could not find a configured service named '#{vmpooler_fallback}' in ~/.vmfloaty.yml use this format:\nservices:\n #{vmpooler_fallback}:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" - end + raise ArgumentError, + "Could not find a configured service named '#{vmpooler_fallback}' in ~/.vmfloaty.yml use this format:\nservices:\n #{vmpooler_fallback}:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" end service_config diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index d74edd1..3c99d63 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -3,4 +3,3 @@ class Vmfloaty VERSION = '1.2.0' end - diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e23a554..6d17c36 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,9 +4,9 @@ require 'simplecov' require 'coveralls' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter -]) + SimpleCov::Formatter::HTMLFormatter, + Coveralls::SimpleCov::Formatter + ]) SimpleCov.start do add_filter %r{^/spec/} end diff --git a/spec/vmfloaty/abs/auth_spec.rb b/spec/vmfloaty/abs/auth_spec.rb index 555d6c5..fcf2392 100644 --- a/spec/vmfloaty/abs/auth_spec.rb +++ b/spec/vmfloaty/abs/auth_spec.rb @@ -16,7 +16,7 @@ describe Pooler do it 'returns a token from abs' do stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') - .to_return(:status => 200, :body => @get_token_response, :headers => {}) + .to_return(status: 200, body: @get_token_response, headers: {}) token = Auth.get_token(false, @abs_url, 'first.last', 'password') expect(token).to eq @token @@ -24,7 +24,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') - .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + .to_return(status: 500, body: '{"ok":false}', headers: {}) expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError) end @@ -38,14 +38,15 @@ describe Pooler do it 'deletes the specified token' do stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .to_return(:status => 200, :body => @delete_token_response, :headers => {}) + .to_return(status: 200, body: @delete_token_response, headers: {}) - expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) + expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', + @token)).to eq JSON.parse(@delete_token_response) end it 'raises a token error if something goes wrong' do stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + .to_return(status: 500, body: '{"ok":false}', headers: {}) expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError) end @@ -63,16 +64,16 @@ describe Pooler do it 'checks the status of a token' do stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' }) - .to_return(:status => 200, :body => @token_status_response, :headers => {}) + .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' }) + .to_return(status: 200, body: @token_status_response, headers: {}) expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response) end it 'raises a token error if something goes wrong' do stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' }) - .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' }) + .to_return(status: 500, body: '{"ok":false}', headers: {}) expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError) end diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index d6eabfc..4199c53 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -11,12 +11,12 @@ describe ABS do describe '#list' do it 'skips empty platforms and lists aws' do - stub_request(:get, "http://foo/api/v2/status/platforms/vmpooler"). - to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/api/v2/status/platforms/ondemand_vmpooler"). - to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/api/v2/status/platforms/nspooler"). - to_return(:status => 200, :body => "", :headers => {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/vmpooler') + .to_return(status: 200, body: '', headers: {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/ondemand_vmpooler') + .to_return(status: 200, body: '', headers: {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/nspooler') + .to_return(status: 200, body: '', headers: {}) body = '{ "aws_platforms": [ "amazon-6-x86_64", @@ -26,50 +26,55 @@ describe ABS do "redhat-8-arm64" ] }' - stub_request(:get, "http://foo/api/v2/status/platforms/aws"). - to_return(:status => 200, :body => body, :headers => {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/aws') + .to_return(status: 200, body: body, headers: {}) + results = ABS.list(false, 'http://foo') - results = ABS.list(false, "http://foo") - - expect(results).to include("amazon-6-x86_64", "amazon-7-x86_64", "amazon-7-arm64", "centos-7-x86-64-west", "redhat-8-arm64") + expect(results).to include('amazon-6-x86_64', 'amazon-7-x86_64', 'amazon-7-arm64', 'centos-7-x86-64-west', + 'redhat-8-arm64') end it 'legacy JSON string, prior to PR 306' do - stub_request(:get, "http://foo/api/v2/status/platforms/vmpooler"). - to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/api/v2/status/platforms/ondemand_vmpooler"). - to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/api/v2/status/platforms/nspooler"). - to_return(:status => 200, :body => "", :headers => {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/vmpooler') + .to_return(status: 200, body: '', headers: {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/ondemand_vmpooler') + .to_return(status: 200, body: '', headers: {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/nspooler') + .to_return(status: 200, body: '', headers: {}) body = '{ "aws_platforms": "[\"amazon-6-x86_64\",\"amazon-7-x86_64\",\"amazon-7-arm64\",\"centos-7-x86-64-west\",\"redhat-8-arm64\"]" }' - stub_request(:get, "http://foo/api/v2/status/platforms/aws"). - to_return(:status => 200, :body => body, :headers => {}) + stub_request(:get, 'http://foo/api/v2/status/platforms/aws') + .to_return(status: 200, body: body, headers: {}) - results = ABS.list(false, "http://foo") + results = ABS.list(false, 'http://foo') - expect(results).to include("amazon-6-x86_64", "amazon-7-x86_64", "amazon-7-arm64", "centos-7-x86-64-west", "redhat-8-arm64") + expect(results).to include('amazon-6-x86_64', 'amazon-7-x86_64', 'amazon-7-arm64', 'centos-7-x86-64-west', + 'redhat-8-arm64') end end describe '#format' do it 'returns an hash formatted like a vmpooler return, plus the job_id' do - job_id = "generated_by_floaty_12345" + job_id = 'generated_by_floaty_12345' abs_formatted_response = [ - { 'hostname' => 'aaaaaaaaaaaaaaa.delivery.puppetlabs.net', 'type' => 'centos-7.2-x86_64', 'engine' => 'vmpooler' }, - { 'hostname' => 'aaaaaaaaaaaaaab.delivery.puppetlabs.net', 'type' => 'centos-7.2-x86_64', 'engine' => 'vmpooler' }, - { 'hostname' => 'aaaaaaaaaaaaaac.delivery.puppetlabs.net', 'type' => 'ubuntu-7.2-x86_64', 'engine' => 'vmpooler' }, + { 'hostname' => 'aaaaaaaaaaaaaaa.delivery.puppetlabs.net', 'type' => 'centos-7.2-x86_64', + 'engine' => 'vmpooler' }, + { 'hostname' => 'aaaaaaaaaaaaaab.delivery.puppetlabs.net', 'type' => 'centos-7.2-x86_64', + 'engine' => 'vmpooler' }, + { 'hostname' => 'aaaaaaaaaaaaaac.delivery.puppetlabs.net', 'type' => 'ubuntu-7.2-x86_64', + 'engine' => 'vmpooler' } ] vmpooler_formatted_response = ABS.translated(abs_formatted_response, job_id) vmpooler_formatted_compare = { 'centos-7.2-x86_64' => {}, - 'ubuntu-7.2-x86_64' => {}, + 'ubuntu-7.2-x86_64' => {} } - vmpooler_formatted_compare['centos-7.2-x86_64']['hostname'] = ['aaaaaaaaaaaaaaa.delivery.puppetlabs.net', 'aaaaaaaaaaaaaab.delivery.puppetlabs.net'] + vmpooler_formatted_compare['centos-7.2-x86_64']['hostname'] = + ['aaaaaaaaaaaaaaa.delivery.puppetlabs.net', 'aaaaaaaaaaaaaab.delivery.puppetlabs.net'] vmpooler_formatted_compare['ubuntu-7.2-x86_64']['hostname'] = ['aaaaaaaaaaaaaac.delivery.puppetlabs.net'] vmpooler_formatted_compare['ok'] = true @@ -86,22 +91,22 @@ describe ABS do hosts = ['host1'] allocated_resources = [ { - 'hostname' => 'host1', + 'hostname' => 'host1' }, { - 'hostname' => 'host2', - }, + 'hostname' => 'host2' + } ] expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(false) - hosts = ['host1', 'host2'] + hosts = %w[host1 host2] allocated_resources = [ { - 'hostname' => 'host1', + 'hostname' => 'host1' }, { - 'hostname' => 'host2', - }, + 'hostname' => 'host2' + } ] expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(true) end @@ -126,16 +131,16 @@ describe ABS do it 'will skip a line with a null value returned from abs' do stub_request(:get, 'https://abs.example.com/api/v2/status/queue') - .to_return(:status => 200, :body => @active_requests_response, :headers => {}) + .to_return(status: 200, body: @active_requests_response, headers: {}) ret = ABS.get_active_requests(false, @abs_url, @test_user) expect(ret[0]).to include( 'allocated_resources' => [{ 'hostname' => 'take-this.delivery.puppetlabs.net', - 'type' => 'win-2012r2-x86_64', - 'engine' => 'vmpooler', - }], + 'type' => 'win-2012r2-x86_64', + 'engine' => 'vmpooler' + }] ) end end @@ -147,7 +152,7 @@ describe ABS do [ { "state":"allocated", "last_processed":"2020-01-17 22:29:13 +0000", "allocated_resources":[{"hostname":"craggy-chord.delivery.puppetlabs.net", "type":"centos-7-x86_64", "engine":"vmpooler"}, {"hostname":"visible-revival.delivery.puppetlabs.net", "type":"centos-7-x86_64", "engine":"vmpooler"}], "audit_log":{"2020-01-17 22:28:45 +0000":"Allocated craggy-chord.delivery.puppetlabs.net, visible-revival.delivery.puppetlabs.net for job 1579300120799"}, "request":{"resources":{"centos-7-x86_64":2}, "job":{"id":"1579300120799", "tags":{"user":"test-user"}, "user":"test-user", "time-received":1579300120}, "priority":3}} ]' - @return_request = { '{"job_id":"1579300120799","hosts":{"hostname":"craggy-chord.delivery.puppetlabs.net","type":"centos-7-x86_64","engine":"vmpooler"},{"hostname":"visible-revival.delivery.puppetlabs.net","type":"centos-7-x86_64","engine":"vmpooler"}}'=>true } + @return_request = { '{"job_id":"1579300120799","hosts":{"hostname":"craggy-chord.delivery.puppetlabs.net","type":"centos-7-x86_64","engine":"vmpooler"},{"hostname":"visible-revival.delivery.puppetlabs.net","type":"centos-7-x86_64","engine":"vmpooler"}}' => true } # rubocop:enable Layout/LineLength @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' @test_user = 'test-user' @@ -157,15 +162,15 @@ describe ABS do it 'will delete the whole job' do stub_request(:get, 'https://abs.example.com/api/v2/status/queue') - .to_return(:status => 200, :body => @active_requests_response, :headers => {}) + .to_return(status: 200, body: @active_requests_response, headers: {}) stub_request(:post, 'https://abs.example.com/api/v2/return') - .with(:body => @return_request) - .to_return(:status => 200, :body => 'OK', :headers => {}) + .with(body: @return_request) + .to_return(status: 200, body: 'OK', headers: {}) ret = ABS.delete(false, @abs_url, @hosts, @token, @test_user) expect(ret).to include( - 'craggy-chord.delivery.puppetlabs.net' => { 'ok'=>true }, 'visible-revival.delivery.puppetlabs.net' => { 'ok'=>true }, + 'craggy-chord.delivery.puppetlabs.net' => { 'ok' => true }, 'visible-revival.delivery.puppetlabs.net' => { 'ok' => true } ) end end diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 65cadc4..80effe1 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -16,7 +16,7 @@ describe Pooler do it 'returns a token from vmpooler' do stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') - .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') expect(token).to eq @token @@ -24,7 +24,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') - .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) end @@ -38,14 +38,15 @@ describe Pooler do it 'deletes the specified token' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .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 it 'raises a token error if something goes wrong' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .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) end @@ -63,14 +64,14 @@ describe Pooler do it 'checks the status of a token' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") - .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) end it 'raises a token error if something goes wrong' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") - .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) end diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 8bcfe3c..8b1ab7c 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -9,7 +9,7 @@ describe NonstandardPooler do before :each do @nspooler_url = 'https://nspooler.example.com' @auth_token_headers = { - 'X-Auth-Token' => 'token-value', + 'X-Auth-Token' => 'token-value' } end @@ -36,7 +36,7 @@ describe NonstandardPooler do it 'returns an array with operating systems from the pooler' do stub_request(:get, "#{@nspooler_url}/status") - .to_return(:status => 200, :body => @status_response_body, :headers => {}) + .to_return(status: 200, body: @status_response_body, headers: {}) list = NonstandardPooler.list(false, @nspooler_url, nil) expect(list).to be_an_instance_of Array @@ -44,7 +44,7 @@ describe NonstandardPooler do it 'filters operating systems based on the filter param' do stub_request(:get, "#{@nspooler_url}/status") - .to_return(:status => 200, :body => @status_response_body, :headers => {}) + .to_return(status: 200, body: @status_response_body, headers: {}) list = NonstandardPooler.list(false, @nspooler_url, 'aix') expect(list).to be_an_instance_of Array @@ -53,7 +53,7 @@ describe NonstandardPooler do it 'returns nothing if the filter does not match' do stub_request(:get, "#{@nspooler_url}/status") - .to_return(:status => 199, :body => @status_response_body, :headers => {}) + .to_return(status: 199, body: @status_response_body, headers: {}) list = NonstandardPooler.list(false, @nspooler_url, 'windows') expect(list).to be_an_instance_of Array @@ -89,7 +89,7 @@ describe NonstandardPooler do .and_return(JSON.parse(@token_status_body_active)) list = NonstandardPooler.list_active(false, @nspooler_url, 'token-value', 'user') - expect(list).to eql ['sol10-9', 'sol10-11'] + expect(list).to eql %w[sol10-9 sol10-11] end end @@ -121,17 +121,19 @@ describe NonstandardPooler do it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") - .with(:headers => @auth_token_headers) - .to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {}) + .with(headers: @auth_token_headers) + .to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {}) vm_hash = { 'solaris-11-sparc' => 1 } - expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {}) }.to raise_error(AuthError) + expect do + NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {}) + end.to raise_error(AuthError) end it 'retrieves a single vm with a token' do stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") - .with(:headers => @auth_token_headers) - .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) + .with(headers: @auth_token_headers) + .to_return(status: 200, body: @retrieve_response_body_single, headers: {}) vm_hash = { 'solaris-11-sparc' => 1 } vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {}) @@ -142,15 +144,16 @@ describe NonstandardPooler 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") - .with(:headers => @auth_token_headers) - .to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {}) + .with(headers: @auth_token_headers) + .to_return(status: 200, body: @retrieve_response_body_many, headers: {}) vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 } vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {}) expect(vm_req).to be_an_instance_of Hash expect(vm_req['ok']).to equal true expect(vm_req['solaris-10-sparc']['hostname']).to be_an_instance_of Array - expect(vm_req['solaris-10-sparc']['hostname']).to eq ['sol10-9.delivery.puppetlabs.net', 'sol10-10.delivery.puppetlabs.net'] + expect(vm_req['solaris-10-sparc']['hostname']).to eq ['sol10-9.delivery.puppetlabs.net', + 'sol10-10.delivery.puppetlabs.net'] expect(vm_req['aix-7.1-power']['hostname']).to eq 'pe-aix-71-ci-acceptance.delivery.puppetlabs.net' end end @@ -162,10 +165,10 @@ describe NonstandardPooler do it 'raises an error if the user tries to modify an unsupported attribute' do stub_request(:put, 'https://nspooler.example.com/host/myfakehost') - .with(:body => { '{}' => true }, - :headers => @auth_token_headers) - .to_return(:status => 200, :body => '', :headers => {}) - details = { :lifetime => 12 } + .with(body: { '{}' => true }, + headers: @auth_token_headers) + .to_return(status: 200, body: '', headers: {}) + details = { lifetime: 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } .to raise_error(ModifyError) end @@ -173,11 +176,11 @@ describe NonstandardPooler do it 'modifies the reason of a vm' do modify_request_body = { '{"reserved_for_reason":"testing"}' => true } stub_request(:put, "#{@nspooler_url}/host/myfakehost") - .with(:body => modify_request_body, - :headers => @auth_token_headers) - .to_return(:status => 200, :body => '{"ok": true}', :headers => {}) + .with(body: modify_request_body, + headers: @auth_token_headers) + .to_return(status: 200, body: '{"ok": true}', headers: {}) - modify_hash = { :reason => 'testing' } + modify_hash = { reason: 'testing' } modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash) expect(modify_req['ok']).to be true end @@ -208,7 +211,7 @@ describe NonstandardPooler do it 'prints the status' do stub_request(:get, "#{@nspooler_url}/status") - .to_return(:status => 200, :body => @status_response_body, :headers => {}) + .to_return(status: 200, body: @status_response_body, headers: {}) status = NonstandardPooler.status(false, @nspooler_url) expect(status).to be_an_instance_of Hash @@ -231,7 +234,7 @@ describe NonstandardPooler do it 'prints the summary' do stub_request(:get, "#{@nspooler_url}/summary") - .to_return(:status => 200, :body => @status_response_body, :headers => {}) + .to_return(status: 200, body: @status_response_body, headers: {}) summary = NonstandardPooler.summary(false, @nspooler_url) expect(summary).to be_an_instance_of Hash @@ -256,7 +259,7 @@ describe NonstandardPooler do it 'makes a query about a vm' do stub_request(:get, "#{@nspooler_url}/host/sol10-11") - .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') expect(query_req).to be_an_instance_of Hash @@ -271,8 +274,8 @@ describe NonstandardPooler do it 'deletes a single existing vm' do stub_request(:delete, "#{@nspooler_url}/host/sol11-7") - .with(:headers => @auth_token_headers) - .to_return(:status => 200, :body => @delete_response_success, :headers => {}) + .with(headers: @auth_token_headers) + .to_return(status: 200, body: @delete_response_success, headers: {}) request = NonstandardPooler.delete(false, @nspooler_url, 'sol11-7', 'token-value', nil) expect(request['sol11-7']['ok']).to be true @@ -280,8 +283,8 @@ describe NonstandardPooler do it 'does not delete a nonexistant vm' do stub_request(:delete, "#{@nspooler_url}/host/fakehost") - .with(:headers => @auth_token_headers) - .to_return(:status => 401, :body => @delete_response_failure, :headers => {}) + .with(headers: @auth_token_headers) + .to_return(status: 401, body: @delete_response_failure, headers: {}) request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value', nil) expect(request['fakehost']['ok']).to be false diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 7d83c79..0604176 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -15,7 +15,7 @@ describe Pooler do it 'returns a hash with operating systems from the pooler' do stub_request(:get, "#{@vmpooler_url}/vm") - .to_return(:status => 200, :body => @list_response_body, :headers => {}) + .to_return(status: 200, body: @list_response_body, headers: {}) list = Pooler.list(false, @vmpooler_url, nil) expect(list).to be_an_instance_of Array @@ -23,7 +23,7 @@ describe Pooler do it 'filters operating systems based on the filter param' do stub_request(:get, "#{@vmpooler_url}/vm") - .to_return(:status => 200, :body => @list_response_body, :headers => {}) + .to_return(status: 200, body: @list_response_body, headers: {}) list = Pooler.list(false, @vmpooler_url, 'deb') expect(list).to be_an_instance_of Array @@ -32,7 +32,7 @@ describe Pooler do it 'returns nothing if the filter does not match' do stub_request(:get, "#{@vmpooler_url}/vm") - .to_return(:status => 200, :body => @list_response_body, :headers => {}) + .to_return(status: 200, body: @list_response_body, headers: {}) list = Pooler.list(false, @vmpooler_url, 'windows') expect(list).to be_an_instance_of Array @@ -48,8 +48,8 @@ describe Pooler do it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 401, :body => '{"ok":false}', :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 401, body: '{"ok":false}', headers: {}) vm_hash = {} vm_hash['debian-7-i386'] = 1 @@ -58,8 +58,8 @@ describe Pooler do it 'retrieves a single vm with a token' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: @retrieve_response_body_single, headers: {}) vm_hash = {} vm_hash['debian-7-i386'] = 1 @@ -71,8 +71,8 @@ describe Pooler 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") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: @retrieve_response_body_double, headers: {}) vm_hash = {} vm_hash['debian-7-i386'] = 2 @@ -89,11 +89,11 @@ describe Pooler do let(:ondemand_response) { '{"ok":true,"request_id":"1234"}' } it 'retreives the vm with a token' do stub_request(:post, "#{@vmpooler_url}/ondemandvm/debian-7-i386") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => ondemand_response, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: ondemand_response, headers: {}) stub_request(:get, "#{@vmpooler_url}/ondemandvm/1234") - .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) + .to_return(status: 200, body: @retrieve_response_body_single, headers: {}) vm_hash = {} vm_hash['debian-7-i386'] = 1 @@ -117,11 +117,11 @@ describe Pooler do end it 'modifies the TTL of a vm' do - modify_hash = { :lifetime => 12 } + modify_hash = { lifetime: 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .with(:body => { '{"lifetime":12}' => true }, - :headers => { 'Content-Type' => 'application/x-www-form-urlencoded', 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) + .with(body: { '{"lifetime":12}' => true }, + headers: { 'Content-Type' => 'application/x-www-form-urlencoded', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: @modify_response_body_success, headers: {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) expect(modify_req['ok']).to be true @@ -136,8 +136,8 @@ describe Pooler do it 'deletes a specified vm' do stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: @delete_response_body_success, headers: {}) expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile', nil)).to eq @delete_response end @@ -155,7 +155,7 @@ describe Pooler do it 'prints the status' do stub_request(:get, "#{@vmpooler_url}/status") - .to_return(:status => 200, :body => @status_response_body, :headers => {}) + .to_return(status: 200, body: @status_response_body, headers: {}) status = Pooler.status(false, @vmpooler_url) expect(status).to be_an_instance_of Hash @@ -178,7 +178,7 @@ describe Pooler do it 'makes a query about a vm' do stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .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') expect(query_req).to be_an_instance_of Hash @@ -192,8 +192,8 @@ describe Pooler do it 'makes a snapshot for a single vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: @snapshot_response_body, headers: {}) snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') expect(snapshot_req['ok']).to be true @@ -207,15 +207,18 @@ describe Pooler do it 'makes a request to revert a vm from a snapshot' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) - .to_return(:status => 200, :body => @revert_response_body, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }) + .to_return(status: 200, body: @revert_response_body, headers: {}) revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') expect(revert_req['ok']).to be true end it "doesn't make a request to revert a vm if snapshot is not provided" do - expect { Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6') + expect do + Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', + nil) + end.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6') end it 'raises a TokenError if no token was provided' do @@ -231,7 +234,7 @@ describe Pooler do it 'makes a request to extend disk space of a vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12") - .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @disk_response_body_success, :headers => {}) + .with(headers: { 'X-Auth-Token' => 'mytokenfile' }).to_return(status: 200, body: @disk_response_body_success, headers: {}) disk_req = Pooler.disk(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12) expect(disk_req['ok']).to be true diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 13426b3..70c7199 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -16,7 +16,7 @@ describe Service do it 'prompts the user for their password and retrieves a token' do config = { 'user' => 'first.last', 'url' => 'http://default.url' } service = Service.new(MockOptions.new, config) - allow(STDOUT).to receive(:puts).with('Enter your http://default.url service password:') + allow($stdout).to receive(:puts).with('Enter your http://default.url service password:') allow(Commander::UI).to(receive(:password) .with('Enter your http://default.url service password:', '*') .and_return('hunter2')) @@ -29,9 +29,9 @@ describe Service do it 'prompts the user for their username and password if the username is unknown' do config = { 'url' => 'http://default.url' } service = Service.new(MockOptions.new({}), config) - allow(STDOUT).to receive(:puts).with 'Enter your http://default.url service username:' - allow(STDOUT).to receive(:puts).with "\n" - allow(STDIN).to receive(:gets).and_return('first.last') + allow($stdout).to receive(:puts).with 'Enter your http://default.url service username:' + allow($stdout).to receive(:puts).with "\n" + allow($stdin).to receive(:gets).and_return('first.last') allow(Commander::UI).to(receive(:password) .with('Enter your http://default.url service password:', '*') .and_return('hunter2')) @@ -59,16 +59,16 @@ describe Service do it 'reports the status of a token' do config = { 'user' => 'first.last', - 'url' => 'http://default.url', + 'url' => 'http://default.url' } options = MockOptions.new('token' => 'token-value') service = Service.new(options, config) status = { - 'ok' => true, - 'user' => config['user'], - 'created' => '2017-09-22 02:04:18 +0000', - 'last_accessed' => '2017-09-22 02:04:28 +0000', - 'reserved_hosts' => [], + 'ok' => true, + 'user' => config['user'], + 'created' => '2017-09-22 02:04:18 +0000', + 'last_accessed' => '2017-09-22 02:04:28 +0000', + 'reserved_hosts' => [] } allow(Auth).to(receive(:token_status) .with(nil, config['url'], 'token-value') diff --git a/spec/vmfloaty/ssh_spec.rb b/spec/vmfloaty/ssh_spec.rb index c780a88..c16bb30 100644 --- a/spec/vmfloaty/ssh_spec.rb +++ b/spec/vmfloaty/ssh_spec.rb @@ -8,14 +8,14 @@ class ServiceStub if os_types.keys[0] == 'abs_host_string' return { os_types.keys[0] => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net'] }, - 'ok' => true, + 'ok' => true } end { os_types.keys[0] => { 'hostname' => 'vmpooler-hostname' }, - 'domain' => 'delivery.puppetlabs.net', - 'ok' => true, + 'domain' => 'delivery.puppetlabs.net', + 'ok' => true } end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index ab5846e..bade876 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -36,13 +36,14 @@ describe Utils do it 'formats a result from vmpooler into a hash of os to hostnames' do result = Utils.standardize_hostnames(JSON.parse(@vmpooler_response_body)) - expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], - 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net']) + expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], + 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', + 'ctnktsd0u11p9tm.delivery.mycompany.net']) end it 'formats a result from the nonstandard pooler into a hash of os to hostnames' do result = Utils.standardize_hostnames(JSON.parse(@nonstandard_response_body)) - expect(result).to eq('solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], + expect(result).to eq('solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net']) end end @@ -50,12 +51,12 @@ describe Utils do describe '#format_host_output' do before :each do @vmpooler_results = { - 'centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], - 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net'], + 'centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], + 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net'] } @nonstandard_results = { - 'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], - 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'], + 'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], + 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'] } @vmpooler_output = <<~OUT.chomp - dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) @@ -98,23 +99,23 @@ describe Utils do describe '#get_service_config' do before :each do @default_config = { - 'url' => 'http://default.url', - 'user' => 'first.last.default', - 'token' => 'default-token', + 'url' => 'http://default.url', + 'user' => 'first.last.default', + 'token' => 'default-token' } @services_config = { 'services' => { 'vm' => { - 'url' => 'http://vmpooler.url', - 'user' => 'first.last.vmpooler', - 'token' => 'vmpooler-token', + 'url' => 'http://vmpooler.url', + 'user' => 'first.last.vmpooler', + 'token' => 'vmpooler-token' }, 'ns' => { - 'url' => 'http://nspooler.url', - 'user' => 'first.last.nspooler', - 'token' => 'nspooler-token', - }, - }, + 'url' => 'http://nspooler.url', + 'user' => 'first.last.nspooler', + 'token' => 'nspooler-token' + } + } } end @@ -126,26 +127,26 @@ describe Utils do it 'allows selection by configured service key' do config = @default_config.merge @services_config - options = MockOptions.new(:service => 'ns') + options = MockOptions.new(service: 'ns') expect(Utils.get_service_config(config, options)).to include @services_config['services']['ns'] end it 'uses top-level service config values as defaults when configured service values are missing' do config = @default_config.merge @services_config 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' end it "raises an error if passed a service name that hasn't been configured" do config = @default_config.merge @services_config - options = MockOptions.new(:service => 'none') + options = MockOptions.new(service: 'none') expect { Utils.get_service_config(config, options) }.to raise_error ArgumentError end it 'prioritizes values passed as command line options over configuration options' do 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') expect(Utils.get_service_config(config, options)).to include expected end @@ -182,15 +183,15 @@ describe Utils do { 'template' => 'ubuntu-1604-x86_64', 'lifetime' => 12, - 'running' => 9.66, - 'state' => 'running', - 'ip' => '127.0.0.1', - 'domain' => domain, + 'running' => 9.66, + 'state' => 'running', + 'ip' => '127.0.0.1', + 'domain' => domain } end it 'outputs fqdn for host' do - expect(STDOUT).to receive(:puts).with(fqdn) + expect($stdout).to receive(:puts).with(fqdn) subject end @@ -201,17 +202,17 @@ describe Utils do let(:hostname) { 'sol11-9.delivery.mycompany.net' } let(:host_data) do { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => '', - 'hours_left_on_reservation' => 35.89, + 'fqdn' => hostname, + 'os_triple' => 'solaris-11-sparc', + 'reserved_by_user' => 'first.last', + 'reserved_for_reason' => '', + 'hours_left_on_reservation' => 35.89 } end let(:fqdn) { hostname } # for nspooler these are the same it 'outputs fqdn for host' do - expect(STDOUT).to receive(:puts).with(fqdn) + expect($stdout).to receive(:puts).with(fqdn) subject end @@ -231,19 +232,19 @@ describe Utils do { 'hostname' => fqdn, 'type' => template, - 'enging' => 'vmpooler', - }, + 'enging' => 'vmpooler' + } ], 'request' => { 'job' => { - 'id' => hostname, + 'id' => hostname } - }, + } } end it 'outputs fqdn for host' do - expect(STDOUT).to receive(:puts).with(fqdn) + expect($stdout).to receive(:puts).with(fqdn) subject end @@ -275,10 +276,10 @@ describe Utils do hostname => { 'template' => 'ubuntu-1604-x86_64', 'lifetime' => 12, - 'running' => 9.66, - 'state' => 'running', - 'ip' => '127.0.0.1', - 'domain' => domain, + 'running' => 9.66, + 'state' => 'running', + 'ip' => '127.0.0.1', + 'domain' => domain } } end @@ -286,7 +287,7 @@ describe Utils do let(:default_output) { "- #{fqdn} (running, ubuntu-1604-x86_64, 9.66/12 hours)" } it 'prints output with host fqdn, template and duration info' do - expect(STDOUT).to receive(:puts).with(default_output) + expect($stdout).to receive(:puts).with(default_output) subject end @@ -298,14 +299,14 @@ describe Utils do hostname => { 'template' => 'redhat-7-x86_64', 'lifetime' => 48, - 'running' => 7.67, - 'state' => 'running', - 'tags' => { + 'running' => 7.67, + 'state' => 'running', + 'tags' => { 'user' => 'bob', - 'role' => 'agent', + 'role' => 'agent' }, - 'ip' => '127.0.0.1', - 'domain' => domain, + 'ip' => '127.0.0.1', + 'domain' => domain } } end @@ -313,7 +314,7 @@ describe Utils do it 'prints output with host fqdn, template, duration info, and tags' do output = "- #{fqdn} (running, redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" - expect(STDOUT).to receive(:puts).with(output) + expect($stdout).to receive(:puts).with(output) subject end @@ -323,7 +324,7 @@ describe Utils do let(:print_to_stderr) { true } it 'outputs to stderr instead of stdout' do - expect(STDERR).to receive(:puts).with(default_output) + expect($stderr).to receive(:puts).with(default_output) subject end @@ -337,11 +338,11 @@ describe Utils do let(:response_body) do { hostname => { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => '', - 'hours_left_on_reservation' => 35.89, + 'fqdn' => hostname, + 'os_triple' => 'solaris-11-sparc', + 'reserved_by_user' => 'first.last', + 'reserved_for_reason' => '', + 'hours_left_on_reservation' => 35.89 } } end @@ -349,7 +350,7 @@ describe Utils do let(:default_output) { "- #{hostname} (solaris-11-sparc, 35.89h remaining)" } it 'prints output with host, template, and time remaining' do - expect(STDOUT).to receive(:puts).with(default_output) + expect($stdout).to receive(:puts).with(default_output) subject end @@ -358,11 +359,11 @@ describe Utils do let(:response_body) do { hostname => { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => 'testing', - 'hours_left_on_reservation' => 35.89, + 'fqdn' => hostname, + 'os_triple' => 'solaris-11-sparc', + 'reserved_by_user' => 'first.last', + 'reserved_for_reason' => 'testing', + 'hours_left_on_reservation' => 35.89 } } end @@ -370,7 +371,7 @@ describe Utils do it 'prints output with host, template, time remaining, and reason' do output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)' - expect(STDOUT).to receive(:puts).with(output) + expect($stdout).to receive(:puts).with(output) subject end @@ -380,7 +381,7 @@ describe Utils do let(:print_to_stderr) { true } it 'outputs to stderr instead of stdout' do - expect(STDERR).to receive(:puts).with(default_output) + expect($stderr).to receive(:puts).with(default_output) subject end @@ -392,7 +393,7 @@ describe Utils do let(:hostname) { '1597952189390' } let(:fqdn) { 'example-noun.delivery.mycompany.net' } - let(:fqdn_hostname) {'example-noun'} + let(:fqdn_hostname) { 'example-noun' } let(:template) { 'ubuntu-1604-x86_64' } # This seems to be the miminal stub response from ABS for the current output @@ -404,14 +405,14 @@ describe Utils do { 'hostname' => fqdn, 'type' => template, - 'engine' => 'vmpooler', - }, + 'engine' => 'vmpooler' + } ], 'request' => { 'job' => { - 'id' => hostname, + 'id' => hostname } - }, + } } } end @@ -420,58 +421,58 @@ describe Utils do let(:domain) { 'delivery.mycompany.net' } let(:response_body_vmpooler) do { - fqdn_hostname => { - 'template' => template, - 'lifetime' => 48, - 'running' => 7.67, - 'state' => 'running', - 'tags' => { - 'user' => 'bob', - 'role' => 'agent', - }, - 'ip' => '127.0.0.1', - 'domain' => domain, - } + fqdn_hostname => { + 'template' => template, + 'lifetime' => 48, + 'running' => 7.67, + 'state' => 'running', + 'tags' => { + 'user' => 'bob', + 'role' => 'agent' + }, + 'ip' => '127.0.0.1', + 'domain' => domain + } } end before(:each) do allow(Utils).to receive(:get_vmpooler_service_config).and_return({ - 'url' => 'http://vmpooler.example.com', - 'token' => 'krypto-knight' - }) + 'url' => 'http://vmpooler.example.com', + 'token' => 'krypto-knight' + }) allow(service).to receive(:query) - .with(anything, fqdn_hostname) - .and_return(response_body_vmpooler) + .with(anything, fqdn_hostname) + .and_return(response_body_vmpooler) end let(:default_output_first_line) { "- [JobID:#{hostname}] " } let(:default_output_second_line) { " - #{fqdn} (#{template})" } it 'prints output with job id, host, and template' do - expect(STDOUT).to receive(:puts).with(default_output_first_line) - expect(STDOUT).to receive(:puts).with(default_output_second_line) + expect($stdout).to receive(:puts).with(default_output_first_line) + expect($stdout).to receive(:puts).with(default_output_second_line) subject end it 'prints more information when vmpooler_fallback is set output with job id, host, template, lifetime, user and role' do - fallback = {'vmpooler_fallback' => 'vmpooler'} + fallback = { 'vmpooler_fallback' => 'vmpooler' } service.config.merge! fallback - default_output_second_line=" - #{fqdn} (running, #{template}, 7.67/48 hours, user: bob, role: agent)" - expect(STDOUT).to receive(:puts).with(default_output_first_line) - expect(STDOUT).to receive(:puts).with(default_output_second_line) + default_output_second_line = " - #{fqdn} (running, #{template}, 7.67/48 hours, user: bob, role: agent)" + expect($stdout).to receive(:puts).with(default_output_first_line) + expect($stdout).to receive(:puts).with(default_output_second_line) subject end it 'prints in red when destroyed' do - fallback = {'vmpooler_fallback' => 'vmpooler'} + fallback = { 'vmpooler_fallback' => 'vmpooler' } service.config.merge! fallback - response_body_vmpooler[fqdn_hostname]['state'] = "destroyed" - default_output_second_line_red=" - #{fqdn} (destroyed, #{template}, 7.67/48 hours, user: bob, role: agent)".red - expect(STDOUT).to receive(:puts).with(default_output_first_line) - expect(STDOUT).to receive(:puts).with(default_output_second_line_red) + response_body_vmpooler[fqdn_hostname]['state'] = 'destroyed' + default_output_second_line_red = " - #{fqdn} (destroyed, #{template}, 7.67/48 hours, user: bob, role: agent)".red + expect($stdout).to receive(:puts).with(default_output_first_line) + expect($stdout).to receive(:puts).with(default_output_second_line_red) subject end @@ -480,8 +481,8 @@ describe Utils do let(:print_to_stderr) { true } it 'outputs to stderr instead of stdout' do - expect(STDERR).to receive(:puts).with(default_output_first_line) - expect(STDERR).to receive(:puts).with(default_output_second_line) + expect($stderr).to receive(:puts).with(default_output_first_line) + expect($stderr).to receive(:puts).with(default_output_second_line) subject end @@ -494,34 +495,34 @@ describe Utils do let(:hostname) { '1597952189390' } let(:fqdn) { 'this-noun.delivery.mycompany.net' } let(:fqdn_ns) { 'that-noun.delivery.mycompany.net' } - let(:fqdn_hostname) {'this-noun'} - let(:fqdn_ns_hostname) {'that-noun'} + let(:fqdn_hostname) { 'this-noun' } + let(:fqdn_ns_hostname) { 'that-noun' } let(:template) { 'ubuntu-1604-x86_64' } let(:template_ns) { 'solaris-10-sparc' } # This seems to be the miminal stub response from ABS for the current output let(:response_body) do { - hostname => { - 'state' => 'allocated', - 'allocated_resources' => [ - { - 'hostname' => fqdn, - 'type' => template, - 'engine' => 'vmpooler', - }, - { - 'hostname' => fqdn_ns, - 'type' => template_ns, - 'engine' => 'nspooler', - }, - ], - 'request' => { - 'job' => { - 'id' => hostname, - } - }, + hostname => { + 'state' => 'allocated', + 'allocated_resources' => [ + { + 'hostname' => fqdn, + 'type' => template, + 'engine' => 'vmpooler' + }, + { + 'hostname' => fqdn_ns, + 'type' => template_ns, + 'engine' => 'nspooler' + } + ], + 'request' => { + 'job' => { + 'id' => hostname + } } + } } end @@ -529,29 +530,29 @@ describe Utils do let(:domain) { 'delivery.mycompany.net' } let(:response_body_vmpooler) do { - fqdn_hostname => { - 'template' => template, - 'lifetime' => 48, - 'running' => 7.67, - 'state' => 'running', - 'tags' => { - 'user' => 'bob', - 'role' => 'agent', - }, - 'ip' => '127.0.0.1', - 'domain' => domain, - } + fqdn_hostname => { + 'template' => template, + 'lifetime' => 48, + 'running' => 7.67, + 'state' => 'running', + 'tags' => { + 'user' => 'bob', + 'role' => 'agent' + }, + 'ip' => '127.0.0.1', + 'domain' => domain + } } end before(:each) do allow(Utils).to receive(:get_vmpooler_service_config).and_return({ - 'url' => 'http://vmpooler.example.com', - 'token' => 'krypto-knight' + 'url' => 'http://vmpooler.example.com', + 'token' => 'krypto-knight' }) allow(service).to receive(:query) - .with(anything, fqdn_hostname) - .and_return(response_body_vmpooler) + .with(anything, fqdn_hostname) + .and_return(response_body_vmpooler) end let(:default_output_first_line) { "- [JobID:#{hostname}] " } @@ -559,9 +560,9 @@ describe Utils do let(:default_output_third_line) { " - #{fqdn_ns} (#{template_ns})" } it 'prints output with job id, host, and template' do - expect(STDOUT).to receive(:puts).with(default_output_first_line) - expect(STDOUT).to receive(:puts).with(default_output_second_line) - expect(STDOUT).to receive(:puts).with(default_output_third_line) + expect($stdout).to receive(:puts).with(default_output_first_line) + expect($stdout).to receive(:puts).with(default_output_second_line) + expect($stdout).to receive(:puts).with(default_output_third_line) subject end @@ -570,9 +571,9 @@ describe Utils do let(:print_to_stderr) { true } it 'outputs to stderr instead of stdout' do - expect(STDERR).to receive(:puts).with(default_output_first_line) - expect(STDERR).to receive(:puts).with(default_output_second_line) - expect(STDERR).to receive(:puts).with(default_output_third_line) + expect($stderr).to receive(:puts).with(default_output_first_line) + expect($stderr).to receive(:puts).with(default_output_second_line) + expect($stderr).to receive(:puts).with(default_output_third_line) subject end @@ -586,54 +587,59 @@ describe Utils do config = { 'user' => 'foo', 'services' => { - 'myabs' => { - 'url' => 'http://abs.com', - 'token' => 'krypto-night', - 'type' => 'abs' - } + 'myabs' => { + 'url' => 'http://abs.com', + 'token' => 'krypto-night', + 'type' => 'abs' + } } } allow(Conf).to receive(:read_config).and_return(config) - expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError) + expect do + Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback']) + end.to raise_error(ArgumentError) end it 'returns an error if the vmpooler_fallback is setup but cannot be found' do config = { 'user' => 'foo', 'services' => { 'myabs' => { - 'url' => 'http://abs.com', - 'token' => 'krypto-night', - 'type' => 'abs', - 'vmpooler_fallback' => 'myvmpooler' + 'url' => 'http://abs.com', + 'token' => 'krypto-night', + 'type' => 'abs', + 'vmpooler_fallback' => 'myvmpooler' } } } allow(Conf).to receive(:read_config).and_return(config) - expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError, /myvmpooler/) + expect do + Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback']) + end.to raise_error(ArgumentError, + /myvmpooler/) end it 'returns the vmpooler_fallback config' do config = { 'user' => 'foo', 'services' => { 'myabs' => { - 'url' => 'http://abs.com', - 'token' => 'krypto-night', - 'type' => 'abs', - 'vmpooler_fallback' => 'myvmpooler' + 'url' => 'http://abs.com', + 'token' => 'krypto-night', + 'type' => 'abs', + 'vmpooler_fallback' => 'myvmpooler' }, 'myvmpooler' => { - 'url' => 'http://vmpooler.com', - 'token' => 'krypto-knight' + 'url' => 'http://vmpooler.com', + 'token' => 'krypto-knight' } } } allow(Conf).to receive(:read_config).and_return(config) expect(Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])).to include({ - 'url' => 'http://vmpooler.com', - 'token' => 'krypto-knight', - 'user' => 'foo', - 'type' => 'vmpooler' - }) + 'url' => 'http://vmpooler.com', + 'token' => 'krypto-knight', + 'user' => 'foo', + 'type' => 'vmpooler' + }) end end end diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 572c255..14e3db2 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -8,11 +8,11 @@ Gem::Specification.new do |s| s.version = Vmfloaty::VERSION s.authors = [ 'Brian Cain', - 'Puppet', + 'Puppet' ] s.email = [ 'brianccain@gmail.com', - 'dio-gems@puppet.com', + 'dio-gems@puppet.com' ] s.license = 'Apache-2.0' s.homepage = 'https://github.com/puppetlabs/vmfloaty'