From b5c6ce7a2074c7b0ab1881cf36ed51d4c79764a0 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 9 Dec 2016 08:59:04 -0800 Subject: [PATCH 001/265] Update usage to match help text --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4c86ad6..60d5629 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,17 @@ $ floaty --help ``` delete Schedules the deletion of a host or hosts - get Gets a vm or vms based on the os flag + get Gets a vm or vms based on the os argument help Display global or [command] help documentation - list Shows a list of available vms from the pooler - modify Modify a vms tags and TTL + list Shows a list of available vms from the pooler or vms obtained with a token + modify Modify a vms tags, time to live, and disk space query Get information about a given vm revert Reverts a vm to a specified snapshot snapshot Takes a snapshot of a given vm ssh Grabs a single vm and sshs into it - status Prints the status of vmpooler - summary Prints the summary of vmpooler - token Retrieves or deletes a token + status Prints the status of pools in vmpooler + summary Prints a summary of vmpooler + token Retrieves or deletes a token or checks token status GLOBAL OPTIONS: @@ -59,7 +59,7 @@ This command will then ask you to log in. If successful, it will return a token Grabbing vms: ``` -floaty get centos-7-x86_64=2 debian-7-x86_64=1 windows-10=3 --token mytokenstring --url https://vmpooler.mycompany.net/api/v1 +floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring --url https://vmpooler.mycompany.net/api/v1 ``` ### vmfloaty dotfile From 82afa94b6ebd86efa9b9bcd8dca2c948957a7cf6 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Dec 2016 11:04:51 -0800 Subject: [PATCH 002/265] Properly check for large pool size requests --- lib/vmfloaty.rb | 2 +- lib/vmfloaty/version.rb | 2 +- vmfloaty.gemspec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 5e0621c..9c878ff 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -49,7 +49,7 @@ class Vmfloaty max_pool_request = 5 large_pool_requests = os_types.select{|k,v| v > max_pool_request} - if ! large_pool_requests.nil? and ! force + if ! large_pool_requests.empty? and ! force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts "Try again with `floaty get --force`" exit 1 diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index b9425a3..604d18e 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,6 +1,6 @@ class Version - @version = '0.7.6' + @version = '0.7.7' def self.get @version diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 34b416d..b192220 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'vmfloaty' - s.version = '0.7.6' + s.version = '0.7.7' s.authors = ['Brian Cain'] s.email = ['brian.cain@puppetlabs.com'] s.license = 'Apache' From 313742ebfd924eee551193bda638886ca7c40deb Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 16 Dec 2016 11:21:20 -0800 Subject: [PATCH 003/265] Use actual hostname when creating snapshots in warn msg --- lib/vmfloaty.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 9c878ff..3f718d9 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -382,7 +382,7 @@ class Vmfloaty exit 1 end - puts "Snapshot pending. Use `floaty query host` to determine when snapshot is valid." + puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid." pp snapshot_req end end From c8525bd0f155b054bc41d0f7ddbb1e9825e0db4d Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 20 Dec 2016 08:42:09 -0800 Subject: [PATCH 004/265] Bump to 0.7.8 --- lib/vmfloaty/version.rb | 2 +- vmfloaty.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 604d18e..8674f33 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,6 +1,6 @@ class Version - @version = '0.7.7' + @version = '0.7.8' def self.get @version diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index b192220..15284d9 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'vmfloaty' - s.version = '0.7.7' + s.version = '0.7.8' s.authors = ['Brian Cain'] s.email = ['brian.cain@puppetlabs.com'] s.license = 'Apache' From 573f0d83a96472bbe32db9bf93dfd52fbec5db0a Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 11:48:06 -0800 Subject: [PATCH 005/265] Update Gemspec Formatting is slightly more idiomatic now. --- Gemfile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 13c60e1..49db604 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,11 @@ source 'https://rubygems.org' -gem 'commander' -gem 'faraday', '0.9.2' -gem 'colorize', '~> 0.8' - -gem 'rspec' -gem 'webmock', '1.21.0' -gem 'rake' - gemspec + +gem 'rake', require: false + +group :test do + gem 'rspec', '~> 3.5.0' + gem 'rubocop', '~> 0.47' + gem 'webmock', '1.21.0' +end From 8babbe32ce336b41f86f62bd88d91603acdafcb4 Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 11:51:21 -0800 Subject: [PATCH 006/265] Add Rubocop support to Rakefile --- Rakefile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 755ebc1..efbd5a9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,7 @@ require 'rubygems' require 'bundler/setup' require 'rspec/core/rake_task' +require 'rubocop/rake_task' # Immediately sync all stdout so that tools like buildbot can # immediately load in the output. @@ -8,7 +9,7 @@ $stdout.sync = true $stderr.sync = true # Change to the directory of this file. -Dir.chdir(File.expand_path("../", __FILE__)) +Dir.chdir(File.expand_path('../', __FILE__)) # This installs the tasks that help with gem creation and # publishing. @@ -16,7 +17,13 @@ Bundler::GemHelper.install_tasks # Install the `spec` task so that we can run tests. RSpec::Core::RakeTask.new(:spec) do |t| - t.rspec_opts = "--order defined" + t.rspec_opts = '--order defined' end + +desc 'Run RuboCop' +RuboCop::RakeTask.new(:rubocop) do |task| + task.options << '--display-cop-names' +end + # Default task is to run the unit tests -task :default => :spec +task default: :spec From ee0c73dfda1eee2855524937de5364acc0dbb42e Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 11:53:08 -0800 Subject: [PATCH 007/265] Add a little formatting to Rspec --- spec/spec_helper.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8eaa8b4..decf5e7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,2 +1,8 @@ require 'vmfloaty' require 'webmock/rspec' + +RSpec.configure do |config| + config.color = true + config.tty = true + config.formatter = :documentation +end From 21c42dbffa389b0de91f7270c414a2e607995651 Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 12:38:46 -0800 Subject: [PATCH 008/265] Clarify license in Gemspec As per https://opensource.org/licenses/alphabetical, the name should be Apache-2.0, not Apache. --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 15284d9..82e3f7a 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -3,7 +3,7 @@ Gem::Specification.new do |s| s.version = '0.7.8' s.authors = ['Brian Cain'] s.email = ['brian.cain@puppetlabs.com'] - s.license = 'Apache' + s.license = 'Apache-2.0' s.homepage = 'https://github.com/briancain/vmfloaty' s.description = 'A helper tool for vmpooler to help you stay afloat' s.summary = 'CLI application to interface with vmpooler' From 0380b5fc9addb570fc10eb163ff1ae5ca4c82819 Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 12:39:22 -0800 Subject: [PATCH 009/265] Gemspec whitespace & tighter version constraints Pessimistic versioning means that Faraday 0.11.0 will be installed if the constraint is "~> 0.9", and that will break spec tests due to newer restrictions in Faraday around how HTTP requests are handled by rspec. We don't want to break tests. --- vmfloaty.gemspec | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 82e3f7a..2be8ab4 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -7,11 +7,13 @@ Gem::Specification.new do |s| s.homepage = 'https://github.com/briancain/vmfloaty' s.description = 'A helper tool for vmpooler to help you stay afloat' s.summary = 'CLI application to interface with vmpooler' + s.executables = ['floaty'] s.files = Dir['LICENSE', 'README.md', 'lib/**/*'] s.test_files = Dir['spec/**/*'] s.require_path = 'lib' - s.add_dependency 'commander', '~> 4.3' - s.add_dependency 'faraday', '~> 0.9' - s.add_dependency 'colorize', '0.8.1' + + s.add_dependency 'commander', '~> 4.3.0' + s.add_dependency 'faraday', '~> 0.9.0' + s.add_dependency 'colorize', '~> 0.8.1' end From 5c794cd2b0962d2716f6e5892e6cf1c3235b1bb9 Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 12:41:06 -0800 Subject: [PATCH 010/265] Use the Classname::VERSION pattern Instead of having a hardcoded version identifier in multiple locations, we can leverage the Classname::VERSION pattern to have a single canonical version number that everything can reference programmatically. --- lib/vmfloaty.rb | 2 +- lib/vmfloaty/version.rb | 9 ++------- vmfloaty.gemspec | 5 ++++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 3f718d9..a30ca11 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -16,7 +16,7 @@ class Vmfloaty include Commander::Methods def run - program :version, Version.get + program :version, Vmfloaty::VERSION program :description, 'A CLI helper tool for Puppet Labs vmpooler to help you stay afloat' config = Conf.read_config diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 8674f33..9e40ace 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,8 +1,3 @@ - -class Version - @version = '0.7.8' - - def self.get - @version - end +class Vmfloaty + VERSION = '0.7.8'.freeze end diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 2be8ab4..52820b6 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -1,6 +1,9 @@ +$LOAD_PATH.push File.expand_path('../lib', __FILE__) +require 'vmfloaty/version' + Gem::Specification.new do |s| s.name = 'vmfloaty' - s.version = '0.7.8' + s.version = Vmfloaty::VERSION s.authors = ['Brian Cain'] s.email = ['brian.cain@puppetlabs.com'] s.license = 'Apache-2.0' From d7e3bc9a02206af2d5e2dc098dc76a230f2fbbc6 Mon Sep 17 00:00:00 2001 From: Ryan McKern Date: Wed, 1 Mar 2017 12:45:39 -0800 Subject: [PATCH 011/265] Improve Travis platforms Ruby 2.0 is dead, but 2.1 is not. Of note is that Ruby 2.1 *will* be unsupported soon, but it's definitely not dead yet. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e10c011..41b77f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: false language: ruby rvm: - - 2.0.0-p247 + - 2.1 script: rspec spec From cfbad921ceedf0d9a237f4c49c6db92e58e0a95a Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 14 Mar 2017 08:58:28 -0700 Subject: [PATCH 012/265] (maint) Be clearer about which password to use --- lib/vmfloaty.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 3f718d9..3161e25 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -75,7 +75,7 @@ class Vmfloaty STDERR.puts "You did not provide a user to authenticate to vmpooler with" exit 1 end - pass = password "Enter your password please:", '*' + pass = password "Enter your vmpooler password please:", '*' begin token = Auth.get_token(verbose, url, user, pass) rescue TokenError => e @@ -479,7 +479,7 @@ class Vmfloaty case action when "get" - pass = password "Enter your password please:", '*' + pass = password "Enter your vmpooler password please:", '*' begin token = Auth.get_token(verbose, url, user, pass) rescue TokenError => e @@ -489,7 +489,7 @@ class Vmfloaty puts token exit 0 when "delete" - pass = password "Enter your password please:", '*' + pass = password "Enter your vmpooler password please:", '*' begin result = Auth.delete_token(verbose, url, user, pass, token) rescue TokenError => e @@ -545,7 +545,7 @@ class Vmfloaty STDERR.puts "You did not provide a user to authenticate to vmpooler with" exit 1 end - pass = password "Enter your password please:", '*' + pass = password "Enter your vmpooler password please:", '*' begin token = Auth.get_token(verbose, url, user, pass) rescue TokenError => e From 6d57a1b5df8448a66cacfce24d9209318c175e6a Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Wed, 26 Jul 2017 15:01:53 -0700 Subject: [PATCH 013/265] Add basic bash completion script and framework for others --- README.md | 16 ++++++++++++++++ extras/completions/floaty.bash | 30 ++++++++++++++++++++++++++++++ lib/vmfloaty.rb | 26 ++++++++++++++++++++++++++ lib/vmfloaty/utils.rb | 8 ++++++++ vmfloaty.gemspec | 2 +- 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 extras/completions/floaty.bash diff --git a/README.md b/README.md index 60d5629..5b7eb47 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,22 @@ Here are the keys that vmfloaty currently supports: - url + String +### Tab Completion + +There is a basic completion script for Bash (and possibly other shells) included with the gem in the [extras/completions](https://github.com/briancain/vmfloaty/blob/master/extras/completions) folder. To activate, that file simply needs to be sourced somehow in your shell profile. + +For convenience, the path to the completion script for the currently active version of the gem can be found with the `floaty completion` subcommand. This makes it easy to add the completion script to your profile like so: + +```bash +source $(floaty completion --shell bash) +``` + +If you are running on macOS and use Homebrew's `bash-completion` formula, you can symlink the script to `/usr/local/etc/bash_completion.d/floaty` and it will be sourced automatically: + +```bash +ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty +``` + ## vmpooler API This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md). diff --git a/extras/completions/floaty.bash b/extras/completions/floaty.bash new file mode 100644 index 0000000..1d1e69d --- /dev/null +++ b/extras/completions/floaty.bash @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +_vmfloaty() +{ + local cur prev subcommands template_subcommands hostname_subcommands + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + subcommands="delete get help list modify query revert snapshot ssh status summary token" + template_subcommands="get ssh" + hostname_subcommands="delete modify query revert snapshot" + + if [[ $cur == -* ]] ; then + # TODO: option completion + COMPREPLY=() + elif [[ $template_subcommands =~ (^| )$prev($| ) ]] ; then + if [[ -z "$_vmfloaty_avail_templates" ]] ; then + _vmfloaty_avail_templates=$(floaty list 2>/dev/null) + fi + + COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") ) + elif [[ $hostname_subcommands =~ (^| )$prev($| ) ]] ; then + _vmfloaty_active_hostnames=$(floaty list --active 2>/dev/null | grep '^-' | cut -d' ' -f2) + COMPREPLY=( $(compgen -W "${_vmfloaty_active_hostnames}" -- "${cur}") ) + else + COMPREPLY=( $(compgen -W "${subcommands}" -- "${cur}") ) + fi +} +complete -F _vmfloaty floaty diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 80684ff..e0fbce4 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -562,6 +562,32 @@ class Vmfloaty end end + command :completion do |c| + c.syntax = 'floaty completion [options]' + c.summary = 'Outputs path to completion script' + c.description = Utils.strip_heredoc(<<-EOF) + Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile: + + source $(floaty completion --shell bash) + + This subcommand will exit non-zero with an error message if no completion script is available for the requested shell. + EOF + c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash' + c.option '--shell STRING', String, 'Shell to request completion script for' + c.action do |args, options| + shell = (options.shell || 'bash').downcase.strip + completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__) + + if File.exist?(completion_file) + puts completion_file + exit 0 + else + STDERR.puts "Could not find completion file for '#{shell}': No such file #{completion_file}" + exit 1 + end + end + end + run! end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index e4263c1..31c6fd0 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -113,4 +113,12 @@ class Utils puts puts message.colorize(status['status']['ok'] ? :default : :red) end + + # Adapted from ActiveSupport + def self.strip_heredoc(str) + min_indent = str.scan(/^[ \t]*(?=\S)/).min + min_indent_size = min_indent.nil? ? 0 : min_indent.size + + str.gsub(/^[ \t]{#{min_indent_size}}/, '') + end end diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 52820b6..c309653 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.summary = 'CLI application to interface with vmpooler' s.executables = ['floaty'] - s.files = Dir['LICENSE', 'README.md', 'lib/**/*'] + s.files = Dir['LICENSE', 'README.md', 'lib/**/*', 'extras/**/*'] s.test_files = Dir['spec/**/*'] s.require_path = 'lib' From b670596f5769d3ce42bfb4fe8c76482d6083dcec Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 31 Jul 2017 08:04:40 -0700 Subject: [PATCH 014/265] Update to 0.7.9 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 9e40ace..96d5473 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,3 +1,3 @@ class Vmfloaty - VERSION = '0.7.8'.freeze + VERSION = '0.7.9'.freeze end From ed82c44af55ad0ed46f54bb8844ce830620f3b5a Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 17 Aug 2017 13:49:03 -0700 Subject: [PATCH 015/265] Update email --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index c309653..0ccc715 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = 'vmfloaty' s.version = Vmfloaty::VERSION s.authors = ['Brian Cain'] - s.email = ['brian.cain@puppetlabs.com'] + s.email = ['brianccain@gmail.com'] s.license = 'Apache-2.0' s.homepage = 'https://github.com/briancain/vmfloaty' s.description = 'A helper tool for vmpooler to help you stay afloat' From 7fe2cdc42d71bed811ee8a104f7cced47390593d Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 21 Sep 2017 13:18:04 -0700 Subject: [PATCH 016/265] Add issue template --- .github/PULL_REQUEST_TEMPLATE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE new file mode 100644 index 0000000..2bc3c92 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE @@ -0,0 +1,21 @@ +## Status + +[Ready for Merge | In Progress | ???] + +## Description + +FIXME + +## Related Issues + +- + +## Todos + +- [ ] Tests +- [ ] Documentation + +## Reviewers + +@demophoon +@briancain From e7fcb7c7d53d562a531f8f3707794a7a934263ae Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 21 Sep 2017 13:18:48 -0700 Subject: [PATCH 017/265] Update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5b7eb47..9c3269e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ A CLI helper tool for [Puppet Labs vmpooler](https://github.com/puppetlabs/vmpoo +This project is still supported by @briancain and @demophoon. Ping either of us if you'd like something merged and released. + ## Install Grab the latest from ruby gems... From e78bcc621632272442c01f6e382d5febee6ab7a1 Mon Sep 17 00:00:00 2001 From: Casey Williams Date: Sun, 17 Sep 2017 20:23:11 -0700 Subject: [PATCH 018/265] Allow configuration of multiple services --- README.md | 40 +++++++++- lib/vmfloaty.rb | 148 +++++++++++++++++++++--------------- lib/vmfloaty/utils.rb | 31 ++++++++ spec/vmfloaty/utils_spec.rb | 51 +++++++++++++ 4 files changed, 206 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 5b7eb47..849cb86 100644 --- a/README.md +++ b/README.md @@ -66,8 +66,10 @@ floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring If you do not wish to continuely specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example: +#### Basic configuration + ```yaml -#file at /Users/me/.vmfloaty.yml +# file at /Users/me/.vmfloaty.yml url: 'https://vmpooler.mycompany.net/api/v1' user: 'brian' token: 'tokenstring' @@ -75,6 +77,40 @@ token: 'tokenstring' Now vmfloaty will use those config files if no flag was specified. +#### Configuring multiple services + +Most commands allow you to specify a `--service ` option to allow the use of multiple vmpooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services. + +To configure multiple services, you can set up your `~/.vmfloaty.yml` config file like this: + +```yaml +# file at /Users/me/.vmfloaty.yml +user: 'brian' +services: + main: + url: 'https://vmpooler.mycompany.net/api/v1' + token: 'tokenstring' + alternate: + url: 'https://vmpooler.alternate.net/api/v1' + token: 'alternate-tokenstring' +``` + +vmfloaty will now use the top-level keys (just "user" above) as default values, and you will be able to specify a service name with `--service` when you run floaty. If you don't specify a service name, vmfloaty will first try to use the default, top-level values. If there is no default URL or token specified in the config file, vmfloaty will then use the first configured service as the default. + +Examples using the above configuration: + +List available vm types from our main vmpooler instance: +```sh +floaty list --service main --active +# or, since the first configured service is the default: +floaty list --active +``` + +List available vm types from our alternate vmpooler instance: +```sh +floaty list --service alternate --active +``` + #### Valid config keys Here are the keys that vmfloaty currently supports: @@ -87,6 +123,8 @@ Here are the keys that vmfloaty currently supports: + String - url + String +- services + + Map ### Tab Completion diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index e0fbce4..c4e985a 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -17,26 +17,28 @@ class Vmfloaty def run program :version, Vmfloaty::VERSION - program :description, 'A CLI helper tool for Puppet Labs vmpooler to help you stay afloat' + program :description, 'A CLI helper tool for Puppet Labs VM poolers to help you stay afloat' config = Conf.read_config command :get do |c| c.syntax = 'floaty get os_type0 os_type1=x ox_type2=y [options]' c.summary = 'Gets a vm or vms based on the os argument' - c.description = 'A command to retrieve vms from vmpooler. Can either be a single vm, or multiple with the `=` syntax.' + c.description = 'A command to retrieve vms from a pooler service. Can either be a single vm, or multiple with the `=` syntax.' c.example 'Gets a few vms', 'floaty get centos=3 debian --user brian --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' + c.option '--service STRING', String, 'Configured pooler service name' c.option '--user STRING', String, 'User to authenticate with' - c.option '--url STRING', String, 'URL of vmpooler' - c.option '--token STRING', String, 'Token for vmpooler' + c.option '--url STRING', String, 'URL of pooler service' + c.option '--token STRING', String, 'Token for pooler service' c.option '--notoken', 'Makes a request without a token' c.option '--force', 'Forces vmfloaty to get requested vms' c.action do |args, options| verbose = options.verbose || config['verbose'] - token = options.token || config['token'] - user = options.user ||= config['user'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + token = options.token || service_config['token'] || config['token'] + user = options.user ||= service_config['user'] || config['user'] + url = options.url ||= service_config['url'] || config['url'] no_token = options.notoken force = options.force @@ -72,10 +74,10 @@ class Vmfloaty unless token puts "No token found. Retrieving a token..." if !user - STDERR.puts "You did not provide a user to authenticate to vmpooler with" + STDERR.puts "You did not provide a user to authenticate to the pooler service with" exit 1 end - pass = password "Enter your vmpooler password please:", '*' + pass = password "Enter your pooler service password please:", '*' begin token = Auth.get_token(verbose, url, user, pass) rescue TokenError => e @@ -109,17 +111,19 @@ class Vmfloaty command :list do |c| c.syntax = 'floaty list [options]' c.summary = 'Shows a list of available vms from the pooler or vms obtained with a token' - c.description = 'List will either show all vm templates available in vmpooler, or with the --active flag it will list vms obtained with a vmpooler token.' + c.description = 'List will either show all vm templates available in pooler service, or with the --active flag it will list vms obtained with a pooler service token.' c.example 'Filter the list on centos', 'floaty list centos --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' + c.option '--service STRING', String, 'Configured pooler service name' c.option '--active', 'Prints information about active vms for a given token' - c.option '--token STRING', String, 'Token for vmpooler' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--token STRING', String, 'Token for pooler service' + c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] + service_config = Utils.get_service_from_config(config, options.service) filter = args[0] - url = options.url ||= config['url'] - token = options.token || config['token'] + url = options.url ||= service_config['url'] ||=config['url'] + token = options.token || service_config['token'] || config['token'] active = options.active if active @@ -148,13 +152,15 @@ class Vmfloaty command :query do |c| c.syntax = 'floaty query hostname [options]' c.summary = 'Get information about a given vm' - c.description = 'Given a hostname from vmpooler, vmfloaty with query vmpooler to get various details about the vm.' + c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm.' c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] hostname = args[0] query_req = Pooler.query(verbose, url, hostname) @@ -165,23 +171,25 @@ class Vmfloaty command :modify do |c| c.syntax = 'floaty modify hostname [options]' c.summary = 'Modify a vms tags, time to live, and disk space' - c.description = 'This command makes modifications to the virtual machines state in vmpooler. You can either append tags to the vm, increase how long it stays active for, or increase the amount of disk space.' + 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.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' - c.option '--token STRING', String, 'Token for vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' + c.option '--token STRING', String, 'Token for pooler service' c.option '--lifetime INT', Integer, 'VM TTL (Integer, in hours)' c.option '--disk INT', Integer, 'Increases VM disk space (Integer, in gb)' c.option '--tags STRING', String, 'free-form VM tagging (json)' c.option '--all', 'Modifies all vms acquired by a token' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] hostname = args[0] lifetime = options.lifetime disk = options.disk tags = JSON.parse(options.tags) if options.tags - token = options.token || config['token'] + token = options.token || service_config['token'] || config['token'] modify_all = options.all running_vms = nil @@ -289,18 +297,20 @@ class Vmfloaty command :delete do |c| c.syntax = 'floaty delete hostname,hostname2 [options]' c.summary = 'Schedules the deletion of a host or hosts' - c.description = 'Given a comma separated list of hostnames, or --all for all vms, vmfloaty makes a request to vmpooler to schedule the deletion of those vms.' + c.description = 'Given a comma separated list of hostnames, or --all for all vms, vmfloaty makes a request to the pooler service to schedule the deletion of those vms.' c.example 'Schedules the deletion of a host or hosts', 'floaty delete myhost1,myhost2 --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' + c.option '--service STRING', String, 'Configured pooler service name' c.option '--all', 'Deletes all vms acquired by a token' c.option '-f', 'Does not prompt user when deleting all vms' - c.option '--token STRING', String, 'Token for vmpooler' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--token STRING', String, 'Token for pooler service' + c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] + service_config = Utils.get_service_from_config(config, options.service) hostnames = args[0] - token = options.token || config['token'] - url = options.url ||= config['url'] + token = options.token || service_config['token'] || config['token'] + url = options.url ||= service_config['url'] ||= config['url'] delete_all = options.all force = options.f @@ -355,7 +365,7 @@ class Vmfloaty exit 1 end - puts "Schedulered vmpooler to delete vms #{hosts}." + puts "Scheduled pooler service to delete vms #{hosts}." exit 0 end end @@ -364,16 +374,18 @@ class Vmfloaty command :snapshot do |c| 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 vmpooler. This command is known to take a while depending on how much load is on vmpooler.' + 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.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' - c.option '--token STRING', String, 'Token for vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' + c.option '--token STRING', String, 'Token for pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] hostname = args[0] - token = options.token ||= config['token'] + token = options.token ||= service_config['token'] ||= config['token'] begin snapshot_req = Pooler.snapshot(verbose, url, hostname, token) @@ -390,17 +402,19 @@ class Vmfloaty command :revert do |c| 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 vmpooler to go back to a previous 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.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' - c.option '--token STRING', String, 'Token for vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' + c.option '--token STRING', String, 'Token for pooler service' c.option '--snapshot STRING', String, 'SHA of snapshot' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] hostname = args[0] - token = options.token || config['token'] + token = options.token || service_config['token'] || config['token'] snapshot_sha = args[1] || options.snapshot if args[1] && options.snapshot @@ -420,15 +434,17 @@ class Vmfloaty command :status do |c| c.syntax = 'floaty status [options]' - c.summary = 'Prints the status of pools in vmpooler' - c.description = 'Makes a request to vmpooler to request the information about vm pools and how many are ready to be used, what pools are empty, etc.' - c.example 'Gets the current vmpooler status', 'floaty status --url http://vmpooler.example.com' + c.summary = 'Prints the status of pools in the pooler service' + c.description = 'Makes a request to the pooler service to request the information about vm pools and how many are ready to be used, what pools are empty, etc.' + c.example 'Gets the current pooler service status', 'floaty status --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' c.option '--json', 'Prints status in JSON format' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] status = Pooler.status(verbose, url) message = status['status']['message'] @@ -446,14 +462,16 @@ class Vmfloaty command :summary do |c| c.syntax = 'floaty summary [options]' - c.summary = 'Prints a summary of vmpooler' - c.description = 'Gives a very detailed summary of information related to vmpooler.' - c.example 'Gets the current day summary of vmpooler', 'floaty summary --url http://vmpooler.example.com' + c.summary = 'Prints a summary of a pooler service' + c.description = 'Gives a very detailed summary of information related to the pooler service.' + c.example 'Gets the current day summary of the pooler service', 'floaty summary --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] summary = Pooler.summary(verbose, url) pp summary @@ -464,22 +482,24 @@ class Vmfloaty command :token do |c| c.syntax = 'floaty token [options]' c.summary = 'Retrieves or deletes a token or checks token status' - c.description = 'This command is used to manage your vmpooler token. Through the various options, you are able to get a new token, delete an existing token, and request a tokens status.' + c.description = 'This command is used to manage your pooler service token. Through the various options, you are able to get a new token, delete an existing token, and request a tokens status.' c.example 'Gets a token from the pooler', 'floaty token get' c.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' c.option '--user STRING', String, 'User to authenticate with' - c.option '--token STRING', String, 'Token for vmpooler' + c.option '--token STRING', String, 'Token for pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] + service_config = Utils.get_service_from_config(config, options.service) action = args.first - url = options.url ||= config['url'] - token = args[1] ||= options.token ||= config['token'] - user = options.user ||= config['user'] + url = options.url ||= service_config['url'] ||= config['url'] + token = args[1] ||= options.token ||= service_config['token'] ||= config['token'] + user = options.user ||= service_config['user'] ||= config['user'] case action when "get" - pass = password "Enter your vmpooler password please:", '*' + pass = password "Enter your pooler service password please:", '*' begin token = Auth.get_token(verbose, url, user, pass) rescue TokenError => e @@ -489,7 +509,7 @@ class Vmfloaty puts token exit 0 when "delete" - pass = password "Enter your vmpooler password please:", '*' + pass = password "Enter your pooler service password please:", '*' begin result = Auth.delete_token(verbose, url, user, pass, token) rescue TokenError => e @@ -521,15 +541,17 @@ class Vmfloaty c.description = 'This command simply will grab a vm template that was requested, and then ssh the user into the machine all at once.' c.example 'SSHs into a centos vm', 'floaty ssh centos7 --url https://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' - c.option '--url STRING', String, 'URL of vmpooler' + c.option '--service STRING', String, 'Configured pooler service name' + c.option '--url STRING', String, 'URL of pooler service' c.option '--user STRING', String, 'User to authenticate with' - c.option '--token STRING', String, 'Token for vmpooler' + c.option '--token STRING', String, 'Token for pooler service' c.option '--notoken', 'Makes a request without a token' c.action do |args, options| verbose = options.verbose || config['verbose'] - url = options.url ||= config['url'] - token = options.token ||= config['token'] - user = options.user ||= config['user'] + service_config = Utils.get_service_from_config(config, options.service) + url = options.url ||= service_config['url'] ||= config['url'] + token = options.token ||= service_config['token'] ||= config['token'] + user = options.user ||= service_config['user'] ||= config['user'] no_token = options.notoken if args.empty? @@ -542,10 +564,10 @@ class Vmfloaty if !no_token && !token puts "No token found. Retrieving a token..." if !user - STDERR.puts "You did not provide a user to authenticate to vmpooler with" + STDERR.puts "You did not provide a user to authenticate to the pooler service with" exit 1 end - pass = password "Enter your vmpooler password please:", '*' + pass = password "Enter your pooler service password please:", '*' begin token = Auth.get_token(verbose, url, user, pass) rescue TokenError => e diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 31c6fd0..93ad7e0 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -121,4 +121,35 @@ class Utils str.gsub(/^[ \t]{#{min_indent_size}}/, '') end + + def self.get_service_from_config(config, service_name = '') + # The top-level url, user, and token values are treated as defaults + service = { + 'url' => config['url'], + 'user' => config['user'], + 'token' => config['token'] + } + + # If no named services have been configured, use the default values + return service unless config['services'] and config['services'].length + + if not service_name.empty? + if config['services'][service_name] + # If the user specified a configured service name, use that service + # If values are missing, use the top-level defaults + service.merge!(config['services'][service_name]) { |key, default, value| value } + else + STDERR.puts "WARNING: Could not find a configured service matching the name #{service_name} at #{Dir.home}/.vmfloaty.yml" + return {} + end + else + # Otherwise, use the first service configured under the 'services' key + # If values are missing, use the top-level defaults + name, config_hash = config['services'].first + service.merge!(config_hash) { |key, default, value| value } + end + + service + end + end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index c30d378..ed8b0b2 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -16,6 +16,57 @@ describe Utils do end end + describe "#get_service_from_config" do + before :each do + @default_config = { + "url" => "http://default.url", + "user" => "first.last.default", + "token" => "default-token", + } + @services_config = { + "services" => { + "vm" => { + "url" => "http://vmpooler.url", + "user" => "first.last.vmpooler", + "token" => "vmpooler-token" + }, + "ns" => { + "url" => "http://nspooler.url", + "user" => "first.last.nspooler", + "token" => "nspooler-token" + } + } + } + end + + it "returns the first service configured under 'services' as the default if available" do + config = @default_config.merge @services_config + expect(Utils.get_service_from_config(config)).to include @services_config['services']['vm'] + end + + it "uses top-level service config values as defaults when service values are missing" do + config = {"services" => { "vm" => {}}} + config.merge! @default_config + expect(Utils.get_service_from_config(config, 'vm')).to include @default_config + end + + it "allows selection by configured service key" do + config = @default_config.merge @services_config + expect(Utils.get_service_from_config(config, 'ns')).to include @services_config['services']['ns'] + end + + it "fills in missing values in configured services with the defaults" do + config = @default_config.merge @services_config + config["services"]['vm'].delete 'url' + expect(Utils.get_service_from_config(config, 'vm')['url']).to eq 'http://default.url' + end + + it "returns an empty hash if passed a service name that hasn't been configured" do + config = @default_config.merge @services_config + expect(Utils.get_service_from_config(config, 'nil')).to eq({}) + end + end + describe "#generate_os_hash" do before :each do @host_hash = {"centos"=>1, "debian"=>5, "windows"=>1} From ca5b0f5e8bd06357c19d750c0e488adcf873d6a0 Mon Sep 17 00:00:00 2001 From: Casey Williams Date: Tue, 19 Sep 2017 12:08:09 -0700 Subject: [PATCH 019/265] Integrate nonstandard pooler service into vmfloaty --- README.md | 36 +- lib/vmfloaty.rb | 450 ++++++++--------------- lib/vmfloaty/errors.rb | 6 + lib/vmfloaty/nonstandard_pooler.rb | 135 +++++++ lib/vmfloaty/pooler.rb | 28 +- lib/vmfloaty/service.rb | 133 +++++++ lib/vmfloaty/utils.rb | 259 ++++++++----- spec/spec_helper.rb | 7 + spec/vmfloaty/nonstandard_pooler_spec.rb | 325 ++++++++++++++++ spec/vmfloaty/pooler_spec.rb | 7 +- spec/vmfloaty/service_spec.rb | 79 ++++ spec/vmfloaty/utils_spec.rb | 207 +++++++---- 12 files changed, 1190 insertions(+), 482 deletions(-) create mode 100644 lib/vmfloaty/nonstandard_pooler.rb create mode 100644 lib/vmfloaty/service.rb create mode 100644 spec/vmfloaty/nonstandard_pooler_spec.rb create mode 100644 spec/vmfloaty/service_spec.rb diff --git a/README.md b/README.md index 849cb86..283954f 100644 --- a/README.md +++ b/README.md @@ -95,20 +95,46 @@ services: token: 'alternate-tokenstring' ``` -vmfloaty will now use the top-level keys (just "user" above) as default values, and you will be able to specify a service name with `--service` when you run floaty. If you don't specify a service name, vmfloaty will first try to use the default, top-level values. If there is no default URL or token specified in the config file, vmfloaty will then use the first configured service as the default. +- If you run `floaty` without a `--service ` option, vmfloaty will use the first configured service by default. + With the config file above, the default would be to use the 'main' vmpooler instance. +- If keys are missing for a configured service, vmfloaty will attempt to fall back to the top-level values. + With the config file above, 'brian' will be used as the username for both configured services, since neither specifies a username. Examples using the above configuration: List available vm types from our main vmpooler instance: ```sh -floaty list --service main --active -# or, since the first configured service is the default: -floaty list --active +floaty list --service main +# or, since the first configured service is used by default: +floaty list ``` List available vm types from our alternate vmpooler instance: ```sh -floaty list --service alternate --active +floaty list --service alternate +``` + +#### Using a Nonstandard Pooler service + +vmfloaty is capable of working with Puppet's [nonstandard pooler](https://github.com/puppetlabs/nspooler) in addition to the default vmpooler API. To add a nonstandard pooler service, specify an API `type` value in your service configuration, like this: + +```yaml +# file at /Users/me/.vmfloaty.yml +user: 'brian' +services: + vm: + url: 'https://vmpooler.mycompany.net/api/v1' + token: 'tokenstring' + ns: + url: 'https://nspooler.mycompany.net/api/v1' + token: 'nspooler-tokenstring' + type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service +``` + +With this configuration, you could list available OS types from nspooler like this: + +```sh +floaty list --service ns ``` #### Valid config keys diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index c4e985a..5056d4f 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -5,11 +5,13 @@ require 'commander' require 'colorize' require 'json' require 'pp' +require 'uri' require 'vmfloaty/auth' require 'vmfloaty/pooler' require 'vmfloaty/version' require 'vmfloaty/conf' require 'vmfloaty/utils' +require 'vmfloaty/service' require 'vmfloaty/ssh' class Vmfloaty @@ -35,11 +37,8 @@ class Vmfloaty c.option '--force', 'Forces vmfloaty to get requested vms' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - token = options.token || service_config['token'] || config['token'] - user = options.user ||= service_config['user'] || config['user'] - url = options.url ||= service_config['url'] || config['url'] - no_token = options.notoken + service = Service.new(options, config) + use_token = !options.notoken force = options.force if args.empty? @@ -50,61 +49,20 @@ class Vmfloaty os_types = Utils.generate_os_hash(args) max_pool_request = 5 - large_pool_requests = os_types.select{|k,v| v > max_pool_request} + large_pool_requests = os_types.select{|_,v| v > max_pool_request} if ! large_pool_requests.empty? and ! force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts "Try again with `floaty get --force`" exit 1 end - unless os_types.empty? - if no_token - begin - response = Pooler.retrieve(verbose, os_types, nil, url) - rescue MissingParamError - STDERR.puts e - STDERR.puts "See `floaty get --help` for more information on how to get VMs." - rescue AuthError => e - STDERR.puts e - exit 1 - end - puts Utils.format_hosts(response) - exit 0 - else - unless token - puts "No token found. Retrieving a token..." - if !user - STDERR.puts "You did not provide a user to authenticate to the pooler service with" - exit 1 - end - pass = password "Enter your pooler service password please:", '*' - begin - token = Auth.get_token(verbose, url, user, pass) - rescue TokenError => e - STDERR.puts e - exit 1 - end - - puts "\nToken retrieved!" - puts token - end - - begin - response = Pooler.retrieve(verbose, os_types, token, url) - rescue MissingParamError - STDERR.puts e - STDERR.puts "See `floaty get --help` for more information on how to get VMs." - rescue AuthError => e - STDERR.puts e - exit 1 - end - puts Utils.format_hosts(response) - exit 0 - end - else + if os_types.empty? STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs." exit 1 end + + response = service.retrieve(verbose, os_types, use_token) + puts Utils.format_hosts(response) end end @@ -120,30 +78,22 @@ class Vmfloaty c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) + service = Service.new(options, config) filter = args[0] - url = options.url ||= service_config['url'] ||=config['url'] - token = options.token || service_config['token'] || config['token'] - active = options.active - if active + if options.active # list active vms - begin - running_vms = Utils.get_all_token_vms(verbose, url, token) - rescue TokenError => e - STDERR.puts e - exit 1 - rescue Exception => e - STDERR.puts e - exit 1 - end - - if ! running_vms.nil? - Utils.prettyprint_hosts(running_vms, verbose, url) + running_vms = service.list_active(verbose) + host = URI.parse(service.url).host + if running_vms.empty? + puts "You have no running VMs on #{host}" + else + puts "Your VMs on #{host}:" + Utils.pretty_print_hosts(verbose, service, running_vms) end else # list available vms from pooler - os_list = Pooler.list(verbose, url, filter) + os_list = service.list(verbose, filter) puts os_list end end @@ -159,136 +109,67 @@ class Vmfloaty c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] + service = Service.new(options, config) hostname = args[0] - query_req = Pooler.query(verbose, url, hostname) + query_req = service.query(verbose, hostname) pp query_req end end command :modify do |c| c.syntax = 'floaty modify hostname [options]' - c.summary = 'Modify a vms tags, time to live, and disk space' + 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.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' c.option '--token STRING', String, 'Token for pooler service' - c.option '--lifetime INT', Integer, 'VM TTL (Integer, in hours)' - c.option '--disk INT', Integer, 'Increases VM disk space (Integer, in gb)' - c.option '--tags STRING', String, 'free-form VM tagging (json)' + c.option '--lifetime INT', Integer, 'VM TTL (Integer, in hours) [vmpooler only]' + c.option '--disk INT', Integer, 'Increases VM disk space (Integer, in gb) [vmpooler only]' + c.option '--tags STRING', String, 'free-form VM tagging (json) [vmpooler only]' + c.option '--reason STRING', String, 'VM reservation reason [nspooler only]' c.option '--all', 'Modifies all vms acquired by a token' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] + service = Service.new(options, config) hostname = args[0] - lifetime = options.lifetime - disk = options.disk - tags = JSON.parse(options.tags) if options.tags - token = options.token || service_config['token'] || config['token'] modify_all = options.all - running_vms = nil - - if modify_all - begin - running_vms = Utils.get_all_token_vms(verbose, url, token) - rescue Exception => e - STDERR.puts e - end - elsif hostname.include? "," - running_vms = hostname.split(",") + if hostname.nil? and !modify_all + STDERR.puts "ERROR: Provide a hostname or specify --all." + exit 1 end + running_vms = modify_all ? service.list_active(verbose) : hostname.split(",") - if lifetime || tags - # all vms - if !running_vms.nil? + tags = options.tags ? JSON.parse(options.tags) : nil + modify_hash = { + lifetime: options.lifetime, + disk: options.disk, + tags: tags, + reason: options.reason + } + modify_hash.delete_if { |_, value| value.nil? } + + unless modify_hash.empty? + ok = true + modified_hash = {} + running_vms.each do |vm| begin - modify_hash = {} - modify_flag = true - - running_vms.each do |vm| - modify_hash[vm] = Pooler.modify(verbose, url, vm, token, lifetime, tags) - end - - modify_hash.each do |hostname,status| - if status == false - STDERR.puts "Could not modify #{hostname}." - modify_flag = false - end - end - - if modify_flag - puts "Successfully modified all vms. Use `floaty list --active` to see the results." - end - rescue Exception => e + modified_hash[vm] = service.modify(verbose, vm, modify_hash) + rescue ModifyError => e STDERR.puts e - exit 1 - end - else - # Single Vm - begin - modify_req = Pooler.modify(verbose, url, hostname, token, lifetime, tags) - rescue TokenError => e - STDERR.puts e - exit 1 - end - - if modify_req["ok"] - puts "Successfully modified vm #{hostname}." - else - STDERR.puts "Could not modify given host #{hostname} at #{url}." - puts modify_req - exit 1 + ok = false end end - end - - if disk - # all vms - if !running_vms.nil? - begin - modify_hash = {} - modify_flag = true - - running_vms.each do |vm| - modify_hash[vm] = Pooler.disk(verbose, url, vm, token, disk) - end - - modify_hash.each do |hostname,status| - if status == false - STDERR.puts "Could not update disk space on #{hostname}." - modify_flag = false - end - end - - if modify_flag - puts "Successfully made request to update disk space on all vms." - end - rescue Exception => e - STDERR.puts e - exit 1 - end - else - # single vm - begin - disk_req = Pooler.disk(verbose, url, hostname, token, disk) - rescue TokenError => e - STDERR.puts e - exit 1 - end - - if disk_req["ok"] - puts "Successfully made request to update disk space of vm #{hostname}." + if ok + if modify_all + puts "Successfully modified all VMs." else - STDERR.puts "Could not modify given host #{hostname} at #{url}." - puts disk_req - exit 1 + puts "Successfully modified VM #{hostname}." end + puts "Use `floaty list --active` to see the results." end end end @@ -307,67 +188,69 @@ class Vmfloaty c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) + service = Service.new(options, config) hostnames = args[0] - token = options.token || service_config['token'] || config['token'] - url = options.url ||= service_config['url'] ||= config['url'] delete_all = options.all force = options.f + failures = [] + successes = [] + if delete_all - # get vms with token - begin - running_vms = Utils.get_all_token_vms(verbose, url, token) - rescue TokenError => e - STDERR.puts e - exit 1 - rescue Exception => e - STDERR.puts e - exit 1 - end - - if ! running_vms.nil? - Utils.prettyprint_hosts(running_vms, verbose, url) - # query y/n + running_vms = service.list_active(verbose) + if running_vms.empty? + STDERR.puts "You have no running VMs." + else + Utils.pretty_print_hosts(verbose, service, running_vms) + # Confirm deletion puts - - if force - ans = true - else - ans = agree("Delete all VMs associated with token #{token}? [y/N]") + confirmed = true + unless force + confirmed = agree('Delete all these VMs? [y/N]') end - - if ans - # delete vms - puts "Scheduling all vms for for deletion" - response = Pooler.delete(verbose, url, running_vms, token) - response.each do |host,vals| - if vals['ok'] == false - STDERR.puts "There was a problem with your request for vm #{host}." - STDERR.puts vals + if confirmed + response = service.delete(verbose, running_vms) + response.each do |hostname, result| + if result['ok'] + successes << hostname + else + failures << hostname end end end end - - exit 0 - end - - if hostnames.nil? + elsif hostnames || args + hostnames = hostnames.split(',') + results = service.delete(verbose, hostnames) + results.each do |hostname, result| + if result['ok'] + successes << hostname + else + failures << hostname + end + end + else STDERR.puts "You did not provide any hosts to delete" exit 1 - else - hosts = hostnames.split(',') - begin - Pooler.delete(verbose, url, hosts, token) - rescue TokenError => e - STDERR.puts e - exit 1 - end - - puts "Scheduled pooler service to delete vms #{hosts}." - exit 0 end + + unless failures.empty? + STDERR.puts 'Unable to delete the following VMs:' + failures.each do |hostname| + STDERR.puts "- #{hostname}" + end + STDERR.puts 'Check `floaty list --active`; Do you need to specify a different service?' + end + + unless successes.empty? + puts unless failures.empty? + puts 'Scheduled the following VMs for deletion:' + successes.each do |hostname| + puts "- #{hostname}" + end + end + + exit 1 unless failures.empty? end end @@ -382,14 +265,12 @@ class Vmfloaty c.option '--token STRING', String, 'Token for pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] + service = Service.new(options, config) hostname = args[0] - token = options.token ||= service_config['token'] ||= config['token'] begin - snapshot_req = Pooler.snapshot(verbose, url, hostname, token) - rescue TokenError => e + snapshot_req = service.snapshot(verbose, hostname) + rescue TokenError, ModifyError => e STDERR.puts e exit 1 end @@ -411,10 +292,8 @@ class Vmfloaty c.option '--snapshot STRING', String, 'SHA of snapshot' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] + service = Service.new(options, config) hostname = args[0] - token = options.token || service_config['token'] || config['token'] snapshot_sha = args[1] || options.snapshot if args[1] && options.snapshot @@ -422,8 +301,8 @@ class Vmfloaty end begin - revert_req = Pooler.revert(verbose, url, hostname, token, snapshot_sha) - rescue TokenError => e + revert_req = service.revert(verbose, hostname, snapshot_sha) + rescue TokenError, ModifyError => e STDERR.puts e exit 1 end @@ -441,22 +320,14 @@ class Vmfloaty c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' c.option '--json', 'Prints status in JSON format' - c.action do |args, options| + c.action do |_, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] - - status = Pooler.status(verbose, url) - message = status['status']['message'] - pools = status['pools'] - + service = Service.new(options, config) if options.json - pp status + pp service.status(verbose) else - Utils.prettyprint_status(status, message, pools, verbose) + Utils.pretty_print_status(verbose, service) end - - exit status['status']['ok'] end end @@ -468,12 +339,11 @@ class Vmfloaty c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' - c.action do |args, options| + c.action do |_, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] + service = Service.new(options, config) - summary = Pooler.summary(verbose, url) + summary = service.summary(verbose) pp summary exit 0 end @@ -491,47 +361,36 @@ class Vmfloaty c.option '--token STRING', String, 'Token for pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) + service = Service.new(options, config) action = args.first - url = options.url ||= service_config['url'] ||= config['url'] - token = args[1] ||= options.token ||= service_config['token'] ||= config['token'] - user = options.user ||= service_config['user'] ||= config['user'] - case action - when "get" - pass = password "Enter your pooler service password please:", '*' - begin - token = Auth.get_token(verbose, url, user, pass) - rescue TokenError => e - STDERR.puts e - exit 1 + begin + case action + when 'get' + token = service.get_new_token(verbose) + puts token + when 'delete' + result = service.delete_token(verbose, options.token) + puts result + when 'status' + token_value = options.token + if token_value.nil? + token_value = args[1] + end + status = service.token_status(verbose, token_value) + puts status + when nil + STDERR.puts 'No action provided' + exit 1 + else + STDERR.puts "Unknown action: #{action}" + exit 1 end - puts token - exit 0 - when "delete" - pass = password "Enter your pooler service password please:", '*' - begin - result = Auth.delete_token(verbose, url, user, pass, token) - rescue TokenError => e - STDERR.puts e - exit 1 - end - puts result - exit 0 - when "status" - begin - status = Auth.token_status(verbose, url, token) - rescue TokenError => e - STDERR.puts e - exit 1 - end - puts status - exit 0 - when nil - STDERR.puts "No action provided" - else - STDERR.puts "Unknown action: #{action}" + rescue TokenError => e + STDERR.puts e + exit 1 end + exit 0 end end @@ -548,11 +407,8 @@ class Vmfloaty c.option '--notoken', 'Makes a request without a token' c.action do |args, options| verbose = options.verbose || config['verbose'] - service_config = Utils.get_service_from_config(config, options.service) - url = options.url ||= service_config['url'] ||= config['url'] - token = options.token ||= service_config['token'] ||= config['token'] - user = options.user ||= service_config['user'] ||= config['user'] - no_token = options.notoken + service = Service.new(options, config) + use_token = !options.notoken if args.empty? STDERR.puts "No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs." @@ -561,25 +417,11 @@ class Vmfloaty host_os = args.first - if !no_token && !token - puts "No token found. Retrieving a token..." - if !user - STDERR.puts "You did not provide a user to authenticate to the pooler service with" - exit 1 - end - pass = password "Enter your pooler service password please:", '*' - begin - token = Auth.get_token(verbose, url, user, pass) - rescue TokenError => e - STDERR.puts e - STDERR.puts 'Could not get token...requesting vm without a token anyway...' - else - puts "\nToken retrieved!" - puts token - end + if args.length > 1 + STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." end - Ssh.ssh(verbose, host_os, token, url) + service.ssh(verbose, host_os, use_token) exit 0 end end @@ -596,7 +438,7 @@ class Vmfloaty EOF c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash' c.option '--shell STRING', String, 'Shell to request completion script for' - c.action do |args, options| + c.action do |_, options| shell = (options.shell || 'bash').downcase.strip completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__) diff --git a/lib/vmfloaty/errors.rb b/lib/vmfloaty/errors.rb index aa3b2b8..221fa14 100644 --- a/lib/vmfloaty/errors.rb +++ b/lib/vmfloaty/errors.rb @@ -15,3 +15,9 @@ class MissingParamError < StandardError super end end + +class ModifyError < StandardError + def initialize(msg="Could not modify VM") + super + end +end diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb new file mode 100644 index 0000000..7384db8 --- /dev/null +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -0,0 +1,135 @@ +require 'vmfloaty/errors' +require 'vmfloaty/http' +require 'faraday' +require 'json' + +class NonstandardPooler + def self.list(verbose, url, os_filter = nil) + conn = Http.get_conn(verbose, url) + + response = conn.get 'status' + response_body = JSON.parse(response.body) + os_list = response_body.keys.sort + os_list.delete 'ok' + + os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list + end + + def self.list_active(verbose, url, token) + status = Auth.token_status(verbose, url, token) + status['reserved_hosts'] || [] + end + + def self.retrieve(verbose, os_type, token, url) + conn = Http.get_conn(verbose, url) + conn.headers['X-AUTH-TOKEN'] = token if token + + os_string = '' + os_type.each do |os, num| + num.times do |_i| + os_string << os + '+' + end + end + + os_string = os_string.chomp('+') + + if os_string.empty? + raise MissingParamError, 'No operating systems provided to obtain.' + end + + response = conn.post "host/#{os_string}" + + res_body = JSON.parse(response.body) + + if res_body['ok'] + res_body + elsif response.status == 401 + raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" + else + raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/host/#{os_string}. #{res_body}" + end + end + + def self.modify(verbose, url, hostname, token, modify_hash) + if token.nil? + raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' + end + + modify_hash.each do |key, value| + unless [:reason, :reserved_for_reason].include? key + raise ModifyError, "Configured service type does not support modification of #{key}" + end + end + + if modify_hash[:reason] + # "reason" is easier to type than "reserved_for_reason", but nspooler needs the latter + modify_hash[:reserved_for_reason] = modify_hash.delete :reason + end + + conn = Http.get_conn(verbose, url) + conn.headers['X-AUTH-TOKEN'] = token + + response = conn.put do |req| + req.url "host/#{hostname}" + req.body = modify_hash.to_json + end + + response.body.empty? ? {} : JSON.parse(response.body) + end + + def self.disk(verbose, url, hostname, token, disk) + raise ModifyError, 'Configured service type does not support modification of disk space' + end + + def self.snapshot(verbose, url, hostname, token) + raise ModifyError, 'Configured service type does not support snapshots' + end + + def self.revert(verbose, url, hostname, token, snapshot_sha) + raise ModifyError, 'Configured service type does not support snapshots' + end + + def self.delete(verbose, url, hosts, token) + if token.nil? + raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' + end + + conn = Http.get_conn(verbose, url) + + conn.headers['X-AUTH-TOKEN'] = token if token + + response_body = {} + + unless hosts.is_a? Array + hosts = hosts.split(',') + end + hosts.each do |host| + response = conn.delete "host/#{host}" + res_body = JSON.parse(response.body) + response_body[host] = res_body + end + + response_body + end + + def self.status(verbose, url) + conn = Http.get_conn(verbose, url) + + response = conn.get '/status' + JSON.parse(response.body) + end + + def self.summary(verbose, url) + conn = Http.get_conn(verbose, url) + + response = conn.get '/summary' + JSON.parse(response.body) + end + + def self.query(verbose, url, hostname) + conn = Http.get_conn(verbose, url) + + response = conn.get "host/#{hostname}" + JSON.parse(response.body) + end +end diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 50820b0..e81b4cd 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -19,6 +19,15 @@ class Pooler hosts end + def self.list_active(verbose, url, token) + status = Auth.token_status(verbose, url, token) + vms = [] + if status[token] && status[token]['vms'] + vms = status[token]['vms']['running'] + end + vms + end + def self.retrieve(verbose, os_type, token, url) # NOTE: # Developers can use `Utils.generate_os_hash` to @@ -54,25 +63,28 @@ class Pooler end end - def self.modify(verbose, url, hostname, token, lifetime, tags) + def self.modify(verbose, url, hostname, token, modify_hash) if token.nil? raise TokenError, "Token provided was nil. Request cannot be made to modify vm" end - modify_body = {} - if lifetime - modify_body['lifetime'] = lifetime - end - if tags - modify_body['tags'] = tags + modify_hash.keys.each do |key| + unless [:tags, :lifetime, :disk].include? key + raise ModifyError, "Configured service type does not support modification of #{key}." + end end conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token + if modify_hash['disk'] + disk(verbose, url, hostname, token, modify_hash['disk']) + modify_hash.delete 'disk' + end + response = conn.put do |req| req.url "vm/#{hostname}" - req.body = modify_body.to_json + req.body = modify_hash.to_json end res_body = JSON.parse(response.body) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb new file mode 100644 index 0000000..b2a2333 --- /dev/null +++ b/lib/vmfloaty/service.rb @@ -0,0 +1,133 @@ +require 'commander/user_interaction' +require 'commander/command' +require 'vmfloaty/utils' +require 'vmfloaty/ssh' + +class Service + + attr_reader :config + + def initialize(options, config_hash = {}) + options ||= Commander::Command::Options.new + @config = Utils.get_service_config config_hash, options + @service_object = Utils.get_service_object @config['type'] + end + + def method_missing(m, *args, &block) + if @service_object.respond_to? m + @service_object.send(m, *args, &block) + else + super + end + end + + def url + @config['url'] + end + + def type + @service_object.name + end + + def user + unless @config['user'] + puts "Enter your pooler service username:" + @config['user'] = STDIN.gets.chomp + end + @config['user'] + end + + def token + unless @config['token'] + puts "No token found. Retrieving a token..." + @config['token'] = get_new_token(nil) + end + @config['token'] + end + + def get_new_token(verbose) + username = user + pass = Commander::UI::password "Enter your pooler service password:", '*' + Auth.get_token(verbose, url, username, pass) + end + + def delete_token(verbose, token_value = @config['token']) + username = user + pass = Commander::UI::password "Enter your pooler service password:", '*' + Auth.delete_token(verbose, url, username, pass, token_value) + end + + def token_status(verbose, token_value) + token_value ||= @config['token'] + Auth.token_status(verbose, url, token_value) + end + + def list(verbose, os_filter = nil) + @service_object.list verbose, url, os_filter + end + + def list_active(verbose) + @service_object.list_active verbose, url, token + end + + def retrieve(verbose, os_types, use_token = true) + puts 'Requesting a vm without a token...' unless use_token + token_value = use_token ? token : nil + @service_object.retrieve verbose, os_types, token_value, url + end + + def ssh(verbose, host_os, use_token = true) + token_value = nil + if use_token + begin + token_value = token || get_new_token(verbose) + rescue TokenError => e + STDERR.puts e + STDERR.puts 'Could not get token... requesting vm without a token anyway...' + end + end + Ssh.ssh(verbose, host_os, token_value, url) + end + + def pretty_print_running(verbose, hostnames = []) + if hostnames.empty? + puts "You have no running VMs." + else + puts "Running VMs:" + @service_object.pretty_print_hosts(verbose, hostnames, url) + end + end + + def query(verbose, hostname) + @service_object.query verbose, url, hostname + end + + def modify(verbose, hostname, modify_hash) + @service_object.modify verbose, url, hostname, token, modify_hash + end + + def delete(verbose, hosts) + @service_object.delete verbose, url, hosts, token + end + + def status(verbose) + @service_object.status verbose, url + end + + def summary(verbose) + @service_object.summary verbose, url + end + + def snapshot(verbose, hostname) + @service_object.snapshot verbose, url, hostname, token + end + + def revert(verbose, hostname, snapshot_sha) + @service_object.revert verbose, url, hostname, token, snapshot_sha + end + + def disk(verbose, hostname, disk) + @service_object.disk(verbose, url, hostname, token, disk) + end + +end \ No newline at end of file diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 93ad7e0..fe55511 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -1,27 +1,62 @@ - require 'vmfloaty/pooler' +require 'vmfloaty/nonstandard_pooler' class Utils # TODO: Takes the json response body from an HTTP GET # request and "pretty prints" it - def self.format_hosts(hostname_hash) - host_hash = {} + def self.format_hosts(response_body) + # vmpooler response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`: + # { + # "ok": true, + # "domain": "delivery.mycompany.net", + # "ubuntu-1610-x86_64": { + # "hostname": ["gdoy8q3nckuob0i", "ctnktsd0u11p9tm"] + # }, + # "centos-7-x86_64": { + # "hostname": "dlgietfmgeegry2" + # } + # } - hostname_hash.delete("ok") - domain = hostname_hash["domain"] - hostname_hash.each do |type, hosts| - if type != "domain" - if hosts["hostname"].kind_of?(Array) - hosts["hostname"].map!{|host| host + "." + domain } + # nonstandard pooler response body example when `floaty get` arguments are `solaris-11-sparc=2 ubuntu-16.04-power8`: + # { + # "ok": true, + # "solaris-10-sparc": { + # "hostname": ["sol10-10.delivery.mycompany.net", "sol10-11.delivery.mycompany.net"] + # }, + # "ubuntu-16.04-power8": { + # "hostname": "power8-ubuntu1604-6.delivery.mycompany.net" + # } + # } + + unless response_body.delete('ok') + raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" + end + + hostnames = [] + + # vmpooler reports the domain separately from the hostname + domain = response_body.delete('domain') + + if domain + # vmpooler output + response_body.each do |os, hosts| + if hosts['hostname'].kind_of?(Array) + hosts['hostname'].map!{ |host| hostnames << host + "." + domain + " (#{os})"} else - hosts["hostname"] = hosts["hostname"] + "." + domain + hostnames << hosts["hostname"] + ".#{domain} (#{os})" + end + end + else + response_body.each do |os, hosts| + if hosts['hostname'].kind_of?(Array) + hosts['hostname'].map!{ |host| hostnames << host + " (#{os})" } + else + hostnames << hosts['hostname'] + " (#{os})" end - - host_hash[type] = hosts["hostname"] end end - host_hash.to_json + hostnames.map { |hostname| puts "- #{hostname}" } end def self.generate_os_hash(os_args) @@ -46,72 +81,84 @@ class Utils os_types end - def self.get_vm_info(hosts, verbose, url) - vms = {} - hosts.each do |host| - vm_info = Pooler.query(verbose, url, host) - if vm_info['ok'] - vms[host] = {} - vms[host]['domain'] = vm_info[host]['domain'] - vms[host]['template'] = vm_info[host]['template'] - vms[host]['lifetime'] = vm_info[host]['lifetime'] - vms[host]['running'] = vm_info[host]['running'] - vms[host]['tags'] = vm_info[host]['tags'] - end - end - vms - end - - def self.prettyprint_hosts(hosts, verbose, url) - puts "Running VMs:" - vm_info = get_vm_info(hosts, verbose, url) - vm_info.each do |vm,info| - domain = info['domain'] - template = info['template'] - lifetime = info['lifetime'] - running = info['running'] - tags = info['tags'] || {} - - tag_pairs = tags.map {|key,value| "#{key}: #{value}" } - duration = "#{running}/#{lifetime} hours" - metadata = [template, duration, *tag_pairs] - - puts "- #{vm}.#{domain} (#{metadata.join(", ")})" - end - end - - def self.get_all_token_vms(verbose, url, token) - # get vms with token - status = Auth.token_status(verbose, url, token) - - vms = status[token]['vms'] - if vms.nil? - raise "You have no running vms" - end - - running_vms = vms['running'] - running_vms - end - - def self.prettyprint_status(status, message, pools, verbose) - pools.select! {|name,pool| pool['ready'] < pool['max']} if ! verbose - - width = pools.keys.map(&:length).max - pools.each do |name,pool| + def self.pretty_print_hosts(verbose, service, hostnames = []) + hostnames = [hostnames] unless hostnames.is_a? Array + hostnames.each do |hostname| 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}" + response = service.query(verbose, hostname) + host_data = response[hostname] + + case service.type + when 'Pooler' + tag_pairs = [] + unless host_data['tags'].nil? + tag_pairs = host_data['tags'].map {|key, value| "#{key}: #{value}"} + end + duration = "#{host_data['running']}/#{host_data['lifetime']} hours" + metadata = [host_data['template'], duration, *tag_pairs] + puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(", ")})" + when 'NonstandardPooler' + line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" + line += ", #{host_data['hours_left_on_reservation']}h remaining" + unless host_data['reserved_for_reason'].empty? + line += ", reason: #{host_data['reserved_for_reason']}" + end + line += ')' + puts line + else + raise "Invalid service type #{service.type}" + end rescue => e - puts "#{name.ljust(width)} #{e.red}" + STDERR.puts("Something went wrong while trying to gather information on #{hostname}:") + STDERR.puts(e) end end + end - puts - puts message.colorize(status['status']['ok'] ? :default : :red) + def self.pretty_print_status(verbose, service) + status_response = service.status(verbose) + + case service.type + when 'Pooler' + message = status_response['status']['message'] + pools = status_response['pools'] + pools.select! {|_, pool| pool['ready'] < pool['max']} unless verbose + + width = pools.keys.map(&:length).max + pools.each do |name, pool| + begin + max = pool['max'] + ready = pool['ready'] + pending = pool['pending'] + missing = max - ready - pending + char = 'o' + puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}" + rescue => e + puts "#{name.ljust(width)} #{e.red}" + end + end + puts message.colorize(status_response['status']['ok'] ? :default : :red) + when 'NonstandardPooler' + pools = status_response + pools.delete 'ok' + pools.select! {|_, pool| pool['available_hosts'] < pool['total_hosts']} unless verbose + + width = pools.keys.map(&:length).max + pools.each do |name, pool| + begin + max = pool['total_hosts'] + ready = pool['available_hosts'] + pending = pool['pending'] || 0 # not available for nspooler + missing = max - ready - pending + char = 'o' + puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}" + rescue => e + puts "#{name.ljust(width)} #{e.red}" + end + end + else + raise "Invalid service type #{service.type}" + end end # Adapted from ActiveSupport @@ -122,34 +169,46 @@ class Utils str.gsub(/^[ \t]{#{min_indent_size}}/, '') end - def self.get_service_from_config(config, service_name = '') - # The top-level url, user, and token values are treated as defaults - service = { - 'url' => config['url'], - 'user' => config['user'], - 'token' => config['token'] - } - - # If no named services have been configured, use the default values - return service unless config['services'] and config['services'].length - - if not service_name.empty? - if config['services'][service_name] - # If the user specified a configured service name, use that service - # If values are missing, use the top-level defaults - service.merge!(config['services'][service_name]) { |key, default, value| value } - else - STDERR.puts "WARNING: Could not find a configured service matching the name #{service_name} at #{Dir.home}/.vmfloaty.yml" - return {} - end + def self.get_service_object(type = '') + nspooler_strings = ['ns', 'nspooler', 'nonstandard', 'nonstandard_pooler'] + if nspooler_strings.include? type.downcase + NonstandardPooler else - # Otherwise, use the first service configured under the 'services' key - # If values are missing, use the top-level defaults - name, config_hash = config['services'].first - service.merge!(config_hash) { |key, default, value| value } + Pooler end - - service end + def self.get_service_config(config, options) + # The top-level url, user, and token values in the config file are treated as defaults + service_config = { + 'url' => config['url'], + 'user' => config['user'], + 'token' => config['token'], + 'type' => config['type'] || 'vmpooler' + } + + if config['services'] + if options.service.nil? + # If the user did not specify a service name at the command line, but configured services do exist, + # use the first configured service in the list by default. + _, values = config['services'].first + service_config.merge! values + else + # If the user provided a service name at the command line, use that service if posible, or fail + if config['services'][options.service] + # If the service is configured but some values are missing, use the top-level defaults to fill them in + service_config.merge! config['services'][options.service] + else + raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" + end + end + end + + # Prioritize an explicitly specified url, user, or token if the user provided one + service_config['url'] = options.url unless options.url.nil? + service_config['token'] = options.token unless options.token.nil? + service_config['user'] = options.user unless options.user.nil? + + service_config + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index decf5e7..982b1ed 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,13 @@ require 'vmfloaty' require 'webmock/rspec' +# Mock Commander Options object to allow pre-population with values +class MockOptions < Commander::Command::Options + def initialize(values = {}) + @table = values + end +end + RSpec.configure do |config| config.color = true config.tty = true diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb new file mode 100644 index 0000000..02ab9d9 --- /dev/null +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -0,0 +1,325 @@ +require 'spec_helper' +require 'vmfloaty/utils' +require 'vmfloaty/errors' +require 'vmfloaty/nonstandard_pooler' + +describe NonstandardPooler do + before :each do + @nspooler_url = 'https://nspooler.example.com' + @post_request_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' => 'token-value' + } + @get_request_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' => 'token-value' + } + @get_request_headers_notoken = @get_request_headers.tap do |headers| + headers.delete('X-Auth-Token') + end + + end + + describe '#list' do + before :each do + @status_response_body = <<-BODY +{ + "ok": true, + "solaris-10-sparc": { + "total_hosts": 11, + "available_hosts": 11 + }, + "ubuntu-16.04-power8": { + "total_hosts": 10, + "available_hosts": 10 + }, + "aix-7.2-power": { + "total_hosts": 5, + "available_hosts": 4 + } +} + BODY + end + + it 'returns an array with operating systems from the pooler' do + stub_request(:get, "#{@nspooler_url}/status") + .to_return(status: 200, body: @status_response_body, headers: {}) + + list = NonstandardPooler.list(false, @nspooler_url, nil) + expect(list).to be_an_instance_of Array + end + + 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: {}) + + list = NonstandardPooler.list(false, @nspooler_url, 'aix') + expect(list).to be_an_instance_of Array + expect(list.size).to equal 1 + end + + 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: {}) + + list = NonstandardPooler.list(false, @nspooler_url, 'windows') + expect(list).to be_an_instance_of Array + expect(list.size).to equal 0 + end + end + + describe '#list_active' do + before :each do + @token_status_body_active = <<-BODY +{ + "ok": true, + "user": "first.last", + "created": "2017-09-18 01:25:41 +0000", + "last_accessed": "2017-09-21 19:46:25 +0000", + "reserved_hosts": ["sol10-9", "sol10-11"] +} +BODY + @token_status_body_empty = <<-BODY +{ + "ok": true, + "user": "first.last", + "created": "2017-09-18 01:25:41 +0000", + "last_accessed": "2017-09-21 19:46:25 +0000", + "reserved_hosts": [] +} +BODY + end + + it 'prints an output of fqdn, template, and duration' do + allow(Auth).to receive(:token_status) + .with(false, @nspooler_url, 'token-value') + .and_return(JSON.parse(@token_status_body_active)) + + list = NonstandardPooler.list_active(false, @nspooler_url, 'token-value') + expect(list).to eql ['sol10-9', 'sol10-11'] + end + end + + describe '#retrieve' do + before :each do + @retrieve_response_body_single = <<-BODY +{ + "ok": true, + "solaris-11-sparc": { + "hostname": "sol11-4.delivery.puppetlabs.net" + } +} +BODY + @retrieve_response_body_many = <<-BODY +{ + "ok": true, + "solaris-10-sparc": { + "hostname": [ + "sol10-9.delivery.puppetlabs.net", + "sol10-10.delivery.puppetlabs.net" + ] + }, + "aix-7.1-power": { + "hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net" + } +} +BODY + end + + it 'raises an AuthError if the token is invalid' do + stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") + .with(headers: @post_request_headers) + .to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {}) + + vm_hash = { 'solaris-11-sparc' => 1 } + expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.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: @post_request_headers) + .to_return(status: 200, body: @retrieve_response_body_single, headers: {}) + + vm_hash = { 'solaris-11-sparc' => 1 } + vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) + expect(vm_req).to be_an_instance_of Hash + expect(vm_req['ok']).to equal true + expect(vm_req['solaris-11-sparc']['hostname']).to eq 'sol11-4.delivery.puppetlabs.net' + end + + it 'retrieves a multiple vms with a token' do + stub_request(:post,"#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc") + .with(headers: @post_request_headers) + .to_return(status: 200, body: @retrieve_response_body_many, headers: {}) + + vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 } + vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) + 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['aix-7.1-power']['hostname']).to eq 'pe-aix-71-ci-acceptance.delivery.puppetlabs.net' + end + end + + describe '#modify' do + before :each do + @modify_response_body_success = '{"ok":true}' + end + + it 'raises an error if the user tries to modify an unsupported attribute' do + stub_request(:put, "https://nspooler.example.com/host/myfakehost"). + with(body: {"{}"=>true}, + headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'token-value'}). + to_return(status: 200, body: "", headers: {}) + details = { lifetime: 12 } + expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } + .to raise_error(ModifyError) + end + + it 'modifies the reason of a vm' do + modify_request_body = { '{"reserved_for_reason":"testing"}' => true } + stub_request(:put, "#{@nspooler_url}/host/myfakehost") + .with(body: modify_request_body, + headers: @post_request_headers) + .to_return(status: 200, body: '{"ok": true}', headers: {}) + + modify_hash = { reason: "testing" } + modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash) + expect(modify_req['ok']).to be true + end + end + + describe '#status' 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."}}' + # TODO: make this report stuff like 'broken' + @status_response_body = <<-BODY +{ + "ok": true, + "solaris-10-sparc": { + "total_hosts": 11, + "available_hosts": 10 + }, + "ubuntu-16.04-power8": { + "total_hosts": 10, + "available_hosts": 10 + }, + "aix-7.2-power": { + "total_hosts": 5, + "available_hosts": 4 + } +} +BODY + end + + it 'prints the status' do + stub_request(:get, "#{@nspooler_url}/status") + .with(headers: @get_request_headers) + .to_return(status: 200, body: @status_response_body, headers: {}) + + status = NonstandardPooler.status(false, @nspooler_url) + expect(status).to be_an_instance_of Hash + end + end + + describe '#summary' do + before :each do + @status_response_body = <<-BODY +{ + "ok": true, + "total": 57, + "available": 39, + "in_use": 16, + "resetting": 2, + "broken": 0 +} +BODY + end + + it 'prints the summary' do + stub_request(:get, "#{@nspooler_url}/summary") + .with(headers: @get_request_headers) + .to_return(status: 200, body: @status_response_body, headers: {}) + + summary = NonstandardPooler.summary(false, @nspooler_url) + expect(summary).to be_an_instance_of Hash + end + end + + describe '#query' do + before :each do + @query_response_body = <<-BODY +{ + "ok": true, + "sol10-11": { + "fqdn": "sol10-11.delivery.puppetlabs.net", + "os_triple": "solaris-10-sparc", + "reserved_by_user": "first.last", + "reserved_for_reason": "testing", + "hours_left_on_reservation": 29.12 + } +} +BODY + end + + it 'makes a query about a vm' do + stub_request(:get, "#{@nspooler_url}/host/sol10-11") + .with(headers: @get_request_headers_notoken) + .to_return(status: 200, body: @query_response_body, headers: {}) + + query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11') + expect(query_req).to be_an_instance_of Hash + end + end + + describe '#delete' do + before :each do + @delete_response_success = '{"ok": true}' + @delete_response_failure = '{"ok": false, "failure": "ERROR: fakehost does not exist"}' + end + + it 'deletes a single existing vm' do + stub_request(:delete, "#{@nspooler_url}/host/sol11-7") + .with(headers: @post_request_headers) + .to_return(status: 200, body: @delete_response_success, headers: {}) + + request = NonstandardPooler.delete(false, @nspooler_url, 'sol11-7', 'token-value') + expect(request['sol11-7']['ok']).to be true + end + + it 'does not delete a nonexistant vm' do + stub_request(:delete, "#{@nspooler_url}/host/fakehost") + .with(headers: @post_request_headers) + .to_return(status: 401, body: @delete_response_failure, headers: {}) + + request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value') + expect(request['fakehost']['ok']).to be false + end + end + + describe '#snapshot' do + it 'logs an error explaining that snapshots are not supported' do + expect { NonstandardPooler.snapshot(false, @nspooler_url, 'myfakehost', 'token-value') } + .to raise_error(ModifyError) + end + end + + describe '#revert' do + it 'logs an error explaining that snapshots are not supported' do + expect { NonstandardPooler.revert(false, @nspooler_url, 'myfakehost', 'token-value', 'snapshot-sha') } + .to raise_error(ModifyError) + end + end + + describe '#disk' do + it 'logs an error explaining that disk modification is not supported' do + expect { NonstandardPooler.disk(false, @nspooler_url, 'myfakehost', 'token-value', 'diskname') } + .to raise_error(ModifyError) + end + end +end diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index d3d994d..557149a 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -91,16 +91,17 @@ describe Pooler do end it "raises a TokenError if token provided is nil" do - expect{ Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, 12, nil) }.to raise_error(TokenError) + expect{ Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError) end it "modifies the TTL of a vm" do + modify_hash = { :lifetime => 12 } 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'}). to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) - modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12, nil) + modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) expect(modify_req["ok"]).to be true end end diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb new file mode 100644 index 0000000..78ba671 --- /dev/null +++ b/spec/vmfloaty/service_spec.rb @@ -0,0 +1,79 @@ +require_relative '../../lib/vmfloaty/service' + +describe Service do + + describe '#initialize' do + it 'store configuration options' do + options = MockOptions.new({}) + config = {'url' => 'http://example.url'} + service = Service.new(options, config) + expect(service.config).to include config + end + end + + describe '#get_new_token' 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 pooler service password:') + allow(Commander::UI).to(receive(:password) + .with('Enter your pooler service password:', '*') + .and_return('hunter2')) + allow(Auth).to(receive(:get_token) + .with(nil, config['url'], config['user'], 'hunter2') + .and_return('token-value')) + expect(service.get_new_token(nil)).to eql 'token-value' + end + + 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 pooler 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 pooler service password:', '*') + .and_return('hunter2')) + allow(Auth).to(receive(:get_token) + .with(nil, config['url'], 'first.last', 'hunter2') + .and_return('token-value')) + expect(service.get_new_token(nil)).to eql 'token-value' + end + end + + describe '#delete_token' do + it 'deletes a token' do + service = Service.new(MockOptions.new,{'user' => 'first.last', 'url' => 'http://default.url'}) + allow(Commander::UI).to(receive(:password) + .with('Enter your pooler service password:', '*') + .and_return('hunter2')) + allow(Auth).to(receive(:delete_token) + .with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value') + .and_return('ok' => true)) + expect(service.delete_token(nil, 'token-value')).to eql({'ok' => true}) + end + end + + describe '#token_status' do + it 'reports the status of a token' do + config = { + 'user' => 'first.last', + 'url' => 'http://default.url' + } + options = MockOptions.new('token' => 'token-value') + service = Service.new(options, config) + status = { + 'ok' => true, + 'user' => config['user'], + 'created' => '2017-09-22 02:04:18 +0000', + 'last_accessed' => '2017-09-22 02:04:28 +0000', + 'reserved_hosts' => [] + } + allow(Auth).to(receive(:token_status) + .with(nil, config['url'], 'token-value') + .and_return(status)) + expect(service.token_status(nil, 'token-value')).to eql(status) + end + end + +end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index ed8b0b2..47822ca 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -1,22 +1,63 @@ require 'spec_helper' require 'json' +require 'commander/command' require_relative '../../lib/vmfloaty/utils' describe Utils do - describe "#get_hosts" do + describe "#format_hosts" do before :each do - @hostname_hash = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":[\"sc0o4xqtodlul5w\",\"4m4dkhqiufnjmxy\"]},\"debian-7-x86_64\":{\"hostname\":\"zb91y9qbrbf6d3q\"},\"domain\":\"company.com\"}" - @format_hash = "{\"debian-7-i386\":[\"sc0o4xqtodlul5w.company.com\",\"4m4dkhqiufnjmxy.company.com\"],\"debian-7-x86_64\":\"zb91y9qbrbf6d3q.company.com\"}" + @vmpooler_response_body ='{ + "ok": true, + "domain": "delivery.mycompany.net", + "ubuntu-1610-x86_64": { + "hostname": ["gdoy8q3nckuob0i", "ctnktsd0u11p9tm"] + }, + "centos-7-x86_64": { + "hostname": "dlgietfmgeegry2" + } + }' + @nonstandard_response_body = '{ + "ok": true, + "solaris-10-sparc": { + "hostname": ["sol10-10.delivery.mycompany.net", "sol10-11.delivery.mycompany.net"] + }, + "ubuntu-16.04-power8": { + "hostname": "power8-ubuntu16.04-6.delivery.mycompany.net" + } + }' + @vmpooler_output = <<-OUT +- gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64) +- ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64) +- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) + OUT + @nonstandard_output = <<-OUT +- sol10-10.delivery.mycompany.net (solaris-10-sparc) +- sol10-11.delivery.mycompany.net (solaris-10-sparc) +- power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8) + OUT end - it "formats a hostname hash into os, hostnames, and domain name" do + it "formats a hostname hash from vmpooler into a list that includes the os" do + expect { Utils.format_hosts(JSON.parse(@vmpooler_response_body)) }.to output( @vmpooler_output).to_stdout_from_any_process + end - expect(Utils.format_hosts(JSON.parse(@hostname_hash))).to eq @format_hash + it "formats a hostname hash from the nonstandard pooler into a list that includes the os" do + expect { Utils.format_hosts(JSON.parse(@nonstandard_response_body)) }.to output(@nonstandard_output).to_stdout_from_any_process end end - describe "#get_service_from_config" do + describe "#get_service_object" do + it "assumes vmpooler by default" do + expect(Utils.get_service_object).to be Pooler + end + + it "uses nspooler when told explicitly" do + expect(Utils.get_service_object "nspooler").to be NonstandardPooler + end + end + + describe "#get_service_config" do before :each do @default_config = { "url" => "http://default.url", @@ -41,29 +82,34 @@ describe Utils do it "returns the first service configured under 'services' as the default if available" do config = @default_config.merge @services_config - expect(Utils.get_service_from_config(config)).to include @services_config['services']['vm'] - end - - it "uses top-level service config values as defaults when service values are missing" do - config = {"services" => { "vm" => {}}} - config.merge! @default_config - expect(Utils.get_service_from_config(config, 'vm')).to include @default_config + options = MockOptions.new({}) + expect(Utils.get_service_config(config, options)).to include @services_config['services']['vm'] end it "allows selection by configured service key" do config = @default_config.merge @services_config - expect(Utils.get_service_from_config(config, 'ns')).to include @services_config['services']['ns'] + options = MockOptions.new({:service => "ns"}) + expect(Utils.get_service_config(config, options)).to include @services_config['services']['ns'] end - it "fills in missing values in configured services with the defaults" do + it "uses top-level service config values as defaults when configured service values are missing" do config = @default_config.merge @services_config config["services"]['vm'].delete 'url' - expect(Utils.get_service_from_config(config, 'vm')['url']).to eq 'http://default.url' + options = MockOptions.new({:service => "vm"}) + expect(Utils.get_service_config(config, options)['url']).to eq 'http://default.url' end - it "returns an empty hash 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 - expect(Utils.get_service_from_config(config, 'nil')).to eq({}) + 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"}) + expected = config.merge({"url" => "http://alternate.url", "token" => "alternate-token"}) + expect(Utils.get_service_config(config, options)).to include expected end end @@ -83,60 +129,97 @@ describe Utils do end end - describe '#prettyprint_hosts' do - let(:host_without_tags) { 'mcpy42eqjxli9g2' } - let(:host_with_tags) { 'aiydvzpg23r415q' } + describe '#pretty_print_hosts' do let(:url) { 'http://pooler.example.com' } - let(:host_info_with_tags) do - { - host_with_tags => { - "template" => "redhat-7-x86_64", - "lifetime" => 48, - "running" => 7.67, - "tags" => { - "user" => "bob", - "role" => "agent" + it 'prints a vmpooler output with host fqdn, template and duration info' do + hostname = 'mcpy42eqjxli9g2' + response_body = { hostname => { + 'template' => 'ubuntu-1604-x86_64', + 'lifetime' => 12, + 'running' => 9.66, + 'state' => 'running', + 'ip' => '127.0.0.1', + 'domain' => 'delivery.mycompany.net' + }} + output = "- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)" + + expect(Utils).to receive(:puts).with(output) + + service = Service.new(MockOptions.new, {'url' => url}) + allow(service).to receive(:query) + .with(nil, hostname) + .and_return(response_body) + + Utils.pretty_print_hosts(nil, service, hostname) + end + + it 'prints a vmpooler output with host fqdn, template, duration info, and tags when supplied' do + hostname = 'aiydvzpg23r415q' + response_body = { hostname => { + 'template' => 'redhat-7-x86_64', + 'lifetime' => 48, + 'running' => 7.67, + 'state' => 'running', + 'tags' => { + 'user' => 'bob', + 'role' => 'agent' }, - "domain" => "delivery.puppetlabs.net" - } - } + 'ip' => '127.0.0.1', + 'domain' => 'delivery.mycompany.net' + }} + output = "- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" + + expect(Utils).to receive(:puts).with(output) + + service = Service.new(MockOptions.new, {'url' => url}) + allow(service).to receive(:query) + .with(nil, hostname) + .and_return(response_body) + + Utils.pretty_print_hosts(nil, service, hostname) end - let(:host_info_without_tags) do - { - host_without_tags => { - "template" => "ubuntu-1604-x86_64", - "lifetime" => 12, - "running" => 9.66, - "domain" => "delivery.puppetlabs.net" - } - } + it 'prints a nonstandard pooler output with host, template, and time remaining' do + hostname = "sol11-9.delivery.mycompany.net" + response_body = { hostname => { + 'fqdn' => hostname, + 'os_triple' => 'solaris-11-sparc', + 'reserved_by_user' => 'first.last', + 'reserved_for_reason' => '', + 'hours_left_on_reservation' => 35.89 + }} + output = "- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)" + + expect(Utils).to receive(:puts).with(output) + + service = Service.new(MockOptions.new, {'url' => url, 'type' => 'ns'}) + allow(service).to receive(:query) + .with(nil, hostname) + .and_return(response_body) + + Utils.pretty_print_hosts(nil, service, hostname) end - let(:output_with_tags) { "- #{host_with_tags}.delivery.puppetlabs.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" } - let(:output_without_tags) { "- #{host_without_tags}.delivery.puppetlabs.net (ubuntu-1604-x86_64, 9.66/12 hours)" } + it 'prints a nonstandard pooler output with host, template, time remaining, and reason' do + hostname = 'sol11-9.delivery.mycompany.net' + response_body = { hostname => { + 'fqdn' => hostname, + 'os_triple' => 'solaris-11-sparc', + 'reserved_by_user' => 'first.last', + 'reserved_for_reason' => 'testing', + 'hours_left_on_reservation' => 35.89 + }} + output = "- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)" - it 'prints an output with host fqdn, template and duration info' do - allow(Utils).to receive(:get_vm_info). - with(host_without_tags, false, url). - and_return(host_info_without_tags) + expect(Utils).to receive(:puts).with(output) - expect(Utils).to receive(:puts).with("Running VMs:") - expect(Utils).to receive(:puts).with(output_without_tags) + service = Service.new(MockOptions.new, {'url' => url, 'type' => 'ns'}) + allow(service).to receive(:query) + .with(nil, hostname) + .and_return(response_body) - Utils.prettyprint_hosts(host_without_tags, false, url) - end - - it 'prints an output with host fqdn, template, duration info, and tags when supplied' do - allow(Utils).to receive(:get_vm_info). - with(host_with_tags, false, url). - and_return(host_info_with_tags) - - expect(Utils).to receive(:puts).with("Running VMs:") - expect(Utils).to receive(:puts).with(output_with_tags) - - Utils.prettyprint_hosts(host_with_tags, false, url) + Utils.pretty_print_hosts(nil, service, hostname) end end end From bc621f36013b9e2c6d987a16aaf1221cadd8cfe8 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 13 Oct 2017 16:10:15 -0700 Subject: [PATCH 020/265] Release v0.8.0 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 96d5473..a5e7535 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,3 +1,3 @@ class Vmfloaty - VERSION = '0.7.9'.freeze + VERSION = '0.8.0'.freeze end From 24722279d0f5c2ad02841890645cb4253790e72f Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 13 Oct 2017 16:13:54 -0700 Subject: [PATCH 021/265] Update LICENSE --- LICENSE | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index d8abcdc..8dada3e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,192 @@ - vmfloaty + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ - Copyright (C) 2014-2016 Puppet + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 6622a2ea17f5404a19a96117be10c0136da9fc19 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 13 Oct 2017 16:19:39 -0700 Subject: [PATCH 022/265] Update example config --- vmfloaty.yml.example | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/vmfloaty.yml.example b/vmfloaty.yml.example index 1864257..fa6507f 100644 --- a/vmfloaty.yml.example +++ b/vmfloaty.yml.example @@ -1,3 +1,8 @@ -url: 'http://vmpooler.example.com/api/v1' user: 'brian' -token: 'token here' +services: + main: + url: 'https://vmpooler.mycompany.net/api/v1' + token: 'tokenstring' + alternate: + url: 'https://vmpooler.alternate.net/api/v1' + token: 'alternate-tokenstring' From 8550e1fa2f142f7aca33e7d144a1ca8dc1c939e9 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Wed, 18 Oct 2017 10:51:43 -0700 Subject: [PATCH 023/265] Bump commander version This commit bumps the commander version up to 4.4.3 in order to clear up the deprecation warnings being emitted from 4.3.0: ``` > floaty get centos-7-x86_64 /Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333: warning: constant ::NIL is deprecated /Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333: warning: constant ::TRUE is deprecated /Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333: warning: constant ::FALSE is deprecated /Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333: warning: constant ::Fixnum is deprecated /Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333: warning: constant ::Bignum is deprecated - as9r7rigltr70zt.delivery.puppetlabs.net (centos-7-x86_64) ``` --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 0ccc715..4317b4a 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.test_files = Dir['spec/**/*'] s.require_path = 'lib' - s.add_dependency 'commander', '~> 4.3.0' + s.add_dependency 'commander', '~> 4.4.3' s.add_dependency 'faraday', '~> 0.9.0' s.add_dependency 'colorize', '~> 0.8.1' end From 6fc8e14f8f11ff3dafd386e9a45deb885635fd4e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 24 Oct 2017 08:54:10 -0700 Subject: [PATCH 024/265] Update travis to ruby 2.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 41b77f5..6788143 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: false language: ruby rvm: - - 2.1 + - 2.4 script: rspec spec From 837fa94af520f22320ab10dd6bc4158ec158cf91 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 24 Oct 2017 08:59:28 -0700 Subject: [PATCH 025/265] Version 0.8.1 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index a5e7535..bb0ab34 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,3 +1,3 @@ class Vmfloaty - VERSION = '0.8.0'.freeze + VERSION = '0.8.1'.freeze end From 941d8452d6e71a436e7b3cec9f32452ffeb8d461 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Sat, 23 Dec 2017 12:36:12 -0800 Subject: [PATCH 026/265] Update rubocop dep --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 49db604..926c627 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,6 @@ gem 'rake', require: false group :test do gem 'rspec', '~> 3.5.0' - gem 'rubocop', '~> 0.47' + gem 'rubocop', '~> 0.52' gem 'webmock', '1.21.0' end From 50eeb8f265a7a0984699823833ec9f6fe1e5e836 Mon Sep 17 00:00:00 2001 From: Nick Lewis Date: Tue, 12 Dec 2017 11:22:10 -0800 Subject: [PATCH 027/265] Add --json option for `floaty get` This option will return structured output from `floaty get`, which is easier to parse in some cases. Example output: ```json { "centos-7-x86_64": [ "hpfhhf5aqxowfd8.delivery.puppetlabs.net", "k65euywltpz9fz0.delivery.puppetlabs.net" ], "centos-6-x86_64": [ "oahunrurl7xis05.delivery.puppetlabs.net" ] } ``` --- lib/vmfloaty.rb | 8 +++++++- lib/vmfloaty/utils.rb | 35 +++++++++++++++------------------- spec/vmfloaty/utils_spec.rb | 38 ++++++++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 5056d4f..9bbe782 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -35,6 +35,7 @@ class Vmfloaty c.option '--token STRING', String, 'Token for pooler service' c.option '--notoken', 'Makes a request without a token' c.option '--force', 'Forces vmfloaty to get requested vms' + c.option '--json', 'Prints retrieved vms in JSON format' c.action do |args, options| verbose = options.verbose || config['verbose'] service = Service.new(options, config) @@ -62,7 +63,12 @@ class Vmfloaty end response = service.retrieve(verbose, os_types, use_token) - puts Utils.format_hosts(response) + hosts = Utils.standardize_hostnames(response) + if options.json + puts JSON.pretty_generate(hosts) + else + puts Utils.format_host_output(hosts) + end end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index fe55511..b8e1a17 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -4,7 +4,7 @@ require 'vmfloaty/nonstandard_pooler' class Utils # TODO: Takes the json response body from an HTTP GET # request and "pretty prints" it - def self.format_hosts(response_body) + def self.standardize_hostnames(response_body) # vmpooler response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`: # { # "ok": true, @@ -32,31 +32,26 @@ class Utils raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" end - hostnames = [] - # vmpooler reports the domain separately from the hostname domain = response_body.delete('domain') - if domain - # vmpooler output - response_body.each do |os, hosts| - if hosts['hostname'].kind_of?(Array) - hosts['hostname'].map!{ |host| hostnames << host + "." + domain + " (#{os})"} - else - hostnames << hosts["hostname"] + ".#{domain} (#{os})" - end - end - else - response_body.each do |os, hosts| - if hosts['hostname'].kind_of?(Array) - hosts['hostname'].map!{ |host| hostnames << host + " (#{os})" } - else - hostnames << hosts['hostname'] + " (#{os})" - end + result = {} + + response_body.each do |os, value| + hostnames = Array(value['hostname']) + if domain + hostnames.map! {|host| "#{host}.#{domain}"} end + result[os] = hostnames end - hostnames.map { |hostname| puts "- #{hostname}" } + result + end + + def self.format_host_output(hosts) + hosts.flat_map do |os, names| + names.map { |name| "- #{name} (#{os})" } + end.join("\n") end def self.generate_os_hash(os_args) diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 47822ca..5a78a61 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -5,7 +5,7 @@ require_relative '../../lib/vmfloaty/utils' describe Utils do - describe "#format_hosts" do + describe "#standardize_hostnames" do before :each do @vmpooler_response_body ='{ "ok": true, @@ -26,24 +26,48 @@ describe Utils do "hostname": "power8-ubuntu16.04-6.delivery.mycompany.net" } }' - @vmpooler_output = <<-OUT + end + + 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"]) + 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'], + 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net']) + end + end + + 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"] + } + @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'] + } + @vmpooler_output = <<-OUT.chomp +- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) - gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64) - ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64) -- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) OUT - @nonstandard_output = <<-OUT + @nonstandard_output = <<-OUT.chomp - sol10-10.delivery.mycompany.net (solaris-10-sparc) - sol10-11.delivery.mycompany.net (solaris-10-sparc) - power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8) OUT end - it "formats a hostname hash from vmpooler into a list that includes the os" do - expect { Utils.format_hosts(JSON.parse(@vmpooler_response_body)) }.to output( @vmpooler_output).to_stdout_from_any_process + expect(Utils.format_host_output(@vmpooler_results)).to eq(@vmpooler_output) end it "formats a hostname hash from the nonstandard pooler into a list that includes the os" do - expect { Utils.format_hosts(JSON.parse(@nonstandard_response_body)) }.to output(@nonstandard_output).to_stdout_from_any_process + expect(Utils.format_host_output(@nonstandard_results)).to eq(@nonstandard_output) end end From cf2295ccfd2ddc18a20b96a2cfc153b11ece461a Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 4 Jan 2018 16:54:58 -0800 Subject: [PATCH 028/265] Tag v0.8.2 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index bb0ab34..4000441 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,3 +1,3 @@ class Vmfloaty - VERSION = '0.8.1'.freeze + VERSION = '0.8.2'.freeze end From 1272343cdd963062c33f0a9cb19733269f0a6446 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 10:42:28 +1100 Subject: [PATCH 029/265] (rubocop) Fix Style/StringLiterals --- lib/vmfloaty.rb | 20 ++-- lib/vmfloaty/auth.rb | 10 +- lib/vmfloaty/errors.rb | 8 +- lib/vmfloaty/http.rb | 6 +- lib/vmfloaty/pooler.rb | 20 ++-- lib/vmfloaty/service.rb | 12 +-- lib/vmfloaty/ssh.rb | 10 +- lib/vmfloaty/utils.rb | 2 +- spec/vmfloaty/auth_spec.rb | 60 ++++++------ spec/vmfloaty/nonstandard_pooler_spec.rb | 8 +- spec/vmfloaty/pooler_spec.rb | 114 +++++++++++------------ spec/vmfloaty/utils_spec.rb | 92 +++++++++--------- 12 files changed, 181 insertions(+), 181 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 9bbe782..390d2ab 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -43,7 +43,7 @@ class Vmfloaty force = options.force if args.empty? - STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs." + STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' exit 1 end @@ -53,12 +53,12 @@ class Vmfloaty large_pool_requests = os_types.select{|_,v| v > max_pool_request} if ! large_pool_requests.empty? and ! force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." - STDERR.puts "Try again with `floaty get --force`" + STDERR.puts 'Try again with `floaty get --force`' exit 1 end if os_types.empty? - STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs." + STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' exit 1 end @@ -144,10 +144,10 @@ class Vmfloaty modify_all = options.all if hostname.nil? and !modify_all - STDERR.puts "ERROR: Provide a hostname or specify --all." + STDERR.puts 'ERROR: Provide a hostname or specify --all.' exit 1 end - running_vms = modify_all ? service.list_active(verbose) : hostname.split(",") + running_vms = modify_all ? service.list_active(verbose) : hostname.split(',') tags = options.tags ? JSON.parse(options.tags) : nil modify_hash = { @@ -171,11 +171,11 @@ class Vmfloaty end if ok if modify_all - puts "Successfully modified all VMs." + puts 'Successfully modified all VMs.' else puts "Successfully modified VM #{hostname}." end - puts "Use `floaty list --active` to see the results." + puts 'Use `floaty list --active` to see the results.' end end end @@ -205,7 +205,7 @@ class Vmfloaty if delete_all running_vms = service.list_active(verbose) if running_vms.empty? - STDERR.puts "You have no running VMs." + STDERR.puts 'You have no running VMs.' else Utils.pretty_print_hosts(verbose, service, running_vms) # Confirm deletion @@ -236,7 +236,7 @@ class Vmfloaty end end else - STDERR.puts "You did not provide any hosts to delete" + STDERR.puts 'You did not provide any hosts to delete' exit 1 end @@ -417,7 +417,7 @@ class Vmfloaty use_token = !options.notoken if args.empty? - STDERR.puts "No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs." + STDERR.puts 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.' exit 1 end diff --git a/lib/vmfloaty/auth.rb b/lib/vmfloaty/auth.rb index b68e22d..7d33327 100644 --- a/lib/vmfloaty/auth.rb +++ b/lib/vmfloaty/auth.rb @@ -7,11 +7,11 @@ class Auth def self.get_token(verbose, url, user, password) conn = Http.get_conn_with_auth(verbose, url, user, password) - resp = conn.post "token" + resp = conn.post 'token' res_body = JSON.parse(resp.body) - if res_body["ok"] - return res_body["token"] + if res_body['ok'] + return res_body['token'] else raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}" end @@ -26,7 +26,7 @@ class Auth response = conn.delete "token/#{token}" res_body = JSON.parse(response.body) - if res_body["ok"] + if res_body['ok'] return res_body else raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}" @@ -43,7 +43,7 @@ class Auth response = conn.get "token/#{token}" res_body = JSON.parse(response.body) - if res_body["ok"] + 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}" diff --git a/lib/vmfloaty/errors.rb b/lib/vmfloaty/errors.rb index 221fa14..ee8e2cb 100644 --- a/lib/vmfloaty/errors.rb +++ b/lib/vmfloaty/errors.rb @@ -1,23 +1,23 @@ class AuthError < StandardError - def initialize(msg="Could not authenticate to pooler") + def initialize(msg='Could not authenticate to pooler') super end end class TokenError < StandardError - def initialize(msg="Could not do operation with token provided") + def initialize(msg='Could not do operation with token provided') super end end class MissingParamError < StandardError - def initialize(msg="Argument provided to function is missing") + def initialize(msg='Argument provided to function is missing') super end end class ModifyError < StandardError - def initialize(msg="Could not modify VM") + def initialize(msg='Could not modify VM') super end end diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index 656b732..f21b993 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -18,7 +18,7 @@ class Http def self.get_conn(verbose, url) if url.nil? - raise "Did not provide a url to connect to" + raise 'Did not provide a url to connect to' end unless is_url(url) @@ -36,11 +36,11 @@ class Http def self.get_conn_with_auth(verbose, url, user, password) if url.nil? - raise "Did not provide a url to connect to" + raise 'Did not provide a url to connect to' end if user.nil? - raise "You did not provide a user to authenticate with" + raise 'You did not provide a user to authenticate with' end unless is_url(url) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index e81b4cd..8bdef2c 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -37,24 +37,24 @@ class Pooler conn.headers['X-AUTH-TOKEN'] = token end - os_string = "" + os_string = '' os_type.each do |os,num| num.times do |i| - os_string << os+"+" + os_string << os+'+' end end - os_string = os_string.chomp("+") + os_string = os_string.chomp('+') if os_string.size == 0 - raise MissingParamError, "No operating systems provided to obtain." + raise MissingParamError, 'No operating systems provided to obtain.' end response = conn.post "vm/#{os_string}" res_body = JSON.parse(response.body) - if res_body["ok"] + if res_body['ok'] res_body elsif response.status == 401 raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" @@ -65,7 +65,7 @@ class Pooler 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" + raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' end modify_hash.keys.each do |key| @@ -93,7 +93,7 @@ class Pooler def self.disk(verbose, url, hostname, token, disk) if token.nil? - raise TokenError, "Token provided was nil. Request cannot be made to modify vm" + raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' end conn = Http.get_conn(verbose, url) @@ -107,7 +107,7 @@ class Pooler def self.delete(verbose, url, hosts, token) if token.nil? - raise TokenError, "Token provided was nil. Request cannot be made to delete vm" + raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' end conn = Http.get_conn(verbose, url) @@ -154,7 +154,7 @@ class Pooler def self.snapshot(verbose, url, hostname, token) if token.nil? - raise TokenError, "Token provided was nil. Request cannot be made to snapshot vm" + raise TokenError, 'Token provided was nil. Request cannot be made to snapshot vm' end conn = Http.get_conn(verbose, url) @@ -167,7 +167,7 @@ class Pooler 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" + raise TokenError, 'Token provided was nil. Request cannot be made to revert vm' end conn = Http.get_conn(verbose, url) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index b2a2333..14a8df3 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -31,7 +31,7 @@ class Service def user unless @config['user'] - puts "Enter your pooler service username:" + puts 'Enter your pooler service username:' @config['user'] = STDIN.gets.chomp end @config['user'] @@ -39,7 +39,7 @@ class Service def token unless @config['token'] - puts "No token found. Retrieving a token..." + puts 'No token found. Retrieving a token...' @config['token'] = get_new_token(nil) end @config['token'] @@ -47,13 +47,13 @@ class Service def get_new_token(verbose) username = user - pass = Commander::UI::password "Enter your pooler service password:", '*' + pass = Commander::UI::password 'Enter your pooler service password:', '*' Auth.get_token(verbose, url, username, pass) end def delete_token(verbose, token_value = @config['token']) username = user - pass = Commander::UI::password "Enter your pooler service password:", '*' + pass = Commander::UI::password 'Enter your pooler service password:', '*' Auth.delete_token(verbose, url, username, pass, token_value) end @@ -91,9 +91,9 @@ class Service def pretty_print_running(verbose, hostnames = []) if hostnames.empty? - puts "You have no running VMs." + puts 'You have no running VMs.' else - puts "Running VMs:" + puts 'Running VMs:' @service_object.pretty_print_hosts(verbose, hostnames, url) end end diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 4ee4b8c..4087d3a 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -14,19 +14,19 @@ class Ssh end 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" + raise 'Could not determine path to ssh' end os_types = {} os_types[host_os] = 1 response = Pooler.retrieve(verbose, os_types, token, url) - if response["ok"] == true + if response['ok'] == true if host_os =~ /win/ - user = "Administrator" + user = 'Administrator' else - user = "root" + user = 'root' end hostname = "#{response[host_os]["hostname"]}.#{response["domain"]}" diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index b8e1a17..fca7a32 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -65,7 +65,7 @@ class Utils # ...] os_types = {} os_args.each do |arg| - os_arr = arg.split("=") + os_arr = arg.split('=') if os_arr.size == 1 # assume they didn't specify an = sign if split returns 1 size os_types[os_arr[0]] = 1 diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index bcd246e..8a527ed 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -3,67 +3,67 @@ require_relative '../../lib/vmfloaty/auth' describe Pooler do before :each do - @vmpooler_url = "https://vmpooler.example.com" + @vmpooler_url = 'https://vmpooler.example.com' end - describe "#get_token" do + describe '#get_token' do before :each do - @get_token_response = "{\"ok\": true,\"token\":\"utpg2i2xswor6h8ttjhu3d47z53yy47y\"}" - @token = "utpg2i2xswor6h8ttjhu3d47z53yy47y" + @get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}' + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' end - it "returns a token from vmpooler" do - stub_request(:post, "https://first.last:password@vmpooler.example.com/token"). + it 'returns a token from vmpooler' do + stub_request(:post, 'https://first.last:password@vmpooler.example.com/token'). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2'}). to_return(:status => 200, :body => @get_token_response, :headers => {}) - token = Auth.get_token(false, @vmpooler_url, "first.last", "password") + token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password') expect(token).to eq @token end - it "raises a token error if something goes wrong" do - stub_request(:post, "https://first.last:password@vmpooler.example.com/token"). + it 'raises a token error if something goes wrong' do + stub_request(:post, 'https://first.last:password@vmpooler.example.com/token'). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2'}). - to_return(:status => 500, :body => "{\"ok\":false}", :headers => {}) + to_return(:status => 500, :body => '{"ok":false}', :headers => {}) - expect{ Auth.get_token(false, @vmpooler_url, "first.last", "password") }.to raise_error(TokenError) + expect{ Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) end end - describe "#delete_token" do + describe '#delete_token' do before :each do - @delete_token_response = "{\"ok\":true}" - @token = "utpg2i2xswor6h8ttjhu3d47z53yy47y" + @delete_token_response = '{"ok":true}' + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' end - it "deletes the specified token" do - stub_request(:delete, "https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). + it 'deletes the specified token' do + stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). to_return(:status => 200, :body => @delete_token_response, :headers => {}) - expect(Auth.delete_token(false, @vmpooler_url, "first.last", "password", @token)).to eq JSON.parse(@delete_token_response) + expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) end - it "raises a token error if something goes wrong" do - stub_request(:delete, "https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). + it 'raises a token error if something goes wrong' do + stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). - to_return(:status => 500, :body => "{\"ok\":false}", :headers => {}) + to_return(:status => 500, :body => '{"ok":false}', :headers => {}) - expect{ Auth.delete_token(false, @vmpooler_url, "first.last", "password", @token) }.to raise_error(TokenError) + expect{ Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) end - it "raises a token error if no token provided" do - expect{ Auth.delete_token(false, @vmpooler_url, "first.last", "password", nil) }.to raise_error(TokenError) + it 'raises a token error if no token provided' do + expect{ Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', nil) }.to raise_error(TokenError) end end - describe "#token_status" do + describe '#token_status' do before :each do - @token_status_response = "{\"ok\":true,\"utpg2i2xswor6h8ttjhu3d47z53yy47y\":{\"created\":\"2015-04-28 19:17:47 -0700\"}}" - @token = "utpg2i2xswor6h8ttjhu3d47z53yy47y" + @token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}' + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' end - it "checks the status of a token" do + it 'checks the status of a token' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). to_return(:status => 200, :body => @token_status_response, :headers => {}) @@ -71,15 +71,15 @@ describe Pooler do 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 + it 'raises a token error if something goes wrong' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). - to_return(:status => 500, :body => "{\"ok\":false}", :headers => {}) + to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect{ Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) 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) end end diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 02ab9d9..7b03827 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -172,10 +172,10 @@ BODY end it 'raises an error if the user tries to modify an unsupported attribute' do - stub_request(:put, "https://nspooler.example.com/host/myfakehost"). - with(body: {"{}"=>true}, + stub_request(:put, 'https://nspooler.example.com/host/myfakehost'). + with(body: {'{}'=>true}, headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'token-value'}). - to_return(status: 200, body: "", headers: {}) + to_return(status: 200, body: '', headers: {}) details = { lifetime: 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } .to raise_error(ModifyError) @@ -188,7 +188,7 @@ BODY headers: @post_request_headers) .to_return(status: 200, body: '{"ok": true}', headers: {}) - modify_hash = { reason: "testing" } + modify_hash = { reason: 'testing' } modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash) expect(modify_req['ok']).to be true end diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 557149a..397e99a 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -3,15 +3,15 @@ require_relative '../../lib/vmfloaty/pooler' describe Pooler do before :each do - @vmpooler_url = "https://vmpooler.example.com" + @vmpooler_url = 'https://vmpooler.example.com' end - describe "#list" do + describe '#list' do before :each do - @list_response_body = "[\"debian-7-i386\",\"debian-7-x86_64\",\"centos-7-x86_64\"]" + @list_response_body = '["debian-7-i386","debian-7-x86_64","centos-7-x86_64"]' end - it "returns a hash with operating systems from the pooler" do + 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 => {}) @@ -19,42 +19,42 @@ describe Pooler do expect(list).to be_an_instance_of Array 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"). to_return(:status => 200, :body => @list_response_body, :headers => {}) - list = Pooler.list(false, @vmpooler_url, "deb") + list = Pooler.list(false, @vmpooler_url, 'deb') expect(list).to be_an_instance_of Array expect(list.size).to equal 2 end - it "returns nothing if the filter does not match" do + it 'returns nothing if the filter does not match' do stub_request(:get, "#{@vmpooler_url}/vm"). to_return(:status => 200, :body => @list_response_body, :headers => {}) - list = Pooler.list(false, @vmpooler_url, "windows") + list = Pooler.list(false, @vmpooler_url, 'windows') expect(list).to be_an_instance_of Array expect(list.size).to equal 0 end end - describe "#retrieve" do + describe '#retrieve' do before :each do - @retrieve_response_body_single = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":\"fq6qlpjlsskycq6\"}}" - @retrieve_response_body_double = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":[\"sc0o4xqtodlul5w\",\"4m4dkhqiufnjmxy\"]},\"centos-7-x86_64\":{\"hostname\":\"zb91y9qbrbf6d3q\"}}" + @retrieve_response_body_single = '{"ok":true,"debian-7-i386":{"hostname":"fq6qlpjlsskycq6"}}' + @retrieve_response_body_double = '{"ok":true,"debian-7-i386":{"hostname":["sc0o4xqtodlul5w","4m4dkhqiufnjmxy"]},"centos-7-x86_64":{"hostname":"zb91y9qbrbf6d3q"}}' end - it "raises an AuthError if the token is invalid" do + it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). - to_return(:status => 401, :body => "{\"ok\":false}", :headers => {}) + to_return(:status => 401, :body => '{"ok":false}', :headers => {}) vm_hash = {} vm_hash['debian-7-i386'] = 1 expect{ Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError) 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"). 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 => {}) @@ -63,11 +63,11 @@ describe Pooler do vm_hash['debian-7-i386'] = 1 vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) expect(vm_req).to be_an_instance_of Hash - expect(vm_req["ok"]).to equal true - expect(vm_req["debian-7-i386"]["hostname"]).to eq "fq6qlpjlsskycq6" + expect(vm_req['ok']).to equal true + expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6' end - it "retrieves a multiple vms with a token" do + it 'retrieves a multiple vms with a token' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {}) @@ -77,24 +77,24 @@ describe Pooler do vm_hash['centos-7-x86_64'] = 1 vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) expect(vm_req).to be_an_instance_of Hash - expect(vm_req["ok"]).to equal true - expect(vm_req["debian-7-i386"]["hostname"]).to be_an_instance_of Array - expect(vm_req["debian-7-i386"]["hostname"]).to eq ["sc0o4xqtodlul5w", "4m4dkhqiufnjmxy"] - expect(vm_req["centos-7-x86_64"]["hostname"]).to eq "zb91y9qbrbf6d3q" + expect(vm_req['ok']).to equal true + expect(vm_req['debian-7-i386']['hostname']).to be_an_instance_of Array + expect(vm_req['debian-7-i386']['hostname']).to eq ['sc0o4xqtodlul5w', '4m4dkhqiufnjmxy'] + expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q' end end - describe "#modify" do + describe '#modify' do before :each do - @modify_response_body_success = "{\"ok\":true}" - @modify_response_body_fail = "{\"ok\":false}" + @modify_response_body_success = '{"ok":true}' + @modify_response_body_fail = '{"ok":false}' end - it "raises a TokenError if token provided is nil" do + it 'raises a TokenError if token provided is nil' do expect{ Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError) end - it "modifies the TTL of a vm" do + it 'modifies the TTL of a vm' do modify_hash = { :lifetime => 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). with(:body => {'{"lifetime":12}'=>true}, @@ -102,17 +102,17 @@ describe Pooler do to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) - expect(modify_req["ok"]).to be true + expect(modify_req['ok']).to be true end end - describe "#delete" do + describe '#delete' do before :each do - @delete_response_body_success = "{\"ok\":true}" - @delete_response = {"fq6qlpjlsskycq6"=>{"ok"=>true}} + @delete_response_body_success = '{"ok":true}' + @delete_response = {'fq6qlpjlsskycq6'=>{'ok'=>true}} end - it "deletes a specified vm" do + it 'deletes a specified vm' do stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) @@ -120,18 +120,18 @@ describe Pooler do expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response 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) end end - describe "#status" do + describe '#status' do before :each do #smaller version - @status_response_body = "{\"capacity\":{\"current\":716,\"total\":717,\"percent\": 99.9},\"status\":{\"ok\":true,\"message\":\"Battle station fully armed and operational.\"}}" + @status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}' end - it "prints the status" do + it 'prints the status' do stub_request(:get, "#{@vmpooler_url}/status"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). to_return(:status => 200, :body => @status_response_body, :headers => {}) @@ -141,21 +141,21 @@ describe Pooler do end end - describe "#summary" do + describe '#summary' do before :each do - @status_response_body = "" + @status_response_body = '' - it "prints the summary" do + it 'prints the summary' do end end end - describe "#query" do + describe '#query' do before :each do - @query_response_body = "{\"ok\": true,\"fq6qlpjlsskycq6\":{\"template\":\"debian-7-x86_64\",\"lifetime\": 2,\"running\": 0.08,\"state\":\"running\",\"snapshots\":[\"n4eb4kdtp7rwv4x158366vd9jhac8btq\" ],\"domain\": \"delivery.puppetlabs.net\"}}" + @query_response_body = '{"ok": true,"fq6qlpjlsskycq6":{"template":"debian-7-x86_64","lifetime": 2,"running": 0.08,"state":"running","snapshots":["n4eb4kdtp7rwv4x158366vd9jhac8btq" ],"domain": "delivery.puppetlabs.net"}}' end - it "makes a query about a vm" do + it 'makes a query about a vm' do stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). to_return(:status => 200, :body => @query_response_body, :headers => {}) @@ -165,59 +165,59 @@ describe Pooler do end end - describe "#snapshot" do + describe '#snapshot' do before :each do - @snapshot_response_body = "{\"ok\":true}" + @snapshot_response_body = '{"ok":true}' end - it "makes a snapshot for a single vm" do + it 'makes a snapshot for a single vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') - expect(snapshot_req["ok"]).to be true + expect(snapshot_req['ok']).to be true end end - describe "#revert" do + describe '#revert' do before :each do - @revert_response_body = "{\"ok\":true}" + @revert_response_body = '{"ok":true}' end - it "makes a request to revert a vm from a snapshot" do + it 'makes a request to revert a vm from a snapshot' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @revert_response_body, :headers => {}) revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') - expect(revert_req["ok"]).to be true + expect(revert_req['ok']).to be true end it "doesn't make a request to revert a vm if snapshot is not provided" do - expect{ Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, "Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6") + expect{ Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6') end - it "raises a TokenError if no token was provided" do + it 'raises a TokenError if no token was provided' do expect{ Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError) end end - describe "#disk" do + describe '#disk' do before :each do - @disk_response_body_success = "{\"ok\":true}" - @disk_response_body_fail = "{\"ok\":false}" + @disk_response_body_success = '{"ok":true}' + @disk_response_body_fail = '{"ok":false}' end - it "makes a request to extend disk space of a vm" do + it 'makes a request to extend disk space of a vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12"). with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @disk_response_body_success, :headers => {}) disk_req = Pooler.disk(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12) - expect(disk_req["ok"]).to be true + expect(disk_req['ok']).to be true end - it "raises a TokenError if no token was provided" do + it 'raises a TokenError if no token was provided' do expect{ Pooler.disk(false, @vmpooler_url, 'myfakehost', nil, 12) }.to raise_error(TokenError) end end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 5a78a61..1885bfa 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -5,7 +5,7 @@ require_relative '../../lib/vmfloaty/utils' describe Utils do - describe "#standardize_hostnames" do + describe '#standardize_hostnames' do before :each do @vmpooler_response_body ='{ "ok": true, @@ -28,24 +28,24 @@ describe Utils do }' end - it "formats a result from vmpooler into a hash of os to hostnames" do + it 'formats a result from vmpooler into a hash of os to hostnames' do result = Utils.standardize_hostnames(JSON.parse(@vmpooler_response_body)) - expect(result).to eq('centos-7-x86_64' => ["dlgietfmgeegry2.delivery.mycompany.net"], - 'ubuntu-1610-x86_64' => ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"]) + expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], + 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net']) end - it "formats a result from the nonstandard pooler into a hash of os to hostnames" do + it 'formats a result from the nonstandard pooler into a hash of os to hostnames' do result = Utils.standardize_hostnames(JSON.parse(@nonstandard_response_body)) expect(result).to eq('solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net']) end end - describe "#format_host_output" do + describe '#format_host_output' do before :each do @vmpooler_results = { - 'centos-7-x86_64' => ["dlgietfmgeegry2.delivery.mycompany.net"], - 'ubuntu-1610-x86_64' => ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"] + 'centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], + 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net'] } @nonstandard_results = { 'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], @@ -62,43 +62,43 @@ describe Utils do - power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8) OUT end - it "formats a hostname hash from vmpooler into a list that includes the os" do + it 'formats a hostname hash from vmpooler into a list that includes the os' do expect(Utils.format_host_output(@vmpooler_results)).to eq(@vmpooler_output) end - it "formats a hostname hash from the nonstandard pooler into a list that includes the os" do + it 'formats a hostname hash from the nonstandard pooler into a list that includes the os' do expect(Utils.format_host_output(@nonstandard_results)).to eq(@nonstandard_output) end end - describe "#get_service_object" do - it "assumes vmpooler by default" do + describe '#get_service_object' do + it 'assumes vmpooler by default' do expect(Utils.get_service_object).to be Pooler end - it "uses nspooler when told explicitly" do - expect(Utils.get_service_object "nspooler").to be NonstandardPooler + it 'uses nspooler when told explicitly' do + expect(Utils.get_service_object 'nspooler').to be NonstandardPooler end end - describe "#get_service_config" do + describe '#get_service_config' do before :each do @default_config = { - "url" => "http://default.url", - "user" => "first.last.default", - "token" => "default-token", + 'url' => 'http://default.url', + 'user' => 'first.last.default', + 'token' => 'default-token', } @services_config = { - "services" => { - "vm" => { - "url" => "http://vmpooler.url", - "user" => "first.last.vmpooler", - "token" => "vmpooler-token" + 'services' => { + 'vm' => { + 'url' => 'http://vmpooler.url', + 'user' => 'first.last.vmpooler', + 'token' => 'vmpooler-token' }, - "ns" => { - "url" => "http://nspooler.url", - "user" => "first.last.nspooler", - "token" => "nspooler-token" + 'ns' => { + 'url' => 'http://nspooler.url', + 'user' => 'first.last.nspooler', + 'token' => 'nspooler-token' } } } @@ -110,44 +110,44 @@ describe Utils do expect(Utils.get_service_config(config, options)).to include @services_config['services']['vm'] end - it "allows selection by configured service key" do + it 'allows selection by configured service key' do config = @default_config.merge @services_config - options = MockOptions.new({:service => "ns"}) + options = MockOptions.new({:service => 'ns'}) expect(Utils.get_service_config(config, options)).to include @services_config['services']['ns'] end - it "uses top-level service config values as defaults when configured service values are missing" do + it 'uses top-level service config values as defaults when configured service values are missing' do config = @default_config.merge @services_config - config["services"]['vm'].delete 'url' - options = MockOptions.new({:service => "vm"}) + config['services']['vm'].delete 'url' + options = MockOptions.new({:service => 'vm'}) expect(Utils.get_service_config(config, options)['url']).to eq 'http://default.url' end it "raises an error if passed a service name that hasn't been configured" do config = @default_config.merge @services_config - options = MockOptions.new({:service => "none"}) + options = MockOptions.new({:service => 'none'}) expect { Utils.get_service_config(config, options) }.to raise_error ArgumentError end - it "prioritizes values passed as command line options over configuration options" do + it 'prioritizes values passed as command line options over configuration options' do config = @default_config - options = MockOptions.new({:url => "http://alternate.url", :token => "alternate-token"}) - expected = config.merge({"url" => "http://alternate.url", "token" => "alternate-token"}) + options = MockOptions.new({:url => 'http://alternate.url', :token => 'alternate-token'}) + expected = config.merge({'url' => 'http://alternate.url', 'token' => 'alternate-token'}) expect(Utils.get_service_config(config, options)).to include expected end end - describe "#generate_os_hash" do + describe '#generate_os_hash' do before :each do - @host_hash = {"centos"=>1, "debian"=>5, "windows"=>1} + @host_hash = {'centos'=>1, 'debian'=>5, 'windows'=>1} end - it "takes an array of os arguments and returns a formatted hash" do - host_arg = ["centos", "debian=5", "windows=1"] + it 'takes an array of os arguments and returns a formatted hash' do + host_arg = ['centos', 'debian=5', 'windows=1'] expect(Utils.generate_os_hash(host_arg)).to eq @host_hash end - it "returns an empty hash if there are no arguments provided" do + it 'returns an empty hash if there are no arguments provided' do host_arg = [] expect(Utils.generate_os_hash(host_arg)).to be_empty end @@ -166,7 +166,7 @@ describe Utils do 'ip' => '127.0.0.1', '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) @@ -192,7 +192,7 @@ describe Utils do 'ip' => '127.0.0.1', 'domain' => 'delivery.mycompany.net' }} - output = "- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" + output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)' expect(Utils).to receive(:puts).with(output) @@ -205,7 +205,7 @@ describe Utils do end it 'prints a nonstandard pooler output with host, template, and time remaining' do - hostname = "sol11-9.delivery.mycompany.net" + hostname = 'sol11-9.delivery.mycompany.net' response_body = { hostname => { 'fqdn' => hostname, 'os_triple' => 'solaris-11-sparc', @@ -213,7 +213,7 @@ describe Utils do 'reserved_for_reason' => '', '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) @@ -234,7 +234,7 @@ describe Utils do 'reserved_for_reason' => 'testing', '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) From 1cf00a5a4c75de00b98128a706cd34014f94a776 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 10:44:25 +1100 Subject: [PATCH 030/265] (rubocop) Fix Style/ZeroLengthPredicate --- lib/vmfloaty/pooler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 8bdef2c..539e85b 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -46,7 +46,7 @@ class Pooler os_string = os_string.chomp('+') - if os_string.size == 0 + if os_string.empty? raise MissingParamError, 'No operating systems provided to obtain.' end From 02e49e5c4f48d7c5ab1a61feab5e866e595cfafc Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 10:46:35 +1100 Subject: [PATCH 031/265] (rubocop) Fix Style/ColonMethodCall --- lib/vmfloaty/service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 14a8df3..aa0dae0 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -47,13 +47,13 @@ class Service def get_new_token(verbose) username = user - pass = Commander::UI::password 'Enter your pooler service password:', '*' + pass = Commander::UI.password 'Enter your pooler service password:', '*' Auth.get_token(verbose, url, username, pass) end def delete_token(verbose, token_value = @config['token']) username = user - pass = Commander::UI::password 'Enter your pooler service password:', '*' + pass = Commander::UI.password 'Enter your pooler service password:', '*' Auth.delete_token(verbose, url, username, pass, token_value) end From e0cbf89b8f5b7ac467a114a0d26b59348c4ae67d Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 10:48:00 +1100 Subject: [PATCH 032/265] (rubocop) Fix Style/FrozenStringLiteralComment --- Gemfile | 2 ++ Rakefile | 2 ++ bin/floaty | 1 + lib/vmfloaty.rb | 1 + lib/vmfloaty/auth.rb | 2 ++ lib/vmfloaty/conf.rb | 2 ++ lib/vmfloaty/errors.rb | 2 ++ lib/vmfloaty/http.rb | 2 ++ lib/vmfloaty/nonstandard_pooler.rb | 12 +++--------- lib/vmfloaty/pooler.rb | 12 +++--------- lib/vmfloaty/service.rb | 2 ++ lib/vmfloaty/ssh.rb | 2 ++ lib/vmfloaty/utils.rb | 2 ++ lib/vmfloaty/version.rb | 2 ++ spec/spec_helper.rb | 2 ++ spec/vmfloaty/auth_spec.rb | 2 ++ spec/vmfloaty/nonstandard_pooler_spec.rb | 2 ++ spec/vmfloaty/pooler_spec.rb | 2 ++ spec/vmfloaty/service_spec.rb | 2 ++ spec/vmfloaty/utils_spec.rb | 2 ++ vmfloaty.gemspec | 2 ++ 21 files changed, 42 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index 926c627..26acfc9 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source 'https://rubygems.org' gemspec diff --git a/Rakefile b/Rakefile index efbd5a9..3d5a4dd 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rubygems' require 'bundler/setup' require 'rspec/core/rake_task' diff --git a/bin/floaty b/bin/floaty index 6fe5b10..1a1b0be 100755 --- a/bin/floaty +++ b/bin/floaty @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 390d2ab..4a29e49 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require 'rubygems' require 'commander' diff --git a/lib/vmfloaty/auth.rb b/lib/vmfloaty/auth.rb index 7d33327..bbe7425 100644 --- a/lib/vmfloaty/auth.rb +++ b/lib/vmfloaty/auth.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'faraday' require 'json' require 'vmfloaty/http' diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb index 2f04e61..a232f8d 100644 --- a/lib/vmfloaty/conf.rb +++ b/lib/vmfloaty/conf.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'yaml' class Conf diff --git a/lib/vmfloaty/errors.rb b/lib/vmfloaty/errors.rb index ee8e2cb..098a94c 100644 --- a/lib/vmfloaty/errors.rb +++ b/lib/vmfloaty/errors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AuthError < StandardError def initialize(msg='Could not authenticate to pooler') super diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index f21b993..71f955d 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'faraday' require 'uri' diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 7384db8..512e90d 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'vmfloaty/errors' require 'vmfloaty/http' require 'faraday' @@ -24,15 +26,7 @@ class NonstandardPooler conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - os_string = '' - os_type.each do |os, num| - num.times do |_i| - os_string << os + '+' - end - end - - os_string = os_string.chomp('+') - + os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') if os_string.empty? raise MissingParamError, 'No operating systems provided to obtain.' end diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 539e85b..a84035b 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'faraday' require 'vmfloaty/http' require 'json' @@ -37,15 +39,7 @@ class Pooler conn.headers['X-AUTH-TOKEN'] = token end - os_string = '' - os_type.each do |os,num| - num.times do |i| - os_string << os+'+' - end - end - - os_string = os_string.chomp('+') - + os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') if os_string.empty? raise MissingParamError, 'No operating systems provided to obtain.' end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index aa0dae0..e1ce49e 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'commander/user_interaction' require 'commander/command' require 'vmfloaty/utils' diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 4087d3a..6afc03e 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Ssh def self.which(cmd) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index fca7a32..763bb8f 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'vmfloaty/pooler' require 'vmfloaty/nonstandard_pooler' diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 4000441..1521a18 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Vmfloaty VERSION = '0.8.2'.freeze end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 982b1ed..558a0ad 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'vmfloaty' require 'webmock/rspec' diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 8a527ed..0869a33 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require_relative '../../lib/vmfloaty/auth' diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 7b03827..332e491 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'vmfloaty/utils' require 'vmfloaty/errors' diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 397e99a..43524d4 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require_relative '../../lib/vmfloaty/pooler' diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 78ba671..3f709ce 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../lib/vmfloaty/service' describe Service do diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 1885bfa..2ec858b 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'json' require 'commander/command' diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 4317b4a..fcbaaab 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $LOAD_PATH.push File.expand_path('../lib', __FILE__) require 'vmfloaty/version' From 0d95977db3dfba9cde5cae0e5799b81125363bc9 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 10:55:50 +1100 Subject: [PATCH 033/265] (rubocop) Disable Style/Documentation for now --- .rubocop.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..223211f --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,6 @@ +--- +AllCops: + TargetRubyVersion: 2.4 + +Style/Documentation: + Enabled: False From 42014ae39fa304bbb8f47b468c5639a6e9f89b84 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 10:56:46 +1100 Subject: [PATCH 034/265] (rubocop) Fix Style/RedundantReturn --- lib/vmfloaty/http.rb | 6 +++--- lib/vmfloaty/ssh.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index 71f955d..9d169b0 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -15,7 +15,7 @@ class Http return true end - return false + false end def self.get_conn(verbose, url) @@ -33,7 +33,7 @@ class Http faraday.adapter Faraday.default_adapter end - return conn + conn end def self.get_conn_with_auth(verbose, url, user, password) @@ -56,7 +56,7 @@ class Http faraday.adapter Faraday.default_adapter end - return conn + conn end end diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 6afc03e..c5c63c6 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -12,7 +12,7 @@ class Ssh return exe if File.executable?(exe) && !File.directory?(exe) } end - return nil + nil end def self.ssh(verbose, host_os, token, url) @@ -40,6 +40,6 @@ class Ssh else raise "Could not get vm from vmpooler:\n #{response}" end - return + nil end end From fcf7154a8b1ac4b761c9edfc8ffe0067ed6e160b Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:03:11 +1100 Subject: [PATCH 035/265] (rubocop) Style/HashSyntax to use hash_rockets for consistency --- .rubocop.yml | 2 + Gemfile | 2 +- Rakefile | 2 +- lib/vmfloaty.rb | 8 ++-- spec/vmfloaty/nonstandard_pooler_spec.rb | 54 ++++++++++++------------ 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 223211f..e336fa0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,3 +4,5 @@ AllCops: Style/Documentation: Enabled: False +Style/HashSyntax: + EnforcedStyle: hash_rockets diff --git a/Gemfile b/Gemfile index 26acfc9..adb75fe 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 'rspec', '~> 3.5.0' diff --git a/Rakefile b/Rakefile index 3d5a4dd..bcfae46 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 4a29e49..11bc196 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -152,10 +152,10 @@ class Vmfloaty 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? } diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 332e491..1491204 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -49,7 +49,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 @@ -57,7 +57,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 @@ -66,7 +66,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 @@ -134,8 +134,8 @@ BODY it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") - .with(headers: @post_request_headers) - .to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {}) + .with(:headers => @post_request_headers) + .to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {}) vm_hash = { 'solaris-11-sparc' => 1 } expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.to raise_error(AuthError) @@ -143,8 +143,8 @@ BODY it 'retrieves a single vm with a token' do stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") - .with(headers: @post_request_headers) - .to_return(status: 200, body: @retrieve_response_body_single, headers: {}) + .with(:headers => @post_request_headers) + .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) vm_hash = { 'solaris-11-sparc' => 1 } vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) @@ -155,8 +155,8 @@ BODY it 'retrieves a multiple vms with a token' do stub_request(:post,"#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc") - .with(headers: @post_request_headers) - .to_return(status: 200, body: @retrieve_response_body_many, headers: {}) + .with(:headers => @post_request_headers) + .to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {}) vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 } vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) @@ -175,10 +175,10 @@ BODY it 'raises an error if the user tries to modify an unsupported attribute' do stub_request(:put, 'https://nspooler.example.com/host/myfakehost'). - with(body: {'{}'=>true}, - headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'token-value'}). - to_return(status: 200, body: '', headers: {}) - details = { lifetime: 12 } + with(:body => {'{}'=>true}, + :headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'token-value'}). + to_return(:status => 200, :body => '', :headers => {}) + details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } .to raise_error(ModifyError) end @@ -186,11 +186,11 @@ BODY it 'modifies the reason of a vm' do modify_request_body = { '{"reserved_for_reason":"testing"}' => true } stub_request(:put, "#{@nspooler_url}/host/myfakehost") - .with(body: modify_request_body, - headers: @post_request_headers) - .to_return(status: 200, body: '{"ok": true}', headers: {}) + .with(:body => modify_request_body, + :headers => @post_request_headers) + .to_return(:status => 200, :body => '{"ok": true}', :headers => {}) - modify_hash = { reason: 'testing' } + modify_hash = { :reason => 'testing' } modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash) expect(modify_req['ok']).to be true end @@ -221,8 +221,8 @@ BODY it 'prints the status' do stub_request(:get, "#{@nspooler_url}/status") - .with(headers: @get_request_headers) - .to_return(status: 200, body: @status_response_body, headers: {}) + .with(:headers => @get_request_headers) + .to_return(:status => 200, :body => @status_response_body, :headers => {}) status = NonstandardPooler.status(false, @nspooler_url) expect(status).to be_an_instance_of Hash @@ -245,8 +245,8 @@ BODY it 'prints the summary' do stub_request(:get, "#{@nspooler_url}/summary") - .with(headers: @get_request_headers) - .to_return(status: 200, body: @status_response_body, headers: {}) + .with(:headers => @get_request_headers) + .to_return(:status => 200, :body => @status_response_body, :headers => {}) summary = NonstandardPooler.summary(false, @nspooler_url) expect(summary).to be_an_instance_of Hash @@ -271,8 +271,8 @@ BODY it 'makes a query about a vm' do stub_request(:get, "#{@nspooler_url}/host/sol10-11") - .with(headers: @get_request_headers_notoken) - .to_return(status: 200, body: @query_response_body, headers: {}) + .with(:headers => @get_request_headers_notoken) + .to_return(:status => 200, :body => @query_response_body, :headers => {}) query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11') expect(query_req).to be_an_instance_of Hash @@ -287,8 +287,8 @@ BODY it 'deletes a single existing vm' do stub_request(:delete, "#{@nspooler_url}/host/sol11-7") - .with(headers: @post_request_headers) - .to_return(status: 200, body: @delete_response_success, headers: {}) + .with(:headers => @post_request_headers) + .to_return(:status => 200, :body => @delete_response_success, :headers => {}) request = NonstandardPooler.delete(false, @nspooler_url, 'sol11-7', 'token-value') expect(request['sol11-7']['ok']).to be true @@ -296,8 +296,8 @@ BODY it 'does not delete a nonexistant vm' do stub_request(:delete, "#{@nspooler_url}/host/fakehost") - .with(headers: @post_request_headers) - .to_return(status: 401, body: @delete_response_failure, headers: {}) + .with(:headers => @post_request_headers) + .to_return(:status => 401, :body => @delete_response_failure, :headers => {}) request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value') expect(request['fakehost']['ok']).to be false From 874a6e7cf66b5c13eff410de6d261c306d5d105e Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:05:08 +1100 Subject: [PATCH 036/265] (rubocop) Fix Style/ClassCheck --- lib/vmfloaty/http.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index 9d169b0..33e4f19 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -11,7 +11,7 @@ class Http uri = URI.parse(url) - if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS) + if uri.is_a?(URI::HTTP) or uri.is_a?(URI::HTTPS) return true end From 79f764560d7e18e2a5d1f1008b5117dfe540b5be Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:06:05 +1100 Subject: [PATCH 037/265] (rubocop) Fix Style/AndOr --- lib/vmfloaty.rb | 4 ++-- lib/vmfloaty/http.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 11bc196..2d587e2 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -52,7 +52,7 @@ class Vmfloaty max_pool_request = 5 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 'Try again with `floaty get --force`' exit 1 @@ -144,7 +144,7 @@ class Vmfloaty hostname = args[0] modify_all = options.all - if hostname.nil? and !modify_all + if hostname.nil? && !modify_all STDERR.puts 'ERROR: Provide a hostname or specify --all.' exit 1 end diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index 33e4f19..bb7636e 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -11,7 +11,7 @@ class Http uri = URI.parse(url) - if uri.is_a?(URI::HTTP) or uri.is_a?(URI::HTTPS) + if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS) return true end From d95c6946b8940dad24c6294b958be506a40ea6ab Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:08:05 +1100 Subject: [PATCH 038/265] (rubocop) Fix Style/BracesAroundHashParameters --- spec/vmfloaty/service_spec.rb | 4 ++-- spec/vmfloaty/utils_spec.rb | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 3f709ce..17085af 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -45,14 +45,14 @@ describe Service do describe '#delete_token' do it 'deletes a token' do - service = Service.new(MockOptions.new,{'user' => 'first.last', 'url' => 'http://default.url'}) + service = Service.new(MockOptions.new,'user' => 'first.last', 'url' => 'http://default.url') allow(Commander::UI).to(receive(:password) .with('Enter your pooler service password:', '*') .and_return('hunter2')) allow(Auth).to(receive(:delete_token) .with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value') .and_return('ok' => true)) - expect(service.delete_token(nil, 'token-value')).to eql({'ok' => true}) + expect(service.delete_token(nil, 'token-value')).to eql('ok' => true) end end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 2ec858b..12c86ee 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -114,27 +114,27 @@ 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'}) - expected = config.merge({'url' => 'http://alternate.url', 'token' => 'alternate-token'}) + options = MockOptions.new(:url => 'http://alternate.url', :token => 'alternate-token') + expected = config.merge('url' => 'http://alternate.url', 'token' => 'alternate-token') expect(Utils.get_service_config(config, options)).to include expected end end @@ -172,7 +172,7 @@ describe Utils do expect(Utils).to receive(:puts).with(output) - service = Service.new(MockOptions.new, {'url' => url}) + service = Service.new(MockOptions.new, 'url' => url) allow(service).to receive(:query) .with(nil, hostname) .and_return(response_body) @@ -198,7 +198,7 @@ describe Utils do expect(Utils).to receive(:puts).with(output) - service = Service.new(MockOptions.new, {'url' => url}) + service = Service.new(MockOptions.new, 'url' => url) allow(service).to receive(:query) .with(nil, hostname) .and_return(response_body) @@ -219,7 +219,7 @@ describe Utils do expect(Utils).to receive(:puts).with(output) - service = Service.new(MockOptions.new, {'url' => url, 'type' => 'ns'}) + service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') allow(service).to receive(:query) .with(nil, hostname) .and_return(response_body) @@ -240,7 +240,7 @@ describe Utils do expect(Utils).to receive(:puts).with(output) - service = Service.new(MockOptions.new, {'url' => url, 'type' => 'ns'}) + service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') allow(service).to receive(:query) .with(nil, hostname) .and_return(response_body) From c7c8e48e2f41d3f02ffb99bf019164cee41cb617 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:10:52 +1100 Subject: [PATCH 039/265] (rubocop) Fix Style/ExpandPathArguments --- Rakefile | 2 +- bin/floaty | 2 +- vmfloaty.gemspec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index bcfae46..bde93cf 100644 --- a/Rakefile +++ b/Rakefile @@ -11,7 +11,7 @@ $stdout.sync = true $stderr.sync = true # Change to the directory of this file. -Dir.chdir(File.expand_path('../', __FILE__)) +Dir.chdir(File.expand_path(__dir__)) # This installs the tasks that help with gem creation and # publishing. diff --git a/bin/floaty b/bin/floaty index 1a1b0be..5ab2e1f 100755 --- a/bin/floaty +++ b/bin/floaty @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # frozen_string_literal: true -$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) +$LOAD_PATH.unshift(File.expand_path('../lib', __dir__)) require 'vmfloaty' diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index fcbaaab..455fce0 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -1,6 +1,6 @@ # frozen_string_literal: true -$LOAD_PATH.push File.expand_path('../lib', __FILE__) +$LOAD_PATH.push File.expand_path('lib', __dir__) require 'vmfloaty/version' Gem::Specification.new do |s| From 7bafee35a7e4edd2be7d22dbcf80f22ab217a20c Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:14:23 +1100 Subject: [PATCH 040/265] (rubocop) Fix Style/IfUnlessModifier --- lib/vmfloaty.rb | 8 ++------ lib/vmfloaty/auth.rb | 8 ++------ lib/vmfloaty/http.rb | 24 ++++++------------------ lib/vmfloaty/nonstandard_pooler.rb | 4 +--- lib/vmfloaty/pooler.rb | 8 ++------ lib/vmfloaty/ssh.rb | 4 +--- lib/vmfloaty/utils.rb | 4 +--- 7 files changed, 15 insertions(+), 45 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 2d587e2..17947d9 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -212,9 +212,7 @@ class Vmfloaty # Confirm deletion puts confirmed = true - unless force - confirmed = agree('Delete all these VMs? [y/N]') - end + confirmed = agree('Delete all these VMs? [y/N]') unless force if confirmed response = service.delete(verbose, running_vms) response.each do |hostname, result| @@ -381,9 +379,7 @@ class Vmfloaty puts result when 'status' token_value = options.token - if token_value.nil? - token_value = args[1] - end + token_value = args[1] if token_value.nil? status = service.token_status(verbose, token_value) puts status when nil diff --git a/lib/vmfloaty/auth.rb b/lib/vmfloaty/auth.rb index bbe7425..091b7c2 100644 --- a/lib/vmfloaty/auth.rb +++ b/lib/vmfloaty/auth.rb @@ -20,9 +20,7 @@ class Auth end def self.delete_token(verbose, url, user, password, token) - if token.nil? - raise TokenError, 'You did not provide a token' - end + raise TokenError, 'You did not provide a token' if token.nil? conn = Http.get_conn_with_auth(verbose, url, user, password) @@ -36,9 +34,7 @@ class Auth end def self.token_status(verbose, url, token) - if token.nil? - raise TokenError, 'You did not provide a token' - end + raise TokenError, 'You did not provide a token' if token.nil? conn = Http.get_conn(verbose, url) diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index bb7636e..860df2b 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -11,21 +11,15 @@ class Http uri = URI.parse(url) - if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS) - return true - end + return true if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS) false end def self.get_conn(verbose, url) - if url.nil? - raise 'Did not provide a url to connect to' - end + raise 'Did not provide a url to connect to' if url.nil? - unless is_url(url) - url = "https://#{url}" - end + url = "https://#{url}" unless is_url(url) conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday| faraday.request :url_encoded @@ -37,17 +31,11 @@ class Http end def self.get_conn_with_auth(verbose, url, user, password) - if url.nil? - raise 'Did not provide a url to connect to' - end + raise 'Did not provide a url to connect to' if url.nil? - if user.nil? - raise 'You did not provide a user to authenticate with' - end + raise 'You did not provide a user to authenticate with' if user.nil? - unless is_url(url) - url = "https://#{url}" - end + url = "https://#{url}" unless is_url(url) conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday| faraday.request :url_encoded diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 512e90d..aacb6bb 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -94,9 +94,7 @@ class NonstandardPooler response_body = {} - unless hosts.is_a? Array - hosts = hosts.split(',') - end + hosts = hosts.split(',') unless hosts.is_a? Array hosts.each do |host| response = conn.delete "host/#{host}" res_body = JSON.parse(response.body) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index a84035b..2c0b934 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -35,9 +35,7 @@ class Pooler # Developers can use `Utils.generate_os_hash` to # generate the os_type param. conn = Http.get_conn(verbose, url) - if token - conn.headers['X-AUTH-TOKEN'] = token - end + conn.headers['X-AUTH-TOKEN'] = token if token os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') if os_string.empty? @@ -106,9 +104,7 @@ class Pooler conn = Http.get_conn(verbose, url) - if token - conn.headers['X-AUTH-TOKEN'] = token - end + conn.headers['X-AUTH-TOKEN'] = token if token response_body = {} diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index c5c63c6..848d054 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -17,9 +17,7 @@ class Ssh def self.ssh(verbose, host_os, token, url) ssh_path = which('ssh') - if !ssh_path - raise 'Could not determine path to ssh' - end + raise 'Could not determine path to ssh' if !ssh_path os_types = {} os_types[host_os] = 1 diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 763bb8f..b42bfaa 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -41,9 +41,7 @@ class Utils response_body.each do |os, value| hostnames = Array(value['hostname']) - if domain - hostnames.map! {|host| "#{host}.#{domain}"} - end + hostnames.map! {|host| "#{host}.#{domain}"} if domain result[os] = hostnames end From 12c179504669ad8c73ece18758aaf68c1c416a1e Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:16:25 +1100 Subject: [PATCH 041/265] (rubocop) Fix Style/RescueStandardError --- lib/vmfloaty/conf.rb | 2 +- lib/vmfloaty/utils.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb index a232f8d..b1bfef1 100644 --- a/lib/vmfloaty/conf.rb +++ b/lib/vmfloaty/conf.rb @@ -8,7 +8,7 @@ class Conf conf = {} begin conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml") - rescue + rescue StandardError STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" end conf diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index b42bfaa..9d0cc61 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -103,7 +103,7 @@ class Utils else raise "Invalid service type #{service.type}" end - rescue => e + rescue StandardError => e STDERR.puts("Something went wrong while trying to gather information on #{hostname}:") STDERR.puts(e) end @@ -128,7 +128,7 @@ class Utils missing = max - ready - pending char = 'o' puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}" - rescue => e + rescue StandardError => e puts "#{name.ljust(width)} #{e.red}" end end @@ -147,7 +147,7 @@ class Utils missing = max - ready - pending char = 'o' puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}" - rescue => e + rescue StandardError => e puts "#{name.ljust(width)} #{e.red}" end end From 5ad213075b2a3b4187271a764c5f22334c1bb306 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:17:55 +1100 Subject: [PATCH 042/265] (rubocop) Fix Style/StringLiteralsInInterpolation --- lib/vmfloaty/ssh.rb | 2 +- lib/vmfloaty/utils.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 848d054..b982527 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -29,7 +29,7 @@ class Ssh user = 'root' end - hostname = "#{response[host_os]["hostname"]}.#{response["domain"]}" + hostname = "#{response[host_os]['hostname']}.#{response['domain']}" cmd = "#{ssh_path} #{user}@#{hostname}" # TODO: Should this respect more ssh settings? Can it be configured diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 9d0cc61..1759396 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -91,7 +91,7 @@ class Utils end duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] - puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(", ")})" + puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" From d25732b9504342ae4515312589ec45dc57dbe5be Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:19:13 +1100 Subject: [PATCH 043/265] (rubocop) Fix Style/NegatedIf --- lib/vmfloaty/ssh.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index b982527..3642e49 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -17,7 +17,7 @@ class Ssh def self.ssh(verbose, host_os, token, url) ssh_path = which('ssh') - raise 'Could not determine path to ssh' if !ssh_path + raise 'Could not determine path to ssh' unless ssh_path os_types = {} os_types[host_os] = 1 From 397bbd4dcede934e65399fb38120a6c932d7b31d Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:20:02 +1100 Subject: [PATCH 044/265] (rubocop) Fix Style/RedundantFreeze --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 1521a18..5bc74da 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.8.2'.freeze + VERSION = '0.8.2' end From cdb9b0ca3d2172afe18422e9ea0a5a2be7a03ebb Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:21:53 +1100 Subject: [PATCH 045/265] (rubocop) Fix Style/NestedParenthesizedCalls --- spec/vmfloaty/utils_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 12c86ee..7450960 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -79,7 +79,7 @@ describe Utils do end 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 From 095ac9e75e28fd231a81e2508aac7638ebc84c47 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:24:18 +1100 Subject: [PATCH 046/265] (rubocop) Fix Style/WordArray --- lib/vmfloaty/utils.rb | 2 +- spec/vmfloaty/pooler_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 1759396..12b5047 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -165,7 +165,7 @@ class Utils end def self.get_service_object(type = '') - nspooler_strings = ['ns', 'nspooler', 'nonstandard', 'nonstandard_pooler'] + nspooler_strings = %w[ns nspooler nonstandard nonstandard_pooler] if nspooler_strings.include? type.downcase NonstandardPooler else diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 43524d4..1f6e8fb 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -81,7 +81,7 @@ describe Pooler do expect(vm_req).to be_an_instance_of Hash expect(vm_req['ok']).to equal true expect(vm_req['debian-7-i386']['hostname']).to be_an_instance_of Array - expect(vm_req['debian-7-i386']['hostname']).to eq ['sc0o4xqtodlul5w', '4m4dkhqiufnjmxy'] + expect(vm_req['debian-7-i386']['hostname']).to eq %w[sc0o4xqtodlul5w 4m4dkhqiufnjmxy] expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q' end end From 1aea79a9a1781982decf41006110fb0a94a62b10 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:25:02 +1100 Subject: [PATCH 047/265] (rubocop) Fix Style/SymbolArray --- lib/vmfloaty/nonstandard_pooler.rb | 2 +- lib/vmfloaty/pooler.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index aacb6bb..0e1e449 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -50,7 +50,7 @@ class NonstandardPooler end modify_hash.each do |key, value| - unless [:reason, :reserved_for_reason].include? key + unless %i[reason reserved_for_reason].include? key raise ModifyError, "Configured service type does not support modification of #{key}" end end diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 2c0b934..023f971 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -61,7 +61,7 @@ class Pooler end modify_hash.keys.each do |key| - unless [:tags, :lifetime, :disk].include? key + unless %i[tags lifetime disk].include? key raise ModifyError, "Configured service type does not support modification of #{key}." end end From 58f64b284362922dc3952904ae92d4724d80dbf3 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:27:53 +1100 Subject: [PATCH 048/265] (rubocop) Fix Style/TrailingCommaInHashLiteral --- .rubocop.yml | 2 ++ lib/vmfloaty.rb | 2 +- lib/vmfloaty/utils.rb | 2 +- spec/vmfloaty/nonstandard_pooler_spec.rb | 4 ++-- spec/vmfloaty/service_spec.rb | 4 ++-- spec/vmfloaty/utils_spec.rb | 22 +++++++++++----------- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e336fa0..4136241 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -6,3 +6,5 @@ Style/Documentation: Enabled: False Style/HashSyntax: EnforcedStyle: hash_rockets +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 17947d9..410e1dd 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -155,7 +155,7 @@ class Vmfloaty :lifetime => options.lifetime, :disk => options.disk, :tags => tags, - :reason => options.reason + :reason => options.reason, } modify_hash.delete_if { |_, value| value.nil? } diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 12b5047..6747524 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -179,7 +179,7 @@ class Utils 'url' => config['url'], 'user' => config['user'], 'token' => config['token'], - 'type' => config['type'] || 'vmpooler' + 'type' => config['type'] || 'vmpooler', } if config['services'] diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 1491204..3185da1 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -12,13 +12,13 @@ describe NonstandardPooler do 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', - 'X-Auth-Token' => 'token-value' + 'X-Auth-Token' => 'token-value', } @get_request_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' => 'token-value' + 'X-Auth-Token' => 'token-value', } @get_request_headers_notoken = @get_request_headers.tap do |headers| headers.delete('X-Auth-Token') diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 17085af..bdffb45 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -60,7 +60,7 @@ 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) @@ -69,7 +69,7 @@ describe Service do 'user' => config['user'], 'created' => '2017-09-22 02:04:18 +0000', 'last_accessed' => '2017-09-22 02:04:28 +0000', - 'reserved_hosts' => [] + 'reserved_hosts' => [], } allow(Auth).to(receive(:token_status) .with(nil, config['url'], 'token-value') diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 7450960..9836b85 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -47,11 +47,11 @@ describe Utils 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'] + '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'] + 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'], } @vmpooler_output = <<-OUT.chomp - dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) @@ -95,14 +95,14 @@ describe Utils do 'vm' => { 'url' => 'http://vmpooler.url', 'user' => 'first.last.vmpooler', - 'token' => 'vmpooler-token' + 'token' => 'vmpooler-token', }, 'ns' => { 'url' => 'http://nspooler.url', 'user' => 'first.last.nspooler', - 'token' => 'nspooler-token' - } - } + 'token' => 'nspooler-token', + }, + }, } end @@ -166,7 +166,7 @@ describe Utils do 'running' => 9.66, 'state' => 'running', '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)' @@ -189,10 +189,10 @@ describe Utils do 'state' => 'running', 'tags' => { 'user' => 'bob', - 'role' => 'agent' + 'role' => 'agent', }, '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)' @@ -213,7 +213,7 @@ describe Utils do 'os_triple' => 'solaris-11-sparc', 'reserved_by_user' => 'first.last', '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)' @@ -234,7 +234,7 @@ describe Utils do 'os_triple' => 'solaris-11-sparc', 'reserved_by_user' => 'first.last', '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)' From 0e5dd9b7db405b58eeb5e4256fbeb42988338845 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:29:31 +1100 Subject: [PATCH 049/265] (rubocop) Fix Style/TrailingCommaInArrayLiteral --- .rubocop.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 4136241..7be7272 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,3 +8,5 @@ Style/HashSyntax: EnforcedStyle: hash_rockets Style/TrailingCommaInHashLiteral: EnforcedStyleForMultiline: comma +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma From 692577a486870e167569fb1cbc2e963463c0ddf9 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:30:58 +1100 Subject: [PATCH 050/265] (rubocop) Fix Style/TrailingCommaInArguments --- .rubocop.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 7be7272..e0a6614 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -10,3 +10,5 @@ Style/TrailingCommaInHashLiteral: EnforcedStyleForMultiline: comma Style/TrailingCommaInArrayLiteral: EnforcedStyleForMultiline: comma +Style/TrailingCommaInArguments: + EnforcedStyleForMultiline: comma From 613121f34dd170b4997810d55f93741ef554fc52 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:33:02 +1100 Subject: [PATCH 051/265] (rubocop) Fix Style/BlockDelimiters --- lib/vmfloaty/ssh.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 3642e49..4e25965 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -7,10 +7,10 @@ class Ssh exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| - exts.each { |ext| + exts.each do |ext| exe = File.join(path, "#{cmd}#{ext}") return exe if File.executable?(exe) && !File.directory?(exe) - } + end end nil end From dec621e9b8a6792fd3709f35bc689c65599d5315 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:37:16 +1100 Subject: [PATCH 052/265] (rubocop) Fix Style/ConditionalAssignment --- lib/vmfloaty/pooler.rb | 10 +++++----- lib/vmfloaty/ssh.rb | 6 +----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 023f971..8695fb4 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -12,11 +12,11 @@ class Pooler response = conn.get 'vm' response_body = JSON.parse(response.body) - if os_filter - hosts = response_body.select { |i| i[/#{os_filter}/] } - else - hosts = response_body - end + hosts = if os_filter + response_body.select { |i| i[/#{os_filter}/] } + else + response_body + end hosts end diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 4e25965..bf9cb76 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -23,11 +23,7 @@ class Ssh response = Pooler.retrieve(verbose, os_types, token, url) if response['ok'] == true - if host_os =~ /win/ - user = 'Administrator' - else - user = 'root' - end + user = host_os =~ /win/ ? 'Administrator' : 'root' hostname = "#{response[host_os]['hostname']}.#{response['domain']}" cmd = "#{ssh_path} #{user}@#{hostname}" From 6c4fe8384c3ece08b55a334ef8733ac486fd02d2 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:41:25 +1100 Subject: [PATCH 053/265] (rubocop) Fix Style/IfInsideElse --- lib/vmfloaty/utils.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 6747524..a145003 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -190,12 +190,12 @@ class Utils service_config.merge! values else # If the user provided a service name at the command line, use that service if posible, or fail - if config['services'][options.service] - # If the service is configured but some values are missing, use the top-level defaults to fill them in - service_config.merge! config['services'][options.service] - else + 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] end end From b7b08c9c9e28147cff7de4365a2e0b320fd3fec9 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 11:45:06 +1100 Subject: [PATCH 054/265] (rubocop) Fix Style/MissingRespondToMissing --- lib/vmfloaty/service.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index e1ce49e..899f651 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -23,6 +23,10 @@ class Service end end + def respond_to_missing?(m, *) + @service_object.respond_to?(m) || super + end + def url @config['url'] end From 6a771a8d7698bc40a479c93ea8afd0f534a5f846 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:22:02 +1100 Subject: [PATCH 055/265] (rubocop) Fix Style/GuardClause --- lib/vmfloaty/auth.rb | 21 ++++++--------------- lib/vmfloaty/ssh.rb | 17 +++++++---------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/lib/vmfloaty/auth.rb b/lib/vmfloaty/auth.rb index 091b7c2..a1fdd60 100644 --- a/lib/vmfloaty/auth.rb +++ b/lib/vmfloaty/auth.rb @@ -12,11 +12,8 @@ class Auth resp = conn.post 'token' res_body = JSON.parse(resp.body) - if res_body['ok'] - return res_body['token'] - else - raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}" - end + return res_body['token'] if res_body['ok'] + raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}" end def self.delete_token(verbose, url, user, password, token) @@ -26,11 +23,8 @@ class Auth response = conn.delete "token/#{token}" res_body = JSON.parse(response.body) - if res_body['ok'] - return res_body - else - raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}" - end + return res_body if res_body['ok'] + raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}" end def self.token_status(verbose, url, token) @@ -41,10 +35,7 @@ class Auth response = conn.get "token/#{token}" res_body = JSON.parse(response.body) - if res_body['ok'] - return res_body - else - raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}" - end + return res_body if res_body['ok'] + raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}" end end diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index bf9cb76..e20d84d 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -22,18 +22,15 @@ class Ssh os_types[host_os] = 1 response = Pooler.retrieve(verbose, os_types, token, url) - if response['ok'] == true - user = host_os =~ /win/ ? 'Administrator' : 'root' + raise "Could not get vm from vmpooler:\n #{response}" unless response['ok'] + user = host_os =~ /win/ ? 'Administrator' : 'root' - hostname = "#{response[host_os]['hostname']}.#{response['domain']}" - cmd = "#{ssh_path} #{user}@#{hostname}" + hostname = "#{response[host_os]['hostname']}.#{response['domain']}" + cmd = "#{ssh_path} #{user}@#{hostname}" - # TODO: Should this respect more ssh settings? Can it be configured - # by users ssh config and does this respect those settings? - Kernel.exec(cmd) - else - raise "Could not get vm from vmpooler:\n #{response}" - end + # TODO: Should this respect more ssh settings? Can it be configured + # by users ssh config and does this respect those settings? + Kernel.exec(cmd) nil end end From b16e3fc79284889b9ad573a38b94dc41f807cef9 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:26:38 +1100 Subject: [PATCH 056/265] (rubocop) Fix Layout/SpaceAroundOperators --- lib/vmfloaty/utils.rb | 4 ++-- spec/vmfloaty/auth_spec.rb | 12 ++++++------ spec/vmfloaty/nonstandard_pooler_spec.rb | 4 ++-- spec/vmfloaty/pooler_spec.rb | 24 ++++++++++++------------ spec/vmfloaty/utils_spec.rb | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index a145003..ef20802 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -127,7 +127,7 @@ class Utils pending = pool['pending'] missing = max - ready - pending 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 StandardError => e puts "#{name.ljust(width)} #{e.red}" end @@ -146,7 +146,7 @@ class Utils 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}" + puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" rescue StandardError => e puts "#{name.ljust(width)} #{e.red}" end diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 0869a33..dc7f66d 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'). - 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 => {}) token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password') @@ -25,7 +25,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'). - 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 => {}) expect{ Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) @@ -40,7 +40,7 @@ describe Pooler do it 'deletes the specified token' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). to_return(:status => 200, :body => @delete_token_response, :headers => {}) expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) @@ -48,7 +48,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect{ Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) @@ -67,7 +67,7 @@ describe Pooler do it 'checks the status of a token' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). to_return(:status => 200, :body => @token_status_response, :headers => {}) expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response) @@ -75,7 +75,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect{ Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 3185da1..70507e3 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -175,8 +175,8 @@ BODY it 'raises an error if the user tries to modify an unsupported attribute' do stub_request(:put, 'https://nspooler.example.com/host/myfakehost'). - with(:body => {'{}'=>true}, - :headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'token-value'}). + with(:body => {'{}' => true}, + :headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value'}). to_return(:status => 200, :body => '', :headers => {}) details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 1f6e8fb..c5bdf0d 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -48,7 +48,7 @@ describe Pooler do it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). to_return(:status => 401, :body => '{"ok":false}', :headers => {}) vm_hash = {} @@ -58,7 +58,7 @@ describe Pooler do it 'retrieves a single vm with a token' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) vm_hash = {} @@ -71,7 +71,7 @@ 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 => {'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 => {}) vm_hash = {} @@ -99,8 +99,8 @@ describe Pooler do it 'modifies the TTL of a vm' do modify_hash = { :lifetime => 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:body => {'{"lifetime":12}'=>true}, - :headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). + with(:body => {'{"lifetime":12}' => true}, + :headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) @@ -111,12 +111,12 @@ describe Pooler do describe '#delete' do before :each do @delete_response_body_success = '{"ok":true}' - @delete_response = {'fq6qlpjlsskycq6'=>{'ok'=>true}} + @delete_response = {'fq6qlpjlsskycq6' => {'ok' => true}} end it 'deletes a specified vm' do stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response @@ -135,7 +135,7 @@ describe Pooler do it 'prints the status' do stub_request(:get, "#{@vmpooler_url}/status"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). to_return(:status => 200, :body => @status_response_body, :headers => {}) status = Pooler.status(false, @vmpooler_url) @@ -159,7 +159,7 @@ describe Pooler do it 'makes a query about a vm' do stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). to_return(:status => 200, :body => @query_response_body, :headers => {}) query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6') @@ -174,7 +174,7 @@ describe Pooler do it 'makes a snapshot for a single vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot"). - with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). + with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') @@ -189,7 +189,7 @@ 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 => {'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 => {}) revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') @@ -213,7 +213,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 => {'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) expect(disk_req['ok']).to be true diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 9836b85..b9aca22 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -9,7 +9,7 @@ describe Utils do describe '#standardize_hostnames' do before :each do - @vmpooler_response_body ='{ + @vmpooler_response_body = '{ "ok": true, "domain": "delivery.mycompany.net", "ubuntu-1610-x86_64": { @@ -141,7 +141,7 @@ describe Utils do describe '#generate_os_hash' do before :each do - @host_hash = {'centos'=>1, 'debian'=>5, 'windows'=>1} + @host_hash = {'centos' => 1, 'debian' => 5, 'windows' => 1} end it 'takes an array of os arguments and returns a formatted hash' do From 7cd0256a97e1b4c0ec2f356d4fd4bf021e19ed3e Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:28:17 +1100 Subject: [PATCH 057/265] (rubocop) Fix Layout/SpaceInsideBlockBraces --- lib/vmfloaty.rb | 2 +- lib/vmfloaty/utils.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 410e1dd..428a73f 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -51,7 +51,7 @@ class Vmfloaty os_types = Utils.generate_os_hash(args) 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? && ! force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts 'Try again with `floaty get --force`' diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index ef20802..7bfdd52 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -41,7 +41,7 @@ class Utils response_body.each do |os, value| hostnames = Array(value['hostname']) - hostnames.map! {|host| "#{host}.#{domain}"} if domain + hostnames.map! { |host| "#{host}.#{domain}" } if domain result[os] = hostnames end @@ -87,7 +87,7 @@ class Utils when 'Pooler' tag_pairs = [] unless host_data['tags'].nil? - tag_pairs = host_data['tags'].map {|key, value| "#{key}: #{value}"} + tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } end duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] @@ -117,7 +117,7 @@ class Utils when 'Pooler' message = status_response['status']['message'] 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 pools.each do |name, pool| @@ -136,7 +136,7 @@ class Utils when 'NonstandardPooler' pools = status_response pools.delete 'ok' - pools.select! {|_, pool| pool['available_hosts'] < pool['total_hosts']} unless verbose + pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose width = pools.keys.map(&:length).max pools.each do |name, pool| From eb0d31260fe26815a74568962ba24ea2f4ccd7fb Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:30:26 +1100 Subject: [PATCH 058/265] (rubocop) Fix Layout/SpaceAroundEqualsInParameterDefault --- lib/vmfloaty/errors.rb | 8 ++++---- lib/vmfloaty/pooler.rb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty/errors.rb b/lib/vmfloaty/errors.rb index 098a94c..28891cc 100644 --- a/lib/vmfloaty/errors.rb +++ b/lib/vmfloaty/errors.rb @@ -1,25 +1,25 @@ # frozen_string_literal: true class AuthError < StandardError - def initialize(msg='Could not authenticate to pooler') + def initialize(msg = 'Could not authenticate to pooler') super end end class TokenError < StandardError - def initialize(msg='Could not do operation with token provided') + def initialize(msg = 'Could not do operation with token provided') super end end class MissingParamError < StandardError - def initialize(msg='Argument provided to function is missing') + def initialize(msg = 'Argument provided to function is missing') super end end class ModifyError < StandardError - def initialize(msg='Could not modify VM') + def initialize(msg = 'Could not modify VM') super end end diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 8695fb4..8eceb8c 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -6,7 +6,7 @@ require 'json' require 'vmfloaty/errors' class Pooler - def self.list(verbose, url, os_filter=nil) + def self.list(verbose, url, os_filter = nil) conn = Http.get_conn(verbose, url) response = conn.get 'vm' From b8971c040a5800b476bcae9ffd8a94894fcee65b Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:32:05 +1100 Subject: [PATCH 059/265] (rubocop) Fix Layout/SpaceInsideLiteralHashBraces --- lib/vmfloaty/http.rb | 4 ++-- spec/vmfloaty/auth_spec.rb | 12 ++++++------ spec/vmfloaty/nonstandard_pooler_spec.rb | 4 ++-- spec/vmfloaty/pooler_spec.rb | 24 ++++++++++++------------ spec/vmfloaty/service_spec.rb | 2 +- spec/vmfloaty/utils_spec.rb | 10 +++++----- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index 860df2b..b120538 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -21,7 +21,7 @@ class Http url = "https://#{url}" unless is_url(url) - conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday| + conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday| faraday.request :url_encoded faraday.response :logger if verbose faraday.adapter Faraday.default_adapter @@ -37,7 +37,7 @@ class Http url = "https://#{url}" unless is_url(url) - conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday| + conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday| faraday.request :url_encoded faraday.request :basic_auth, user, password faraday.response :logger if verbose diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index dc7f66d..817ed28 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'). - 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 => {}) token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password') @@ -25,7 +25,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'). - 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 => {}) expect{ Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) @@ -40,7 +40,7 @@ describe Pooler do it 'deletes the specified token' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 200, :body => @delete_token_response, :headers => {}) expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) @@ -48,7 +48,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect{ Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) @@ -67,7 +67,7 @@ describe Pooler do it 'checks the status of a token' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 200, :body => @token_status_response, :headers => {}) expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response) @@ -75,7 +75,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect{ Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 70507e3..cc0f6c0 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -175,8 +175,8 @@ BODY it 'raises an error if the user tries to modify an unsupported attribute' do stub_request(:put, 'https://nspooler.example.com/host/myfakehost'). - with(:body => {'{}' => true}, - :headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value'}). + with(:body => { '{}' => true }, + :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' }). to_return(:status => 200, :body => '', :headers => {}) details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index c5bdf0d..c973930 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -48,7 +48,7 @@ describe Pooler do it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 401, :body => '{"ok":false}', :headers => {}) vm_hash = {} @@ -58,7 +58,7 @@ describe Pooler do it 'retrieves a single vm with a token' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) vm_hash = {} @@ -71,7 +71,7 @@ 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 => {'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 => {}) vm_hash = {} @@ -99,8 +99,8 @@ describe Pooler do it 'modifies the TTL of a vm' do modify_hash = { :lifetime => 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:body => {'{"lifetime":12}' => true}, - :headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). + with(:body => { '{"lifetime":12}' => true }, + :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) @@ -111,12 +111,12 @@ describe Pooler do describe '#delete' do before :each do @delete_response_body_success = '{"ok":true}' - @delete_response = {'fq6qlpjlsskycq6' => {'ok' => true}} + @delete_response = { 'fq6qlpjlsskycq6' => { 'ok' => true } } end it 'deletes a specified vm' do stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response @@ -135,7 +135,7 @@ describe Pooler do it 'prints the status' do stub_request(:get, "#{@vmpooler_url}/status"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 200, :body => @status_response_body, :headers => {}) status = Pooler.status(false, @vmpooler_url) @@ -159,7 +159,7 @@ describe Pooler do it 'makes a query about a vm' do stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 200, :body => @query_response_body, :headers => {}) query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6') @@ -174,7 +174,7 @@ describe Pooler do it 'makes a snapshot for a single vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot"). - with(:headers => {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile'}). + with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') @@ -189,7 +189,7 @@ 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 => {'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 => {}) revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') @@ -213,7 +213,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 => {'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) expect(disk_req['ok']).to be true diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index bdffb45..7e9812a 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -7,7 +7,7 @@ describe Service do describe '#initialize' do it 'store configuration options' do options = MockOptions.new({}) - config = {'url' => 'http://example.url'} + config = { 'url' => 'http://example.url' } service = Service.new(options, config) expect(service.config).to include config end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index b9aca22..2caed14 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -141,7 +141,7 @@ describe Utils do describe '#generate_os_hash' do before :each do - @host_hash = {'centos' => 1, 'debian' => 5, 'windows' => 1} + @host_hash = { 'centos' => 1, 'debian' => 5, 'windows' => 1 } end it 'takes an array of os arguments and returns a formatted hash' do @@ -167,7 +167,7 @@ describe Utils do 'state' => 'running', 'ip' => '127.0.0.1', 'domain' => 'delivery.mycompany.net', - }} + } } output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)' expect(Utils).to receive(:puts).with(output) @@ -193,7 +193,7 @@ describe Utils do }, 'ip' => '127.0.0.1', 'domain' => 'delivery.mycompany.net', - }} + } } output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)' expect(Utils).to receive(:puts).with(output) @@ -214,7 +214,7 @@ describe Utils do 'reserved_by_user' => 'first.last', 'reserved_for_reason' => '', 'hours_left_on_reservation' => 35.89, - }} + } } output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)' expect(Utils).to receive(:puts).with(output) @@ -235,7 +235,7 @@ describe Utils do 'reserved_by_user' => 'first.last', 'reserved_for_reason' => 'testing', 'hours_left_on_reservation' => 35.89, - }} + } } output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)' expect(Utils).to receive(:puts).with(output) From fd753ba188480898aa9edc10b5e1082f646a4440 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:34:24 +1100 Subject: [PATCH 060/265] (rubocop) Fix Layout/SpaceBeforeBlockBraces --- lib/vmfloaty.rb | 2 +- spec/vmfloaty/auth_spec.rb | 10 +++++----- spec/vmfloaty/pooler_spec.rb | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 428a73f..a68fc26 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -51,7 +51,7 @@ class Vmfloaty os_types = Utils.generate_os_hash(args) 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? && ! force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts 'Try again with `floaty get --force`' diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 817ed28..1aacaae 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -28,7 +28,7 @@ describe Pooler do with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) - expect{ Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) + expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) end end @@ -51,11 +51,11 @@ describe Pooler do with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) - expect{ Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) + expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) end it 'raises a token error if no token provided' do - expect{ Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', nil) }.to raise_error(TokenError) + expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', nil) }.to raise_error(TokenError) end end @@ -78,11 +78,11 @@ describe Pooler do with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). to_return(:status => 500, :body => '{"ok":false}', :headers => {}) - expect{ Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) + expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) end it 'raises a token error if no token provided' do - expect{ Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError) + expect { Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError) end end end diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index c973930..304dd36 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -53,7 +53,7 @@ describe Pooler do vm_hash = {} vm_hash['debian-7-i386'] = 1 - expect{ Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError) + expect { Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError) end it 'retrieves a single vm with a token' do @@ -93,7 +93,7 @@ describe Pooler do end 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 it 'modifies the TTL of a vm' do @@ -123,7 +123,7 @@ describe Pooler do end 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 @@ -197,11 +197,11 @@ describe Pooler do end it "doesn't make a request to revert a vm if snapshot is not provided" do - expect{ Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6') + expect { Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6') end it 'raises a TokenError if no token was provided' do - expect{ Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError) + expect { Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError) end end @@ -220,7 +220,7 @@ describe Pooler do end 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 From 6f4039713698884e81d1174a3a7042db6d62d923 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:36:47 +1100 Subject: [PATCH 061/265] (rubocop) Fix Layout/DotPosition --- spec/vmfloaty/auth_spec.rb | 36 ++++++------ spec/vmfloaty/nonstandard_pooler_spec.rb | 8 +-- spec/vmfloaty/pooler_spec.rb | 72 ++++++++++++------------ 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 1aacaae..5133e37 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -15,18 +15,18 @@ describe Pooler do end it 'returns a token from vmpooler' do - stub_request(:post, 'https://first.last:password@vmpooler.example.com/token'). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 200, :body => @get_token_response, :headers => {}) + stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @get_token_response, :headers => {}) token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password') expect(token).to eq @token end it 'raises a token error if something goes wrong' do - stub_request(:post, 'https://first.last:password@vmpooler.example.com/token'). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) end @@ -39,17 +39,17 @@ describe Pooler do end it 'deletes the specified token' do - stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 200, :body => @delete_token_response, :headers => {}) + stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @delete_token_response, :headers => {}) expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) end it 'raises a token error if something goes wrong' do - stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y'). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) end @@ -66,17 +66,17 @@ describe Pooler do end it 'checks the status of a token' do - stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 200, :body => @token_status_response, :headers => {}) + stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @token_status_response, :headers => {}) expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response) end it 'raises a token error if something goes wrong' do - stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) end diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index cc0f6c0..4b60db9 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -174,10 +174,10 @@ BODY end it 'raises an error if the user tries to modify an unsupported attribute' do - stub_request(:put, 'https://nspooler.example.com/host/myfakehost'). - with(:body => { '{}' => true }, - :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' }). - to_return(:status => 200, :body => '', :headers => {}) + stub_request(:put, 'https://nspooler.example.com/host/myfakehost') + .with(:body => { '{}' => true }, + :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' }) + .to_return(:status => 200, :body => '', :headers => {}) details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } .to raise_error(ModifyError) diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 304dd36..eb52710 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -14,16 +14,16 @@ describe Pooler do end it 'returns a hash with operating systems from the pooler' do - stub_request(:get, "#{@vmpooler_url}/vm"). - to_return(:status => 200, :body => @list_response_body, :headers => {}) + stub_request(:get, "#{@vmpooler_url}/vm") + .to_return(:status => 200, :body => @list_response_body, :headers => {}) list = Pooler.list(false, @vmpooler_url, nil) expect(list).to be_an_instance_of Array end it 'filters operating systems based on the filter param' do - stub_request(:get, "#{@vmpooler_url}/vm"). - to_return(:status => 200, :body => @list_response_body, :headers => {}) + stub_request(:get, "#{@vmpooler_url}/vm") + .to_return(:status => 200, :body => @list_response_body, :headers => {}) list = Pooler.list(false, @vmpooler_url, 'deb') expect(list).to be_an_instance_of Array @@ -31,8 +31,8 @@ describe Pooler do end it 'returns nothing if the filter does not match' do - stub_request(:get, "#{@vmpooler_url}/vm"). - to_return(:status => 200, :body => @list_response_body, :headers => {}) + stub_request(:get, "#{@vmpooler_url}/vm") + .to_return(:status => 200, :body => @list_response_body, :headers => {}) list = Pooler.list(false, @vmpooler_url, 'windows') expect(list).to be_an_instance_of Array @@ -47,9 +47,9 @@ describe Pooler do end it 'raises an AuthError if the token is invalid' do - stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 401, :body => '{"ok":false}', :headers => {}) + stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 401, :body => '{"ok":false}', :headers => {}) vm_hash = {} vm_hash['debian-7-i386'] = 1 @@ -57,9 +57,9 @@ describe Pooler do end it 'retrieves a single vm with a token' do - stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) + stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) vm_hash = {} vm_hash['debian-7-i386'] = 1 @@ -70,9 +70,9 @@ describe Pooler do end it 'retrieves a multiple vms with a token' do - stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {}) + stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {}) vm_hash = {} vm_hash['debian-7-i386'] = 2 @@ -98,10 +98,10 @@ describe Pooler do it 'modifies the TTL of a vm' do modify_hash = { :lifetime => 12 } - stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:body => { '{"lifetime":12}' => true }, - :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) + stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") + .with(:body => { '{"lifetime":12}' => true }, + :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) expect(modify_req['ok']).to be true @@ -115,9 +115,9 @@ describe Pooler do end it 'deletes a specified vm' do - stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) + stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response end @@ -134,9 +134,9 @@ describe Pooler do end it 'prints the status' do - stub_request(:get, "#{@vmpooler_url}/status"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 200, :body => @status_response_body, :headers => {}) + stub_request(:get, "#{@vmpooler_url}/status") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @status_response_body, :headers => {}) status = Pooler.status(false, @vmpooler_url) expect(status).to be_an_instance_of Hash @@ -158,9 +158,9 @@ describe Pooler do end it 'makes a query about a vm' do - stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(:status => 200, :body => @query_response_body, :headers => {}) + stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @query_response_body, :headers => {}) query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6') expect(query_req).to be_an_instance_of Hash @@ -173,9 +173,9 @@ describe Pooler do end it 'makes a snapshot for a single vm' do - stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) + stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') expect(snapshot_req['ok']).to be true @@ -188,9 +188,9 @@ describe Pooler do end it 'makes a request to revert a vm from a snapshot' do - stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). - to_return(:status => 200, :body => @revert_response_body, :headers => {}) + stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .to_return(:status => 200, :body => @revert_response_body, :headers => {}) revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') expect(revert_req['ok']).to be true @@ -212,8 +212,8 @@ describe Pooler do end it 'makes a request to extend disk space of a vm' do - stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12"). - with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @disk_response_body_success, :headers => {}) + stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }). to_return(:status => 200, :body => @disk_response_body_success, :headers => {}) disk_req = Pooler.disk(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12) expect(disk_req['ok']).to be true From b2ac1ddf2ff53f62f8773885fb0dac672f195e54 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:39:47 +1100 Subject: [PATCH 062/265] (rubocop) Fix Layout/MultilineMethodCallIndentation --- spec/vmfloaty/auth_spec.rb | 8 ++++---- spec/vmfloaty/nonstandard_pooler_spec.rb | 6 +++--- spec/vmfloaty/utils_spec.rb | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 5133e37..f110359 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -16,8 +16,8 @@ describe Pooler do it 'returns a token from vmpooler' do stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) - .to_return(:status => 200, :body => @get_token_response, :headers => {}) + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @get_token_response, :headers => {}) token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password') expect(token).to eq @token @@ -25,8 +25,8 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) - .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) end diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 4b60db9..82eba9c 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -175,12 +175,12 @@ BODY 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 }, + .with(:body => { '{}' => true }, :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' }) - .to_return(:status => 200, :body => '', :headers => {}) + .to_return(:status => 200, :body => '', :headers => {}) details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } - .to raise_error(ModifyError) + .to raise_error(ModifyError) end it 'modifies the reason of a vm' do diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 2caed14..4f3e4ac 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -174,8 +174,8 @@ describe Utils do service = Service.new(MockOptions.new, 'url' => url) allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + .with(nil, hostname) + .and_return(response_body) Utils.pretty_print_hosts(nil, service, hostname) end @@ -200,8 +200,8 @@ describe Utils do service = Service.new(MockOptions.new, 'url' => url) allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + .with(nil, hostname) + .and_return(response_body) Utils.pretty_print_hosts(nil, service, hostname) end @@ -221,8 +221,8 @@ describe Utils do service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + .with(nil, hostname) + .and_return(response_body) Utils.pretty_print_hosts(nil, service, hostname) end @@ -242,8 +242,8 @@ describe Utils do service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + .with(nil, hostname) + .and_return(response_body) Utils.pretty_print_hosts(nil, service, hostname) end From edaa3e5645ec0ec5cfa54b6d05f8a9ff34ad5504 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:41:22 +1100 Subject: [PATCH 063/265] (rubocop) Fix Layout/EmptyLinesAroundBlockBody --- spec/vmfloaty/nonstandard_pooler_spec.rb | 1 - spec/vmfloaty/service_spec.rb | 2 -- spec/vmfloaty/utils_spec.rb | 1 - 3 files changed, 4 deletions(-) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 82eba9c..c01d79e 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -23,7 +23,6 @@ describe NonstandardPooler do @get_request_headers_notoken = @get_request_headers.tap do |headers| headers.delete('X-Auth-Token') end - end describe '#list' do diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 7e9812a..55e4fb3 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -3,7 +3,6 @@ require_relative '../../lib/vmfloaty/service' describe Service do - describe '#initialize' do it 'store configuration options' do options = MockOptions.new({}) @@ -77,5 +76,4 @@ describe Service do expect(service.token_status(nil, 'token-value')).to eql(status) end end - end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 4f3e4ac..6933aeb 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -6,7 +6,6 @@ require 'commander/command' require_relative '../../lib/vmfloaty/utils' describe Utils do - describe '#standardize_hostnames' do before :each do @vmpooler_response_body = '{ From bb9e821d5ed359b8a9ce6586af11a885f5492c39 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:43:27 +1100 Subject: [PATCH 064/265] (rubocop) Fix Layout/EmptyLinesAroundClassBody --- lib/vmfloaty/conf.rb | 1 - lib/vmfloaty/http.rb | 1 - lib/vmfloaty/service.rb | 2 -- lib/vmfloaty/ssh.rb | 1 - 4 files changed, 5 deletions(-) diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb index b1bfef1..5e572fa 100644 --- a/lib/vmfloaty/conf.rb +++ b/lib/vmfloaty/conf.rb @@ -3,7 +3,6 @@ require 'yaml' class Conf - def self.read_config conf = {} begin diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index b120538..f2ef77c 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -46,5 +46,4 @@ class Http conn end - end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 899f651..e5ad4be 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -6,7 +6,6 @@ require 'vmfloaty/utils' require 'vmfloaty/ssh' class Service - attr_reader :config def initialize(options, config_hash = {}) @@ -135,5 +134,4 @@ class Service def disk(verbose, hostname, disk) @service_object.disk(verbose, url, hostname, token, disk) end - end \ No newline at end of file diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index e20d84d..0b3f9bb 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class Ssh - def self.which(cmd) # Gets path of executable for given command From e6d1fbf954c3015abdfd15222ec2c0b84f9f8d46 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:44:11 +1100 Subject: [PATCH 065/265] (rubocop) Fix Layout/TrailingBlankLines --- lib/vmfloaty/service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index e5ad4be..123f400 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -134,4 +134,4 @@ class Service def disk(verbose, hostname, disk) @service_object.disk(verbose, url, hostname, token, disk) end -end \ No newline at end of file +end From e8f420a08ce1adc59b7d158986e1706041789bf3 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:46:15 +1100 Subject: [PATCH 066/265] (rubocop) Fix Layout/EmptyLineAfterGuardClause --- lib/vmfloaty/auth.rb | 3 +++ lib/vmfloaty/ssh.rb | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/vmfloaty/auth.rb b/lib/vmfloaty/auth.rb index a1fdd60..dcf06c0 100644 --- a/lib/vmfloaty/auth.rb +++ b/lib/vmfloaty/auth.rb @@ -13,6 +13,7 @@ class Auth res_body = JSON.parse(resp.body) return res_body['token'] if res_body['ok'] + raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}" end @@ -24,6 +25,7 @@ class Auth response = conn.delete "token/#{token}" res_body = JSON.parse(response.body) return res_body if res_body['ok'] + raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}" end @@ -36,6 +38,7 @@ class Auth res_body = JSON.parse(response.body) return res_body if res_body['ok'] + raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}" end end diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 0b3f9bb..5de4313 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -17,11 +17,13 @@ class Ssh def self.ssh(verbose, host_os, token, url) ssh_path = which('ssh') raise 'Could not determine path to ssh' unless ssh_path + os_types = {} os_types[host_os] = 1 response = Pooler.retrieve(verbose, os_types, token, url) raise "Could not get vm from vmpooler:\n #{response}" unless response['ok'] + user = host_os =~ /win/ ? 'Administrator' : 'root' hostname = "#{response[host_os]['hostname']}.#{response['domain']}" From cecea8bc052b28fe28a068bd7054ae6ae997867b Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:47:16 +1100 Subject: [PATCH 067/265] (rubocop) Fix Layout/SpaceAfterNot --- lib/vmfloaty.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index a68fc26..6471d18 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -52,7 +52,7 @@ class Vmfloaty max_pool_request = 5 large_pool_requests = os_types.select { |_,v| v > max_pool_request } - if ! large_pool_requests.empty? && ! force + if !large_pool_requests.empty? && !force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts 'Try again with `floaty get --force`' exit 1 From 9afae18ee2c42d3fb2e6c01bbae56fcf86d8d6f0 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:48:04 +1100 Subject: [PATCH 068/265] (rubocop) Fix Layout/SpaceAfterComma --- lib/vmfloaty.rb | 2 +- spec/vmfloaty/nonstandard_pooler_spec.rb | 2 +- spec/vmfloaty/service_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 6471d18..a9e3925 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -51,7 +51,7 @@ class Vmfloaty os_types = Utils.generate_os_hash(args) 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? && !force STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." STDERR.puts 'Try again with `floaty get --force`' diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index c01d79e..dcddbcf 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -153,7 +153,7 @@ BODY end it 'retrieves a multiple vms with a token' do - stub_request(:post,"#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc") + stub_request(:post, "#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc") .with(:headers => @post_request_headers) .to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {}) diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 55e4fb3..2ee0bc9 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -44,7 +44,7 @@ describe Service do describe '#delete_token' do it 'deletes a token' do - service = Service.new(MockOptions.new,'user' => 'first.last', 'url' => 'http://default.url') + service = Service.new(MockOptions.new, 'user' => 'first.last', 'url' => 'http://default.url') allow(Commander::UI).to(receive(:password) .with('Enter your pooler service password:', '*') .and_return('hunter2')) From f2ab052fa4b96683a01f508386b418ce9feeffce Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:49:03 +1100 Subject: [PATCH 069/265] (rubocop) Fix Layout/ExtraSpacing --- spec/vmfloaty/pooler_spec.rb | 2 +- spec/vmfloaty/utils_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index eb52710..115e5cc 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -213,7 +213,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 => { '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) expect(disk_req['ok']).to be true diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 6933aeb..dafdbdb 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -155,7 +155,7 @@ describe Utils do end describe '#pretty_print_hosts' do - let(:url) { 'http://pooler.example.com' } + let(:url) { 'http://pooler.example.com' } it 'prints a vmpooler output with host fqdn, template and duration info' do hostname = 'mcpy42eqjxli9g2' From f2167f8be7930b7cfb6715c2f53adcaf230cd3a8 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 12:59:34 +1100 Subject: [PATCH 070/265] (rubocop) Fix Layout/CaseIndentation --- lib/vmfloaty.rb | 34 +++++++------- lib/vmfloaty/utils.rb | 106 +++++++++++++++++++++--------------------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index a9e3925..8b64e3c 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -371,23 +371,23 @@ class Vmfloaty begin case action - when 'get' - token = service.get_new_token(verbose) - puts token - when 'delete' - result = service.delete_token(verbose, options.token) - puts result - when 'status' - token_value = options.token - token_value = args[1] if token_value.nil? - status = service.token_status(verbose, token_value) - puts status - when nil - STDERR.puts 'No action provided' - exit 1 - else - STDERR.puts "Unknown action: #{action}" - exit 1 + when 'get' + token = service.get_new_token(verbose) + puts token + when 'delete' + result = service.delete_token(verbose, options.token) + puts result + when 'status' + token_value = options.token + token_value = args[1] if token_value.nil? + status = service.token_status(verbose, token_value) + puts status + when nil + STDERR.puts 'No action provided' + exit 1 + else + STDERR.puts "Unknown action: #{action}" + exit 1 end rescue TokenError => e STDERR.puts e diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 7bfdd52..d2e591e 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -84,24 +84,24 @@ class Utils host_data = response[hostname] case service.type - when 'Pooler' - tag_pairs = [] - unless host_data['tags'].nil? - tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } - end - duration = "#{host_data['running']}/#{host_data['lifetime']} hours" - metadata = [host_data['template'], duration, *tag_pairs] - puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" - when 'NonstandardPooler' - line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" - line += ", #{host_data['hours_left_on_reservation']}h remaining" - unless host_data['reserved_for_reason'].empty? - line += ", reason: #{host_data['reserved_for_reason']}" - end - line += ')' - puts line - else - raise "Invalid service type #{service.type}" + when 'Pooler' + tag_pairs = [] + unless host_data['tags'].nil? + tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } + end + duration = "#{host_data['running']}/#{host_data['lifetime']} hours" + metadata = [host_data['template'], duration, *tag_pairs] + puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" + when 'NonstandardPooler' + line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" + line += ", #{host_data['hours_left_on_reservation']}h remaining" + unless host_data['reserved_for_reason'].empty? + line += ", reason: #{host_data['reserved_for_reason']}" + end + line += ')' + puts line + else + raise "Invalid service type #{service.type}" end rescue StandardError => e STDERR.puts("Something went wrong while trying to gather information on #{hostname}:") @@ -114,45 +114,45 @@ class Utils status_response = service.status(verbose) case service.type - when 'Pooler' - message = status_response['status']['message'] - pools = status_response['pools'] - pools.select! { |_, pool| pool['ready'] < pool['max'] } unless verbose + when 'Pooler' + message = status_response['status']['message'] + pools = status_response['pools'] + pools.select! { |_, pool| pool['ready'] < pool['max'] } unless verbose - width = pools.keys.map(&:length).max - pools.each do |name, pool| - begin - max = pool['max'] - ready = pool['ready'] - pending = pool['pending'] - missing = max - ready - pending - char = 'o' - puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" - rescue StandardError => e - puts "#{name.ljust(width)} #{e.red}" - end + width = pools.keys.map(&:length).max + pools.each do |name, pool| + begin + max = pool['max'] + ready = pool['ready'] + pending = pool['pending'] + missing = max - ready - pending + char = 'o' + puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" + rescue StandardError => e + puts "#{name.ljust(width)} #{e.red}" end - puts message.colorize(status_response['status']['ok'] ? :default : :red) - when 'NonstandardPooler' - pools = status_response - pools.delete 'ok' - pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose + end + puts message.colorize(status_response['status']['ok'] ? :default : :red) + when 'NonstandardPooler' + pools = status_response + pools.delete 'ok' + pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose - width = pools.keys.map(&:length).max - pools.each do |name, pool| - begin - max = pool['total_hosts'] - ready = pool['available_hosts'] - pending = pool['pending'] || 0 # not available for nspooler - missing = max - ready - pending - char = 'o' - puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" - rescue StandardError => e - puts "#{name.ljust(width)} #{e.red}" - end + width = pools.keys.map(&:length).max + pools.each do |name, pool| + begin + max = pool['total_hosts'] + ready = pool['available_hosts'] + pending = pool['pending'] || 0 # not available for nspooler + missing = max - ready - pending + char = 'o' + puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" + rescue StandardError => e + puts "#{name.ljust(width)} #{e.red}" end - else - raise "Invalid service type #{service.type}" + end + else + raise "Invalid service type #{service.type}" end end From 851009b1f62b19c138942bd9f514b7290cae985b Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:08:00 +1100 Subject: [PATCH 071/265] (rubocop) Fix Layout/AlignHash & Layout/IndentHash --- .rubocop.yml | 4 ++ lib/vmfloaty.rb | 8 +-- lib/vmfloaty/utils.rb | 8 +-- spec/vmfloaty/nonstandard_pooler_spec.rb | 18 ++--- spec/vmfloaty/pooler_spec.rb | 4 +- spec/vmfloaty/service_spec.rb | 14 ++-- spec/vmfloaty/utils_spec.rb | 88 ++++++++++++------------ 7 files changed, 74 insertions(+), 70 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e0a6614..0430a26 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -12,3 +12,7 @@ Style/TrailingCommaInArrayLiteral: EnforcedStyleForMultiline: comma Style/TrailingCommaInArguments: EnforcedStyleForMultiline: comma +Layout/AlignHash: + EnforcedHashRocketStyle: table +Layout/IndentHash: + EnforcedStyle: consistent diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 8b64e3c..713a81e 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -152,10 +152,10 @@ class Vmfloaty 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? } diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index d2e591e..8652ba5 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -176,10 +176,10 @@ class Utils def self.get_service_config(config, options) # The top-level url, user, and token values in the config file are treated as defaults service_config = { - 'url' => config['url'], - 'user' => config['user'], - 'token' => config['token'], - 'type' => config['type'] || 'vmpooler', + 'url' => config['url'], + 'user' => config['user'], + 'token' => config['token'], + 'type' => config['type'] || 'vmpooler', } if config['services'] diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index dcddbcf..2e8b740 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -9,16 +9,16 @@ describe NonstandardPooler do before :each do @nspooler_url = 'https://nspooler.example.com' @post_request_headers = { - 'Accept' => '*/*', + 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent' => 'Faraday v0.9.2', - 'X-Auth-Token' => 'token-value', + 'User-Agent' => 'Faraday v0.9.2', + 'X-Auth-Token' => 'token-value', } @get_request_headers = { - 'Accept' => '*/*', + 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent' => 'Faraday v0.9.2', - 'X-Auth-Token' => 'token-value', + 'User-Agent' => 'Faraday v0.9.2', + 'X-Auth-Token' => 'token-value', } @get_request_headers_notoken = @get_request_headers.tap do |headers| headers.delete('X-Auth-Token') @@ -174,8 +174,8 @@ BODY it 'raises an error if the user tries to modify an unsupported attribute' do stub_request(:put, 'https://nspooler.example.com/host/myfakehost') - .with(:body => { '{}' => true }, - :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' }) + .with(:body => { '{}' => true }, + :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' }) .to_return(:status => 200, :body => '', :headers => {}) details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } @@ -185,7 +185,7 @@ BODY 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, + .with(:body => modify_request_body, :headers => @post_request_headers) .to_return(:status => 200, :body => '{"ok": true}', :headers => {}) diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 115e5cc..1f26e70 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -99,8 +99,8 @@ describe Pooler do it 'modifies the TTL of a vm' do modify_hash = { :lifetime => 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .with(:body => { '{"lifetime":12}' => true }, - :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .with(:body => { '{"lifetime":12}' => true }, + :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @modify_response_body_success, :headers => {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index 2ee0bc9..e622c15 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -58,17 +58,17 @@ describe Service do describe '#token_status' do it 'reports the status of a token' do config = { - 'user' => 'first.last', - 'url' => 'http://default.url', + 'user' => 'first.last', + 'url' => 'http://default.url', } options = MockOptions.new('token' => 'token-value') service = Service.new(options, config) status = { - 'ok' => true, - 'user' => config['user'], - 'created' => '2017-09-22 02:04:18 +0000', - 'last_accessed' => '2017-09-22 02:04:28 +0000', - 'reserved_hosts' => [], + 'ok' => true, + 'user' => config['user'], + 'created' => '2017-09-22 02:04:18 +0000', + 'last_accessed' => '2017-09-22 02:04:28 +0000', + 'reserved_hosts' => [], } allow(Auth).to(receive(:token_status) .with(nil, config['url'], 'token-value') diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index dafdbdb..ae0eb8c 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -31,13 +31,13 @@ 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'], + 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 @@ -45,11 +45,11 @@ describe Utils do describe '#format_host_output' do before :each do @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'], } @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'], } @vmpooler_output = <<-OUT.chomp @@ -85,23 +85,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', - }, - 'ns' => { - 'url' => 'http://nspooler.url', - 'user' => 'first.last.nspooler', - 'token' => 'nspooler-token', - }, + 'services' => { + 'vm' => { + 'url' => 'http://vmpooler.url', + 'user' => 'first.last.vmpooler', + 'token' => 'vmpooler-token', }, + 'ns' => { + 'url' => 'http://nspooler.url', + 'user' => 'first.last.nspooler', + 'token' => 'nspooler-token', + }, + }, } end @@ -160,12 +160,12 @@ describe Utils do it 'prints a vmpooler output with host fqdn, template and duration info' do hostname = 'mcpy42eqjxli9g2' response_body = { hostname => { - 'template' => 'ubuntu-1604-x86_64', - 'lifetime' => 12, - 'running' => 9.66, - 'state' => 'running', - 'ip' => '127.0.0.1', - 'domain' => 'delivery.mycompany.net', + 'template' => 'ubuntu-1604-x86_64', + 'lifetime' => 12, + 'running' => 9.66, + 'state' => 'running', + 'ip' => '127.0.0.1', + 'domain' => 'delivery.mycompany.net', } } output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)' @@ -182,16 +182,16 @@ describe Utils do it 'prints a vmpooler output with host fqdn, template, duration info, and tags when supplied' do hostname = 'aiydvzpg23r415q' response_body = { hostname => { - 'template' => 'redhat-7-x86_64', - 'lifetime' => 48, - 'running' => 7.67, - 'state' => 'running', - 'tags' => { - 'user' => 'bob', - 'role' => 'agent', - }, - 'ip' => '127.0.0.1', - 'domain' => 'delivery.mycompany.net', + 'template' => 'redhat-7-x86_64', + 'lifetime' => 48, + 'running' => 7.67, + 'state' => 'running', + 'tags' => { + 'user' => 'bob', + 'role' => 'agent', + }, + 'ip' => '127.0.0.1', + 'domain' => 'delivery.mycompany.net', } } output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)' @@ -208,11 +208,11 @@ describe Utils do it 'prints a nonstandard pooler output with host, template, and time remaining' do hostname = 'sol11-9.delivery.mycompany.net' response_body = { hostname => { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => '', - '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, } } output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)' @@ -229,11 +229,11 @@ describe Utils do it 'prints a nonstandard pooler output with host, template, time remaining, and reason' do hostname = 'sol11-9.delivery.mycompany.net' response_body = { hostname => { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => 'testing', - 'hours_left_on_reservation' => 35.89, + 'fqdn' => hostname, + 'os_triple' => 'solaris-11-sparc', + 'reserved_by_user' => 'first.last', + 'reserved_for_reason' => 'testing', + 'hours_left_on_reservation' => 35.89, } } output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)' From 7d9545f202ee27492ac1ff9cfc2d7553a8bcc52a Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:11:07 +1100 Subject: [PATCH 072/265] (rubocop) Fix Layout/IndentHeredoc --- spec/vmfloaty/nonstandard_pooler_spec.rb | 190 +++++++++++------------ spec/vmfloaty/utils_spec.rb | 16 +- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 2e8b740..f6a179e 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -27,22 +27,22 @@ describe NonstandardPooler do describe '#list' do before :each do - @status_response_body = <<-BODY -{ - "ok": true, - "solaris-10-sparc": { - "total_hosts": 11, - "available_hosts": 11 - }, - "ubuntu-16.04-power8": { - "total_hosts": 10, - "available_hosts": 10 - }, - "aix-7.2-power": { - "total_hosts": 5, - "available_hosts": 4 - } -} + @status_response_body = <<~BODY + { + "ok": true, + "solaris-10-sparc": { + "total_hosts": 11, + "available_hosts": 11 + }, + "ubuntu-16.04-power8": { + "total_hosts": 10, + "available_hosts": 10 + }, + "aix-7.2-power": { + "total_hosts": 5, + "available_hosts": 4 + } + } BODY end @@ -75,24 +75,24 @@ describe NonstandardPooler do describe '#list_active' do before :each do - @token_status_body_active = <<-BODY -{ - "ok": true, - "user": "first.last", - "created": "2017-09-18 01:25:41 +0000", - "last_accessed": "2017-09-21 19:46:25 +0000", - "reserved_hosts": ["sol10-9", "sol10-11"] -} -BODY - @token_status_body_empty = <<-BODY -{ - "ok": true, - "user": "first.last", - "created": "2017-09-18 01:25:41 +0000", - "last_accessed": "2017-09-21 19:46:25 +0000", - "reserved_hosts": [] -} -BODY + @token_status_body_active = <<~BODY + { + "ok": true, + "user": "first.last", + "created": "2017-09-18 01:25:41 +0000", + "last_accessed": "2017-09-21 19:46:25 +0000", + "reserved_hosts": ["sol10-9", "sol10-11"] + } + BODY + @token_status_body_empty = <<~BODY + { + "ok": true, + "user": "first.last", + "created": "2017-09-18 01:25:41 +0000", + "last_accessed": "2017-09-21 19:46:25 +0000", + "reserved_hosts": [] + } + BODY end it 'prints an output of fqdn, template, and duration' do @@ -107,28 +107,28 @@ BODY describe '#retrieve' do before :each do - @retrieve_response_body_single = <<-BODY -{ - "ok": true, - "solaris-11-sparc": { - "hostname": "sol11-4.delivery.puppetlabs.net" - } -} -BODY - @retrieve_response_body_many = <<-BODY -{ - "ok": true, - "solaris-10-sparc": { - "hostname": [ - "sol10-9.delivery.puppetlabs.net", - "sol10-10.delivery.puppetlabs.net" - ] - }, - "aix-7.1-power": { - "hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net" - } -} -BODY + @retrieve_response_body_single = <<~BODY + { + "ok": true, + "solaris-11-sparc": { + "hostname": "sol11-4.delivery.puppetlabs.net" + } + } + BODY + @retrieve_response_body_many = <<~BODY + { + "ok": true, + "solaris-10-sparc": { + "hostname": [ + "sol10-9.delivery.puppetlabs.net", + "sol10-10.delivery.puppetlabs.net" + ] + }, + "aix-7.1-power": { + "hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net" + } + } + BODY end it 'raises an AuthError if the token is invalid' do @@ -199,23 +199,23 @@ BODY before :each do @status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}' # TODO: make this report stuff like 'broken' - @status_response_body = <<-BODY -{ - "ok": true, - "solaris-10-sparc": { - "total_hosts": 11, - "available_hosts": 10 - }, - "ubuntu-16.04-power8": { - "total_hosts": 10, - "available_hosts": 10 - }, - "aix-7.2-power": { - "total_hosts": 5, - "available_hosts": 4 - } -} -BODY + @status_response_body = <<~BODY + { + "ok": true, + "solaris-10-sparc": { + "total_hosts": 11, + "available_hosts": 10 + }, + "ubuntu-16.04-power8": { + "total_hosts": 10, + "available_hosts": 10 + }, + "aix-7.2-power": { + "total_hosts": 5, + "available_hosts": 4 + } + } + BODY end it 'prints the status' do @@ -230,16 +230,16 @@ BODY describe '#summary' do before :each do - @status_response_body = <<-BODY -{ - "ok": true, - "total": 57, - "available": 39, - "in_use": 16, - "resetting": 2, - "broken": 0 -} -BODY + @status_response_body = <<~BODY + { + "ok": true, + "total": 57, + "available": 39, + "in_use": 16, + "resetting": 2, + "broken": 0 + } + BODY end it 'prints the summary' do @@ -254,18 +254,18 @@ BODY describe '#query' do before :each do - @query_response_body = <<-BODY -{ - "ok": true, - "sol10-11": { - "fqdn": "sol10-11.delivery.puppetlabs.net", - "os_triple": "solaris-10-sparc", - "reserved_by_user": "first.last", - "reserved_for_reason": "testing", - "hours_left_on_reservation": 29.12 - } -} -BODY + @query_response_body = <<~BODY + { + "ok": true, + "sol10-11": { + "fqdn": "sol10-11.delivery.puppetlabs.net", + "os_triple": "solaris-10-sparc", + "reserved_by_user": "first.last", + "reserved_for_reason": "testing", + "hours_left_on_reservation": 29.12 + } + } + BODY end it 'makes a query about a vm' do diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index ae0eb8c..7fd795b 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -52,15 +52,15 @@ describe Utils do 'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'], 'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'], } - @vmpooler_output = <<-OUT.chomp -- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) -- gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64) -- ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64) + @vmpooler_output = <<~OUT.chomp + - dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64) + - gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64) + - ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64) OUT - @nonstandard_output = <<-OUT.chomp -- sol10-10.delivery.mycompany.net (solaris-10-sparc) -- sol10-11.delivery.mycompany.net (solaris-10-sparc) -- power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8) + @nonstandard_output = <<~OUT.chomp + - sol10-10.delivery.mycompany.net (solaris-10-sparc) + - sol10-11.delivery.mycompany.net (solaris-10-sparc) + - power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8) OUT end it 'formats a hostname hash from vmpooler into a list that includes the os' do From c78ad33104bf5a19a54b37e06f3670e9e82f9bce Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:12:33 +1100 Subject: [PATCH 073/265] (rubocop) Fix Layout/LeadingCommentSpace --- spec/vmfloaty/pooler_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 1f26e70..5c61978 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -129,7 +129,7 @@ describe Pooler do describe '#status' 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."}}' end From c97af3f7db45c322e0f3bcb426ef32f515630fd8 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:15:53 +1100 Subject: [PATCH 074/265] (rubocop) Fix Performance/RegexpMatch --- lib/vmfloaty/ssh.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 5de4313..9adee9c 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -24,7 +24,7 @@ class Ssh response = Pooler.retrieve(verbose, os_types, token, url) raise "Could not get vm from vmpooler:\n #{response}" unless response['ok'] - user = host_os =~ /win/ ? 'Administrator' : 'root' + user = /win/.match?(host_os) ? 'Administrator' : 'root' hostname = "#{response[host_os]['hostname']}.#{response['domain']}" cmd = "#{ssh_path} #{user}@#{hostname}" From 2a05f0d976b835b50dc9d26ece6548978560fdd6 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:18:24 +1100 Subject: [PATCH 075/265] (rubocop) Fix Lint/ScriptPermission --- lib/vmfloaty.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 713a81e..a2defb8 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -1,4 +1,3 @@ -#!/usr/bin/env ruby # frozen_string_literal: true require 'rubygems' From f0863e7fb06b9d7e9ed937f621e8a9dc0871fe2e Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:19:54 +1100 Subject: [PATCH 076/265] (rubocop) Fix Lint/UnusedMethodArgument --- lib/vmfloaty/nonstandard_pooler.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 0e1e449..855fa84 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -71,15 +71,15 @@ class NonstandardPooler response.body.empty? ? {} : JSON.parse(response.body) end - def self.disk(verbose, url, hostname, token, disk) + def self.disk(_verbose, _url, _hostname, _token, _disk) raise ModifyError, 'Configured service type does not support modification of disk space' end - def self.snapshot(verbose, url, hostname, token) + def self.snapshot(_verbose, _url, _hostname, _token) raise ModifyError, 'Configured service type does not support snapshots' end - def self.revert(verbose, url, hostname, token, snapshot_sha) + def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha) raise ModifyError, 'Configured service type does not support snapshots' end From 63eb49c747910490adbb4ad2b85089a8c446c122 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:20:57 +1100 Subject: [PATCH 077/265] (rubocop) Fix Lint/UnusedBlockArgument --- lib/vmfloaty/nonstandard_pooler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 855fa84..f504686 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -49,7 +49,7 @@ class NonstandardPooler 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 %i[reason reserved_for_reason].include? key raise ModifyError, "Configured service type does not support modification of #{key}" end From 66993b43fddb7e58e89b0ead60a0d1979eb40f47 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:22:01 +1100 Subject: [PATCH 078/265] (rubocop) Fix Gemspec/OrderedDependencies --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 455fce0..6947bf3 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.test_files = Dir['spec/**/*'] s.require_path = 'lib' + s.add_dependency 'colorize', '~> 0.8.1' s.add_dependency 'commander', '~> 4.4.3' s.add_dependency 'faraday', '~> 0.9.0' - s.add_dependency 'colorize', '~> 0.8.1' end From e1379a8b9c2723f9c4e1e2a23d2983daf6bd5a6a Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:25:33 +1100 Subject: [PATCH 079/265] (rubocop) Fix Naming/PredicateName --- lib/vmfloaty/http.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb index f2ef77c..b1984b8 100644 --- a/lib/vmfloaty/http.rb +++ b/lib/vmfloaty/http.rb @@ -4,7 +4,7 @@ require 'faraday' require 'uri' class Http - def self.is_url(url) + def self.url?(url) # This method exists because it seems like Farady # has no handling around if a user gives us a URI # with no protocol on the beginning of the URL @@ -19,7 +19,7 @@ class Http def self.get_conn(verbose, url) raise 'Did not provide a url to connect to' if url.nil? - url = "https://#{url}" unless is_url(url) + url = "https://#{url}" unless url?(url) conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday| faraday.request :url_encoded @@ -35,7 +35,7 @@ class Http raise 'You did not provide a user to authenticate with' if user.nil? - url = "https://#{url}" unless is_url(url) + url = "https://#{url}" unless url?(url) conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday| faraday.request :url_encoded From e50d4b32593a5951bc6746f2b75fa71308cc09c2 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:27:25 +1100 Subject: [PATCH 080/265] (rubocop) Fix Naming/HeredocDelimiterNaming --- lib/vmfloaty.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index a2defb8..c2170a3 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -431,13 +431,13 @@ class Vmfloaty command :completion do |c| c.syntax = 'floaty completion [options]' c.summary = 'Outputs path to completion script' - c.description = Utils.strip_heredoc(<<-EOF) + c.description = Utils.strip_heredoc(<<-DESCRIPTION) Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile: source $(floaty completion --shell bash) This subcommand will exit non-zero with an error message if no completion script is available for the requested shell. - EOF + DESCRIPTION c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash' c.option '--shell STRING', String, 'Shell to request completion script for' c.action do |_, options| From af6dc740e4b3cfb55e8a7d1118376f4c151c6e6e Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 13:28:43 +1100 Subject: [PATCH 081/265] (rubocop) Fix Naming/UncommunicativeMethodParamName --- lib/vmfloaty/service.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 123f400..648e71b 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -14,16 +14,16 @@ class Service @service_object = Utils.get_service_object @config['type'] end - def method_missing(m, *args, &block) - if @service_object.respond_to? m - @service_object.send(m, *args, &block) + def method_missing(method_name, *args, &block) + if @service_object.respond_to?(method_name) + @service_object.send(method_name, *args, &block) else super end end - def respond_to_missing?(m, *) - @service_object.respond_to?(m) || super + def respond_to_missing?(method_name, *) + @service_object.respond_to?(method_name) || super end def url From 426e9ce96bbcedf036121f898156d0be9e8123c3 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 15:37:50 +1100 Subject: [PATCH 082/265] (rubocop) Fix Style/ConditionalAssignment --- lib/vmfloaty/utils.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 8652ba5..3f2d433 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -66,12 +66,7 @@ class Utils os_types = {} os_args.each do |arg| os_arr = arg.split('=') - if os_arr.size == 1 - # assume they didn't specify an = sign if split returns 1 size - os_types[os_arr[0]] = 1 - else - os_types[os_arr[0]] = os_arr[1].to_i - end + os_types[os_arr[0]] = os_arr.size == 1 ? 1 : os_arr[1].to_i end os_types end From 6e1f626d7b16ccc387e8fe6ba2af4eb88ae45985 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 15:40:17 +1100 Subject: [PATCH 083/265] (rubocop) Fix Style/IfUnlessModifier --- lib/vmfloaty.rb | 8 ++----- lib/vmfloaty/nonstandard_pooler.rb | 16 ++++--------- lib/vmfloaty/pooler.rb | 36 ++++++++---------------------- lib/vmfloaty/utils.rb | 16 ++++--------- 4 files changed, 19 insertions(+), 57 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index c2170a3..dfe390a 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -300,9 +300,7 @@ class Vmfloaty hostname = args[0] snapshot_sha = args[1] || options.snapshot - if args[1] && options.snapshot - STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" - end + STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot begin revert_req = service.revert(verbose, hostname, snapshot_sha) @@ -419,9 +417,7 @@ class Vmfloaty host_os = args.first - if args.length > 1 - STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." - end + STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1 service.ssh(verbose, host_os, use_token) exit 0 diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index f504686..f5451b7 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -27,9 +27,7 @@ class NonstandardPooler conn.headers['X-AUTH-TOKEN'] = token if token os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') - if os_string.empty? - raise MissingParamError, 'No operating systems provided to obtain.' - end + raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? response = conn.post "host/#{os_string}" @@ -45,14 +43,10 @@ class NonstandardPooler end def self.modify(verbose, url, hostname, token, modify_hash) - if token.nil? - raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' - end + raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' if token.nil? modify_hash.each do |key, _value| - unless %i[reason reserved_for_reason].include? key - raise ModifyError, "Configured service type does not support modification of #{key}" - end + raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason reserved_for_reason].include? key end if modify_hash[:reason] @@ -84,9 +78,7 @@ class NonstandardPooler end def self.delete(verbose, url, hosts, token) - if token.nil? - raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' - end + raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil? conn = Http.get_conn(verbose, url) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 8eceb8c..f8d8633 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -24,9 +24,7 @@ class Pooler def self.list_active(verbose, url, token) status = Auth.token_status(verbose, url, token) vms = [] - if status[token] && status[token]['vms'] - vms = status[token]['vms']['running'] - end + vms = status[token]['vms']['running'] if status[token] && status[token]['vms'] vms end @@ -38,9 +36,7 @@ class Pooler conn.headers['X-AUTH-TOKEN'] = token if token os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') - if os_string.empty? - raise MissingParamError, 'No operating systems provided to obtain.' - end + raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? response = conn.post "vm/#{os_string}" @@ -56,14 +52,10 @@ class Pooler end def self.modify(verbose, url, hostname, token, modify_hash) - if token.nil? - raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' - end + raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil? modify_hash.keys.each do |key| - unless %i[tags lifetime disk].include? key - raise ModifyError, "Configured service type does not support modification of #{key}." - end + raise ModifyError, "Configured service type does not support modification of #{key}." unless %i[tags lifetime disk].include? key end conn = Http.get_conn(verbose, url) @@ -84,9 +76,7 @@ class Pooler end def self.disk(verbose, url, hostname, token, disk) - if token.nil? - raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' - end + raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil? conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token @@ -98,9 +88,7 @@ class Pooler end def self.delete(verbose, url, hosts, token) - if token.nil? - raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' - end + raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' if token.nil? conn = Http.get_conn(verbose, url) @@ -143,9 +131,7 @@ class Pooler end def self.snapshot(verbose, url, hostname, token) - if token.nil? - raise TokenError, 'Token provided was nil. Request cannot be made to snapshot vm' - end + raise TokenError, 'Token provided was nil. Request cannot be made to snapshot vm' if token.nil? conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token @@ -156,16 +142,12 @@ class Pooler end def self.revert(verbose, url, hostname, token, snapshot_sha) - if token.nil? - raise TokenError, 'Token provided was nil. Request cannot be made to revert vm' - end + raise TokenError, 'Token provided was nil. Request cannot be made to revert vm' if token.nil? conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token - if snapshot_sha.nil? - raise "Snapshot SHA provided was nil, could not revert #{hostname}" - end + raise "Snapshot SHA provided was nil, could not revert #{hostname}" if snapshot_sha.nil? response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}" res_body = JSON.parse(response.body) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 3f2d433..b9f5a9c 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -30,9 +30,7 @@ class Utils # } # } - unless response_body.delete('ok') - raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" - end + raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok') # vmpooler reports the domain separately from the hostname domain = response_body.delete('domain') @@ -81,18 +79,14 @@ class Utils case service.type when 'Pooler' tag_pairs = [] - unless host_data['tags'].nil? - tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } - end + tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" - unless host_data['reserved_for_reason'].empty? - line += ", reason: #{host_data['reserved_for_reason']}" - end + line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? line += ')' puts line else @@ -185,9 +179,7 @@ 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 - unless config['services'][options.service] - raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" - end + raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" unless config['services'][options.service] # If the service is configured but some values are missing, use the top-level defaults to fill them in service_config.merge! config['services'][options.service] From 893f9363e01856f6273da74305a9d01cb6585710 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 15:50:07 +1100 Subject: [PATCH 084/265] (rubocop) Defer Metrics cop changes for now --- .rubocop.yml | 4 +++- .rubocop_todo.yml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 .rubocop_todo.yml diff --git a/.rubocop.yml b/.rubocop.yml index 0430a26..1895d8e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,5 @@ ---- +inherit_from: .rubocop_todo.yml + AllCops: TargetRubyVersion: 2.4 @@ -12,6 +13,7 @@ Style/TrailingCommaInArrayLiteral: EnforcedStyleForMultiline: comma Style/TrailingCommaInArguments: EnforcedStyleForMultiline: comma + Layout/AlignHash: EnforcedHashRocketStyle: table Layout/IndentHash: diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..cb32ba8 --- /dev/null +++ b/.rubocop_todo.yml @@ -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 From 4440164f8ac05dfc0cf856de9166d82f50c96425 Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Sun, 3 Feb 2019 15:59:29 +1100 Subject: [PATCH 085/265] Run rubocop during CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6788143..14574bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ sudo: false language: ruby rvm: - 2.4 -script: rspec spec +script: bundle exec rake rubocop spec From 42b5ba3669bf7caf39e98f2d587651239c6dd5c4 Mon Sep 17 00:00:00 2001 From: Steve Axthelm Date: Tue, 9 Apr 2019 16:50:31 -0700 Subject: [PATCH 086/265] change urls in docs to use example.net/.com Prior to this commit, the docs and vmfloaty.yml.example file used a variety of live domains (mycompany.net, alternate.net). This commit changes those to example.net and example.com which are IANA-managed Reserved Domains. This will reduce the chance that any credentials could be harvested if a user executes the example commands without changing the domains. --- README.md | 14 +++++++------- vmfloaty.yml.example | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 486ee65..5526e42 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ $ floaty --help Grabbing a token for authenticated pooler requests: ``` -floaty token get --user username --url https://vmpooler.mycompany.net/api/v1 +floaty token get --user username --url https://vmpooler.example.net/api/v1 ``` This command will then ask you to log in. If successful, it will return a token that you can save either in a dotfile or use with other cli commands. @@ -61,7 +61,7 @@ This command will then ask you to log in. If successful, it will return a token Grabbing vms: ``` -floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring --url https://vmpooler.mycompany.net/api/v1 +floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring --url https://vmpooler.example.net/api/v1 ``` ### vmfloaty dotfile @@ -72,7 +72,7 @@ If you do not wish to continuely specify various config options with the cli, yo ```yaml # file at /Users/me/.vmfloaty.yml -url: 'https://vmpooler.mycompany.net/api/v1' +url: 'https://vmpooler.example.net/api/v1' user: 'brian' token: 'tokenstring' ``` @@ -90,10 +90,10 @@ To configure multiple services, you can set up your `~/.vmfloaty.yml` config fil user: 'brian' services: main: - url: 'https://vmpooler.mycompany.net/api/v1' + url: 'https://vmpooler.example.net/api/v1' token: 'tokenstring' alternate: - url: 'https://vmpooler.alternate.net/api/v1' + url: 'https://vmpooler.example.com/api/v1' token: 'alternate-tokenstring' ``` @@ -125,10 +125,10 @@ vmfloaty is capable of working with Puppet's [nonstandard pooler](https://github user: 'brian' services: vm: - url: 'https://vmpooler.mycompany.net/api/v1' + url: 'https://vmpooler.example.net/api/v1' token: 'tokenstring' ns: - url: 'https://nspooler.mycompany.net/api/v1' + url: 'https://nspooler.example.net/api/v1' token: 'nspooler-tokenstring' type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service ``` diff --git a/vmfloaty.yml.example b/vmfloaty.yml.example index fa6507f..d14388e 100644 --- a/vmfloaty.yml.example +++ b/vmfloaty.yml.example @@ -1,8 +1,8 @@ user: 'brian' services: main: - url: 'https://vmpooler.mycompany.net/api/v1' + url: 'https://vmpooler.example.net/api/v1' token: 'tokenstring' alternate: - url: 'https://vmpooler.alternate.net/api/v1' + url: 'https://vmpooler.example.com/api/v1' token: 'alternate-tokenstring' From 79422000a74528f5bbc07174f9c76aaebd474198 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 21 Oct 2019 21:04:47 -0700 Subject: [PATCH 087/265] Fix rubocop --- .rubocop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1895d8e..262d2b2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -16,5 +16,5 @@ Style/TrailingCommaInArguments: Layout/AlignHash: EnforcedHashRocketStyle: table -Layout/IndentHash: +Layout/IndentFirstHashElement: EnforcedStyle: consistent From b2574325a03fcd9b7aa21cc5e2e894dcabc55ff7 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 21 Oct 2019 21:08:49 -0700 Subject: [PATCH 088/265] Fixup rubocop again --- .rubocop.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 262d2b2..fd3b135 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -18,3 +18,8 @@ Layout/AlignHash: EnforcedHashRocketStyle: table Layout/IndentFirstHashElement: EnforcedStyle: consistent + +Style/StderrPuts: + Enabled: false +Style/WordArray: + Enabled: false From aaeaa1acda2e6a51b0ba51d69eb90f3e5502fe7e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 21 Oct 2019 21:14:48 -0700 Subject: [PATCH 089/265] Update travis-ci ruby rvm version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 14574bc..041e835 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: false language: ruby rvm: - - 2.4 + - 2.6.5 script: bundle exec rake rubocop spec From c140e7af48b6c4769e8940f70aee6e8c9b48857c Mon Sep 17 00:00:00 2001 From: Brandon High Date: Mon, 21 Oct 2019 17:20:37 -0700 Subject: [PATCH 090/265] Update Faraday to 0.15, remove unnecessary headers --- spec/vmfloaty/auth_spec.rb | 6 ----- spec/vmfloaty/nonstandard_pooler_spec.rb | 33 +++++++----------------- spec/vmfloaty/pooler_spec.rb | 18 ++++++------- vmfloaty.gemspec | 2 +- 4 files changed, 18 insertions(+), 41 deletions(-) diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index f110359..65cadc4 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -16,7 +16,6 @@ describe Pooler do it 'returns a token from vmpooler' do stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @get_token_response, :headers => {}) token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password') @@ -25,7 +24,6 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError) @@ -40,7 +38,6 @@ describe Pooler do it 'deletes the specified token' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @delete_token_response, :headers => {}) expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) @@ -48,7 +45,6 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) @@ -67,7 +63,6 @@ describe Pooler do it 'checks the status of a token' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @token_status_response, :headers => {}) expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response) @@ -75,7 +70,6 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index f6a179e..4d6f7ff 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -8,21 +8,9 @@ require 'vmfloaty/nonstandard_pooler' describe NonstandardPooler do before :each do @nspooler_url = 'https://nspooler.example.com' - @post_request_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' => 'token-value', + @auth_token_headers = { + 'X-Auth-Token' => 'token-value', } - @get_request_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' => 'token-value', - } - @get_request_headers_notoken = @get_request_headers.tap do |headers| - headers.delete('X-Auth-Token') - end end describe '#list' do @@ -133,7 +121,7 @@ describe NonstandardPooler do it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") - .with(:headers => @post_request_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 } @@ -142,7 +130,7 @@ describe NonstandardPooler do it 'retrieves a single vm with a token' do stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc") - .with(:headers => @post_request_headers) + .with(:headers => @auth_token_headers) .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) vm_hash = { 'solaris-11-sparc' => 1 } @@ -154,7 +142,7 @@ 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 => @post_request_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 } @@ -175,7 +163,7 @@ 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 => { '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 => @auth_token_headers) .to_return(:status => 200, :body => '', :headers => {}) details = { :lifetime => 12 } expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) } @@ -186,7 +174,7 @@ describe NonstandardPooler do modify_request_body = { '{"reserved_for_reason":"testing"}' => true } stub_request(:put, "#{@nspooler_url}/host/myfakehost") .with(:body => modify_request_body, - :headers => @post_request_headers) + :headers => @auth_token_headers) .to_return(:status => 200, :body => '{"ok": true}', :headers => {}) modify_hash = { :reason => 'testing' } @@ -220,7 +208,6 @@ describe NonstandardPooler do it 'prints the status' do stub_request(:get, "#{@nspooler_url}/status") - .with(:headers => @get_request_headers) .to_return(:status => 200, :body => @status_response_body, :headers => {}) status = NonstandardPooler.status(false, @nspooler_url) @@ -244,7 +231,6 @@ describe NonstandardPooler do it 'prints the summary' do stub_request(:get, "#{@nspooler_url}/summary") - .with(:headers => @get_request_headers) .to_return(:status => 200, :body => @status_response_body, :headers => {}) summary = NonstandardPooler.summary(false, @nspooler_url) @@ -270,7 +256,6 @@ describe NonstandardPooler do it 'makes a query about a vm' do stub_request(:get, "#{@nspooler_url}/host/sol10-11") - .with(:headers => @get_request_headers_notoken) .to_return(:status => 200, :body => @query_response_body, :headers => {}) query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11') @@ -286,7 +271,7 @@ describe NonstandardPooler do it 'deletes a single existing vm' do stub_request(:delete, "#{@nspooler_url}/host/sol11-7") - .with(:headers => @post_request_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') @@ -295,7 +280,7 @@ describe NonstandardPooler do it 'does not delete a nonexistant vm' do stub_request(:delete, "#{@nspooler_url}/host/fakehost") - .with(:headers => @post_request_headers) + .with(:headers => @auth_token_headers) .to_return(:status => 401, :body => @delete_response_failure, :headers => {}) request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value') diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 5c61978..62035e4 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -48,7 +48,7 @@ describe Pooler do it 'raises an AuthError if the token is invalid' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 401, :body => '{"ok":false}', :headers => {}) vm_hash = {} @@ -58,7 +58,7 @@ describe Pooler do it 'retrieves a single vm with a token' do stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) vm_hash = {} @@ -71,7 +71,7 @@ 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 => { '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 => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {}) vm_hash = {} @@ -100,7 +100,7 @@ describe Pooler do modify_hash = { :lifetime => 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") .with(:body => { '{"lifetime":12}' => true }, - :headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + :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) @@ -116,7 +116,7 @@ describe Pooler do it 'deletes a specified vm' do stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response @@ -135,7 +135,6 @@ describe Pooler do it 'prints the status' do stub_request(:get, "#{@vmpooler_url}/status") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @status_response_body, :headers => {}) status = Pooler.status(false, @vmpooler_url) @@ -159,7 +158,6 @@ describe Pooler do it 'makes a query about a vm' do stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @query_response_body, :headers => {}) query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6') @@ -174,7 +172,7 @@ describe Pooler do it 'makes a snapshot for a single vm' do stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot") - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'mytokenfile' }) + .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @snapshot_response_body, :headers => {}) snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile') @@ -189,7 +187,7 @@ 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 => { '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 => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @revert_response_body, :headers => {}) revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve') @@ -213,7 +211,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 => { '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 => { '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/vmfloaty.gemspec b/vmfloaty.gemspec index 6947bf3..0e22a4a 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -20,5 +20,5 @@ Gem::Specification.new do |s| s.add_dependency 'colorize', '~> 0.8.1' s.add_dependency 'commander', '~> 4.4.3' - s.add_dependency 'faraday', '~> 0.9.0' + s.add_dependency 'faraday', '~> 0.15.0' end From de7d0fdeaba12c5375c38ed7bc9edbb3536869e4 Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Thu, 17 Oct 2019 16:09:08 -0700 Subject: [PATCH 091/265] Adding command to list pools out of ABS --- README.md | 4 + lib/vmfloaty/abs.rb | 139 +++++++++++++++++++++++++++++++++ lib/vmfloaty/service.rb | 2 +- lib/vmfloaty/utils.rb | 6 +- spec/vmfloaty/abs/auth_spec.rb | 88 +++++++++++++++++++++ 5 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 lib/vmfloaty/abs.rb create mode 100644 spec/vmfloaty/abs/auth_spec.rb diff --git a/README.md b/README.md index 5526e42..ca7b8f8 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,10 @@ services: url: 'https://nspooler.example.net/api/v1' token: 'nspooler-tokenstring' type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service + abs: + url: 'https://abs.example.net/api/v2' + token: 'abs-tokenstring' + type: 'abs' # <-- 'type' is necessary for any non-vmpooler service ``` With this configuration, you could list available OS types from nspooler like this: diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb new file mode 100644 index 0000000..d35a776 --- /dev/null +++ b/lib/vmfloaty/abs.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +require 'vmfloaty/errors' +require 'vmfloaty/http' +require 'faraday' +require 'json' + +class ABS + # List available VMs in ABS + def self.list(verbose, url, os_filter = nil) + conn = Http.get_conn(verbose, url) + + os_list = [] + + response = conn.get 'status/platforms/vmpooler' + response_body = JSON.parse(response.body) + os_list << "*** VMPOOLER Pools ***" + os_list = os_list + JSON.parse(response_body["vmpooler_platforms"]) + + response = conn.get 'status/platforms/nspooler' + response_body = JSON.parse(response.body) + os_list << "" + os_list << "*** NSPOOLER Pools ***" + os_list = os_list + JSON.parse(response_body["nspooler_platforms"]) + + response = conn.get 'status/platforms/aws' + response_body = JSON.parse(response.body) + os_list << "" + os_list << "*** AWS Pools ***" + os_list = os_list + JSON.parse(response_body["aws_platforms"]) + + os_list.delete 'ok' + + puts os_list + + os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list + end + + # List active VMs from ABS + def self.list_active(verbose, url, token) + status = Auth.token_status(verbose, url, token) + status['reserved_hosts'] || [] + end + + def self.retrieve(verbose, os_type, token, url) + conn = Http.get_conn(verbose, url) + conn.headers['X-AUTH-TOKEN'] = token if token + + os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') + raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? + + response = conn.post "host/#{os_string}" + + res_body = JSON.parse(response.body) + + if res_body['ok'] + res_body + elsif response.status == 401 + raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" + else + raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/host/#{os_string}. #{res_body}" + end + end + + 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.each do |key, _value| + raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason reserved_for_reason].include? key + end + + if modify_hash[:reason] + # "reason" is easier to type than "reserved_for_reason", but nspooler needs the latter + modify_hash[:reserved_for_reason] = modify_hash.delete :reason + end + + conn = Http.get_conn(verbose, url) + conn.headers['X-AUTH-TOKEN'] = token + + response = conn.put do |req| + req.url "host/#{hostname}" + req.body = modify_hash.to_json + end + + response.body.empty? ? {} : JSON.parse(response.body) + end + + def self.disk(_verbose, _url, _hostname, _token, _disk) + raise ModifyError, 'Configured service type does not support modification of disk space' + end + + def self.snapshot(_verbose, _url, _hostname, _token) + raise ModifyError, 'Configured service type does not support snapshots' + end + + def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha) + raise ModifyError, 'Configured service type does not support snapshots' + end + + def self.delete(verbose, url, hosts, token) + raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil? + + conn = Http.get_conn(verbose, url) + + conn.headers['X-AUTH-TOKEN'] = token if token + + response_body = {} + + hosts = hosts.split(',') unless hosts.is_a? Array + hosts.each do |host| + response = conn.delete "host/#{host}" + res_body = JSON.parse(response.body) + response_body[host] = res_body + end + + response_body + end + + def self.status(verbose, url) + conn = Http.get_conn(verbose, url) + + response = conn.get '/status' + JSON.parse(response.body) + end + + def self.summary(verbose, url) + conn = Http.get_conn(verbose, url) + + response = conn.get '/summary' + JSON.parse(response.body) + end + + def self.query(verbose, url, hostname) + conn = Http.get_conn(verbose, url) + + response = conn.get "host/#{hostname}" + JSON.parse(response.body) + end +end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 648e71b..732cf59 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -52,7 +52,7 @@ class Service def get_new_token(verbose) username = user - pass = Commander::UI.password 'Enter your pooler service password:', '*' + pass = Commander::UI.password "Enter your #{@config["url"]} service password:", '*' Auth.get_token(verbose, url, username, pass) end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index b9f5a9c..22cc0c3 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'vmfloaty/pooler' +require 'vmfloaty/abs' require 'vmfloaty/nonstandard_pooler' +require 'vmfloaty/pooler' class Utils # TODO: Takes the json response body from an HTTP GET @@ -155,8 +156,11 @@ class Utils def self.get_service_object(type = '') nspooler_strings = %w[ns nspooler nonstandard nonstandard_pooler] + abs_strings = %w[abs alwaysbescheduling always_be_scheduling] if nspooler_strings.include? type.downcase NonstandardPooler + elsif abs_strings.include? type.downcase + ABS else Pooler end diff --git a/spec/vmfloaty/abs/auth_spec.rb b/spec/vmfloaty/abs/auth_spec.rb new file mode 100644 index 0000000..d6b0d26 --- /dev/null +++ b/spec/vmfloaty/abs/auth_spec.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_relative '../../../lib/vmfloaty/auth' + +describe Pooler do + before :each do + @abs_url = 'https://abs.example.com' + end + + describe '#get_token' do + before :each do + @get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}' + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' + end + + it 'returns a token from vmpooler' do + stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @get_token_response, :headers => {}) + + token = Auth.get_token(false, @abs_url, 'first.last', 'password') + expect(token).to eq @token + end + + it 'raises a token error if something goes wrong' do + stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + + expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError) + end + end + + describe '#delete_token' do + before :each do + @delete_token_response = '{"ok":true}' + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' + end + + it 'deletes the specified token' do + stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @delete_token_response, :headers => {}) + + expect(Auth.delete_token(false, @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') + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + + expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError) + end + + it 'raises a token error if no token provided' do + expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', nil) }.to raise_error(TokenError) + end + end + + describe '#token_status' do + before :each do + @token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}' + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' + end + + it 'checks the status of a token' do + stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") + .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 200, :body => @token_status_response, :headers => {}) + + expect(Auth.token_status(false, @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', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) + + expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError) + end + + it 'raises a token error if no token provided' do + expect { Auth.token_status(false, @abs_url, nil) }.to raise_error(TokenError) + end + end +end From a77ea84092b36eb863c734b71a17ba48924e729c Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Thu, 31 Oct 2019 11:41:51 -0700 Subject: [PATCH 092/265] Rebasing fixed tests --- README.md | 5 +- lib/vmfloaty.rb | 1 + lib/vmfloaty/abs.rb | 227 +++++++++++++++-------- lib/vmfloaty/nonstandard_pooler.rb | 4 +- lib/vmfloaty/pooler.rb | 2 +- lib/vmfloaty/service.rb | 10 +- lib/vmfloaty/utils.rb | 7 + spec/vmfloaty/abs/auth_spec.rb | 12 +- spec/vmfloaty/abs_spec.rb | 38 ++++ spec/vmfloaty/nonstandard_pooler_spec.rb | 12 +- spec/vmfloaty/service_spec.rb | 10 +- 11 files changed, 217 insertions(+), 111 deletions(-) create mode 100644 spec/vmfloaty/abs_spec.rb diff --git a/README.md b/README.md index ca7b8f8..9e278fc 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring ### vmfloaty dotfile -If you do not wish to continuely specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example: +If you do not wish to continually specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example: #### Basic configuration @@ -132,9 +132,10 @@ services: token: 'nspooler-tokenstring' type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service abs: - url: 'https://abs.example.net/api/v2' + url: 'https://abs.example.net/' token: 'abs-tokenstring' type: 'abs' # <-- 'type' is necessary for any non-vmpooler service + ``` With this configuration, you could list available OS types from nspooler like this: diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index dfe390a..caf6a7a 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -84,6 +84,7 @@ class Vmfloaty c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| verbose = options.verbose || config['verbose'] + service = Service.new(options, config) filter = args[0] diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index d35a776..a826ed6 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -6,134 +6,197 @@ require 'faraday' require 'json' class ABS + # List active VMs in ABS + # + # + # { + # "state":"filled", + # "last_processed":"2019-10-31 20:59:33 +0000", + # "allocated_resources": [ + # { + # "hostname":"h3oyntawjm7xdch.delivery.puppetlabs.net", + # "type":"centos-7.2-tmpfs-x86_64", + # "engine":"vmpooler"} + # ], + # "audit_log":{ + # "2019-10-30 20:33:12 +0000":"Allocated h3oyntawjm7xdch.delivery.puppetlabs.net for job 1572467589" + # }, + # "request":{ + # "resources":{ + # "centos-7.2-tmpfs-x86_64":1 + # }, + # "job": { + # "id":1572467589, + # "tags": { + # "user":"mikker", + # "url_string":"floaty://mikker/1572467589" + # }, + # "user":"mikker", + # "time-received":1572467589 + # } + # } + # } + # + def self.list_active(verbose, url, _token, user) + conn = Http.get_conn(verbose, url) + res = conn.get 'status/queue' + requests = JSON.parse(res.body) + + requests.each do |req| + reqHash = JSON.parse(req) + next unless user == reqHash['request']['job']['user'] + + puts '------------------------------------' + puts "State: #{reqHash['state']}" + puts "Job ID: #{reqHash['request']['job']['id']}" + reqHash['request']['resources'].each do |vm_template, i| + puts "--VMRequest: #{vm_template}: #{i}" + end + if reqHash['state'] == 'allocated' || reqHash['state'] == 'filled' + reqHash['allocated_resources'].each do |vm_name, i| + puts "----VM: #{vm_name}: #{i}" + end + end + puts "User: #{reqHash['request']['job']['user']}" + puts '' + end + + sleep(100) + end + # List available VMs in ABS def self.list(verbose, url, os_filter = nil) conn = Http.get_conn(verbose, url) os_list = [] - response = conn.get 'status/platforms/vmpooler' - response_body = JSON.parse(response.body) - os_list << "*** VMPOOLER Pools ***" - os_list = os_list + JSON.parse(response_body["vmpooler_platforms"]) + res = conn.get 'status/platforms/vmpooler' - response = conn.get 'status/platforms/nspooler' - response_body = JSON.parse(response.body) - os_list << "" - os_list << "*** NSPOOLER Pools ***" - os_list = os_list + JSON.parse(response_body["nspooler_platforms"]) + res_body = JSON.parse(res.body) + os_list << '*** VMPOOLER Pools ***' + os_list += JSON.parse(res_body['vmpooler_platforms']) - response = conn.get 'status/platforms/aws' - response_body = JSON.parse(response.body) - os_list << "" - os_list << "*** AWS Pools ***" - os_list = os_list + JSON.parse(response_body["aws_platforms"]) + res = conn.get 'status/platforms/nspooler' + res_body = JSON.parse(res.body) + os_list << '' + os_list << '*** NSPOOLER Pools ***' + os_list += JSON.parse(res_body['nspooler_platforms']) + + res = conn.get 'status/platforms/aws' + res_body = JSON.parse(res.body) + os_list << '' + os_list << '*** AWS Pools ***' + os_list += JSON.parse(res_body['aws_platforms']) os_list.delete 'ok' - puts os_list - os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list end - # List active VMs from ABS - def self.list_active(verbose, url, token) - status = Auth.token_status(verbose, url, token) - status['reserved_hosts'] || [] - end + # Retrieve an OS from ABS. + def self.retrieve(verbose, os_types, token, url, user) + # + # Contents of post must be:j + # + # { + # "resources": { + # "centos-7-i386": 1, + # "ubuntu-1404-x86_64": 2 + # }, + # "job": { + # "id": "12345", + # "tags": { + # "user": "jenkins", + # "jenkins_build_url": "https://jenkins/job/platform_puppet_intn-van-sys_master" + # } + # } + # } - def self.retrieve(verbose, os_type, token, url) conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') - raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? + saved_job_id = Time.now.to_i - response = conn.post "host/#{os_string}" + reqObj = { + :resources => os_types, + :job => { + :id => saved_job_id, + :tags => { + :user => user, + :url_string => "floaty://#{user}/#{saved_job_id}", + }, + }, + } - res_body = JSON.parse(response.body) + # os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') + # raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? + puts "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." + res = conn.post 'api/v2/request', reqObj.to_json - if res_body['ok'] - res_body - elsif response.status == 401 - raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" - else - raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/host/#{os_string}. #{res_body}" + i = 0 + retries = 360 + + raise AuthError, "HTTP #{res.status}: The token provided could not authenticate to the pooler.\n#{res_body}" if res.status == 401 + + (1..retries).each do |i| + queue_place, res_body = check_queue(conn, saved_job_id, reqObj) + return translated(res_body) if res_body + + puts "Waiting 10 seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + sleep(10) end + nil end - 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? + # + # We should fix the ABS API to be more like the vmpooler or nspooler api, but for now + # + def self.translated(res_body) + vmpooler_formatted_body = {} - 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 + res_body.each do |host| + if vmpooler_formatted_body[host['type']] && vmpooler_formatted_body[host['type']]['hostname'].class == Array + vmpooler_formatted_body[host['type']]['hostname'] << host['hostname'] + else + vmpooler_formatted_body[host['type']] = { 'hostname' => [host['hostname']] } + end end + vmpooler_formatted_body['ok'] = true - if modify_hash[:reason] - # "reason" is easier to type than "reserved_for_reason", but nspooler needs the latter - modify_hash[:reserved_for_reason] = modify_hash.delete :reason - end - - conn = Http.get_conn(verbose, url) - conn.headers['X-AUTH-TOKEN'] = token - - response = conn.put do |req| - req.url "host/#{hostname}" - req.body = modify_hash.to_json - end - - response.body.empty? ? {} : JSON.parse(response.body) + vmpooler_formatted_body end - def self.disk(_verbose, _url, _hostname, _token, _disk) - raise ModifyError, 'Configured service type does not support modification of disk space' - end + def self.check_queue(conn, job_id, reqObj) + queue_info_res = conn.get "/status/queue/info/#{job_id}" + queue_info = JSON.parse(queue_info_res.body) - def self.snapshot(_verbose, _url, _hostname, _token) - raise ModifyError, 'Configured service type does not support snapshots' - end + res = conn.post 'api/v2/request', reqObj.to_json - def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha) - raise ModifyError, 'Configured service type does not support snapshots' - end - - def self.delete(verbose, url, hosts, token) - raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil? - - conn = Http.get_conn(verbose, url) - - conn.headers['X-AUTH-TOKEN'] = token if token - - response_body = {} - - hosts = hosts.split(',') unless hosts.is_a? Array - hosts.each do |host| - response = conn.delete "host/#{host}" - res_body = JSON.parse(response.body) - response_body[host] = res_body + unless res.body.empty? + res_body = JSON.parse(res.body) + return queue_info['queue_place'], res_body end - - response_body + [queue_info['queue_place'], nil] end def self.status(verbose, url) conn = Http.get_conn(verbose, url) - response = conn.get '/status' - JSON.parse(response.body) + res = conn.get '/status' + JSON.parse(res.body) end def self.summary(verbose, url) conn = Http.get_conn(verbose, url) - response = conn.get '/summary' - JSON.parse(response.body) + res = conn.get '/summary' + JSON.parse(res.body) end def self.query(verbose, url, hostname) conn = Http.get_conn(verbose, url) - response = conn.get "host/#{hostname}" - JSON.parse(response.body) + res = conn.get "host/#{hostname}" + JSON.parse(res.body) end end diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index f5451b7..d094288 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -17,12 +17,12 @@ class NonstandardPooler os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list end - def self.list_active(verbose, url, token) + def self.list_active(verbose, url, token, _user) status = Auth.token_status(verbose, url, token) status['reserved_hosts'] || [] end - def self.retrieve(verbose, os_type, token, url) + def self.retrieve(verbose, os_type, token, url, _user) conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index f8d8633..69de7da 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -21,7 +21,7 @@ class Pooler hosts end - def self.list_active(verbose, url, token) + def self.list_active(verbose, url, token, _user) status = Auth.token_status(verbose, url, token) vms = [] vms = status[token]['vms']['running'] if status[token] && status[token]['vms'] diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 732cf59..6d606f1 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -36,7 +36,7 @@ class Service def user unless @config['user'] - puts 'Enter your pooler service username:' + puts "Enter your #{@config['url']} service username:" @config['user'] = STDIN.gets.chomp end @config['user'] @@ -52,13 +52,13 @@ class Service def get_new_token(verbose) username = user - pass = Commander::UI.password "Enter your #{@config["url"]} service password:", '*' + pass = Commander::UI.password "Enter your #{@config['url']} service password:", '*' Auth.get_token(verbose, url, username, pass) end def delete_token(verbose, token_value = @config['token']) username = user - pass = Commander::UI.password 'Enter your pooler service password:', '*' + pass = Commander::UI.password "Enter your #{@config['url']} service password:", '*' Auth.delete_token(verbose, url, username, pass, token_value) end @@ -72,13 +72,13 @@ class Service end def list_active(verbose) - @service_object.list_active verbose, url, token + @service_object.list_active verbose, url, token, user end def retrieve(verbose, os_types, use_token = true) puts 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil - @service_object.retrieve verbose, os_types, token_value, url + @service_object.retrieve verbose, os_types, token_value, url, user end def ssh(verbose, host_os, use_token = true) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 22cc0c3..bd83f7e 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -31,6 +31,13 @@ class Utils # } # } + # abs pooler response body example when `floaty get` arguments are : + # { + # "hostname"=>"thin-soutane.delivery.puppetlabs.net", + # "type"=>"centos-7.2-tmpfs-x86_64", + # "engine"=>"vmpooler" + # } + raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok') # vmpooler reports the domain separately from the hostname diff --git a/spec/vmfloaty/abs/auth_spec.rb b/spec/vmfloaty/abs/auth_spec.rb index d6b0d26..555d6c5 100644 --- a/spec/vmfloaty/abs/auth_spec.rb +++ b/spec/vmfloaty/abs/auth_spec.rb @@ -5,7 +5,7 @@ require_relative '../../../lib/vmfloaty/auth' describe Pooler do before :each do - @abs_url = 'https://abs.example.com' + @abs_url = 'https://abs.example.com/api/v2' end describe '#get_token' do @@ -14,9 +14,8 @@ describe Pooler do @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' end - it 'returns a token from vmpooler' do + it 'returns a token from abs' do stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @get_token_response, :headers => {}) token = Auth.get_token(false, @abs_url, 'first.last', 'password') @@ -25,7 +24,6 @@ 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') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError) @@ -40,7 +38,6 @@ describe Pooler do it 'deletes the specified token' do stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 200, :body => @delete_token_response, :headers => {}) expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response) @@ -48,7 +45,6 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') - .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(:status => 500, :body => '{"ok":false}', :headers => {}) expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError) @@ -67,7 +63,7 @@ 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', 'User-Agent' => 'Faraday v0.9.2' }) + .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) @@ -75,7 +71,7 @@ describe Pooler do 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', 'User-Agent' => 'Faraday v0.9.2' }) + .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) diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb new file mode 100644 index 0000000..3939e61 --- /dev/null +++ b/spec/vmfloaty/abs_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'vmfloaty/utils' +require 'vmfloaty/errors' +require 'vmfloaty/abs' + +describe ABS do + before :each do + end + + describe '#format' do + it 'returns an hash formatted like a vmpooler return' do + 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' }, + ] + + vmpooler_formatted_response = ABS.translated(abs_formatted_response) + + vmpooler_formatted_compare = { + 'centos-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['ubuntu-7.2-x86_64']['hostname'] = ['aaaaaaaaaaaaaac.delivery.puppetlabs.net'] + + vmpooler_formatted_compare['ok'] = true + + expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare) + vmpooler_formatted_response.delete('ok') + vmpooler_formatted_compare.delete('ok') + expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare) + end + end +end diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 4d6f7ff..6863078 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -66,7 +66,7 @@ describe NonstandardPooler do @token_status_body_active = <<~BODY { "ok": true, - "user": "first.last", + "user": 'first.last', "created": "2017-09-18 01:25:41 +0000", "last_accessed": "2017-09-21 19:46:25 +0000", "reserved_hosts": ["sol10-9", "sol10-11"] @@ -75,7 +75,7 @@ describe NonstandardPooler do @token_status_body_empty = <<~BODY { "ok": true, - "user": "first.last", + "user": 'first.last', "created": "2017-09-18 01:25:41 +0000", "last_accessed": "2017-09-21 19:46:25 +0000", "reserved_hosts": [] @@ -125,7 +125,7 @@ describe NonstandardPooler do .to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {}) vm_hash = { 'solaris-11-sparc' => 1 } - expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.to raise_error(AuthError) + expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last') }.to raise_error(AuthError) end it 'retrieves a single vm with a token' do @@ -134,7 +134,7 @@ describe NonstandardPooler do .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) + 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-11-sparc']['hostname']).to eq 'sol11-4.delivery.puppetlabs.net' @@ -146,7 +146,7 @@ describe NonstandardPooler do .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) + 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 @@ -246,7 +246,7 @@ describe NonstandardPooler do "sol10-11": { "fqdn": "sol10-11.delivery.puppetlabs.net", "os_triple": "solaris-10-sparc", - "reserved_by_user": "first.last", + "reserved_by_user": 'first.last', "reserved_for_reason": "testing", "hours_left_on_reservation": 29.12 } diff --git a/spec/vmfloaty/service_spec.rb b/spec/vmfloaty/service_spec.rb index e622c15..13426b3 100644 --- a/spec/vmfloaty/service_spec.rb +++ b/spec/vmfloaty/service_spec.rb @@ -16,9 +16,9 @@ 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 pooler service password:') + allow(STDOUT).to receive(:puts).with('Enter your http://default.url service password:') allow(Commander::UI).to(receive(:password) - .with('Enter your pooler service password:', '*') + .with('Enter your http://default.url service password:', '*') .and_return('hunter2')) allow(Auth).to(receive(:get_token) .with(nil, config['url'], config['user'], 'hunter2') @@ -29,11 +29,11 @@ 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 pooler service username:' + 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 pooler service password:', '*') + .with('Enter your http://default.url service password:', '*') .and_return('hunter2')) allow(Auth).to(receive(:get_token) .with(nil, config['url'], 'first.last', 'hunter2') @@ -46,7 +46,7 @@ describe Service do it 'deletes a token' do service = Service.new(MockOptions.new, 'user' => 'first.last', 'url' => 'http://default.url') allow(Commander::UI).to(receive(:password) - .with('Enter your pooler service password:', '*') + .with('Enter your http://default.url service password:', '*') .and_return('hunter2')) allow(Auth).to(receive(:delete_token) .with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value') From 7e275426705545e3f36f7b46feb1cbb661aeb618 Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Mon, 4 Nov 2019 11:41:49 -0800 Subject: [PATCH 093/265] Adding delete and get active requests --- lib/vmfloaty/abs.rb | 91 +++++++++++++++++++++++++++++++-------- lib/vmfloaty/pooler.rb | 2 +- lib/vmfloaty/service.rb | 2 +- lib/vmfloaty/utils.rb | 7 +++ spec/vmfloaty/abs_spec.rb | 24 +++++++++++ 5 files changed, 106 insertions(+), 20 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index a826ed6..381d95b 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -7,8 +7,7 @@ require 'json' class ABS # List active VMs in ABS - # - # + # This is what a job request looks like: # { # "state":"filled", # "last_processed":"2019-10-31 20:59:33 +0000", @@ -37,33 +36,83 @@ class ABS # } # } # + + @@active_hostnames = Hash.new + def self.list_active(verbose, url, _token, user) + all_jobs = Array.new() + @@active_hostnames = Hash.new + + self.get_active_requests(verbose, url, user).each do |reqHash| + all_jobs.push(reqHash['request']['job']['id']) + @@active_hostnames[reqHash['request']['job']['id']] = reqHash + end + + all_jobs + end + + def self.get_active_requests verbose, url, user conn = Http.get_conn(verbose, url) res = conn.get 'status/queue' requests = JSON.parse(res.body) + retVal = [] requests.each do |req| reqHash = JSON.parse(req) next unless user == reqHash['request']['job']['user'] - - puts '------------------------------------' - puts "State: #{reqHash['state']}" - puts "Job ID: #{reqHash['request']['job']['id']}" - reqHash['request']['resources'].each do |vm_template, i| - puts "--VMRequest: #{vm_template}: #{i}" - end - if reqHash['state'] == 'allocated' || reqHash['state'] == 'filled' - reqHash['allocated_resources'].each do |vm_name, i| - puts "----VM: #{vm_name}: #{i}" - end - end - puts "User: #{reqHash['request']['job']['user']}" - puts '' + retVal.push(reqHash) end - sleep(100) + retVal end + def self.all_job_resources_accounted_for(allocated_resources, hosts) + allocated_host_list = allocated_resources.map {|ar| ar["hostname"] } + return (allocated_host_list-hosts).empty? + end + + def self.delete(verbose, url, hosts, token, user) + # In ABS terms, this is a "returned" host. + conn = Http.get_conn(verbose, url) + conn.headers['X-AUTH-TOKEN'] = token if token + + puts "Trying to delete hosts #{hosts}" if verbose + requests = self.get_active_requests(verbose, url, user) + + jobs_to_delete = [] + + requests.each do |reqHash| + if reqHash['state'] == 'allocated' || reqHash['state'] == 'filled' + reqHash['allocated_resources'].each do |vm_name, i| + if hosts.include? vm_name["hostname"] + if (all_job_resources_accounted_for(job['allocated_resources'], hosts)) + jobs_to_delete.push(reqHash) + else + puts "Can't delete #{job_id}: #{hosts} does not include all of #{job['allocated_resources']}" + end + end + end + end + end + + response_body = {} + + jobs_to_delete.each do |job| + reqObj = { + 'job_id': job['request']['job']['id'], + 'hosts': job['allocated_resources'], + } + + puts "Deleting #{reqObj}" if verbose + + res = conn.post 'api/v2/return', reqObj.to_json + response_body[job_id] = res_body + end + + return response_body + end + + # List available VMs in ABS def self.list(verbose, url, os_filter = nil) conn = Http.get_conn(verbose, url) @@ -96,7 +145,7 @@ class ABS # Retrieve an OS from ABS. def self.retrieve(verbose, os_types, token, url, user) # - # Contents of post must be:j + # Contents of post must be like: # # { # "resources": { @@ -179,6 +228,10 @@ class ABS [queue_info['queue_place'], nil] end + def self.snapshot(verbose, url, hostname, token) + puts "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" + end + def self.status(verbose, url) conn = Http.get_conn(verbose, url) @@ -194,6 +247,8 @@ class ABS end def self.query(verbose, url, hostname) + return @@active_hostnames if @@active_hostnames + puts "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" conn = Http.get_conn(verbose, url) res = conn.get "host/#{hostname}" diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 69de7da..354b8a9 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -28,7 +28,7 @@ class Pooler vms end - def self.retrieve(verbose, os_type, token, url) + def self.retrieve(verbose, os_type, token, url, user) # NOTE: # Developers can use `Utils.generate_os_hash` to # generate the os_type param. diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 6d606f1..951db9c 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -112,7 +112,7 @@ class Service end def delete(verbose, hosts) - @service_object.delete verbose, url, hosts, token + @service_object.delete verbose, url, hosts, token, user end def status(verbose) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index bd83f7e..eb3464a 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -85,6 +85,13 @@ class Utils host_data = response[hostname] case service.type + when 'ABS' + # For ABS, 'hostname' variable is the jobID + if host_data['state'] == 'allocated' || host_data['state'] == 'filled' + host_data['allocated_resources'].each do |vm_name, i| + puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name["hostname"]} (#{vm_name["type"]}) <#{host_data['state']}>" + end + end when 'Pooler' tag_pairs = [] tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index 3939e61..c59e14c 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -34,5 +34,29 @@ describe ABS do vmpooler_formatted_compare.delete('ok') expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare) end + + it 'won\'t delete a job if not all vms are listed' do + hosts = ["host1"] + allocated_resources = [ + { + "hostname" => "host1" + }, + { + "hostname" => "host2" + } + ] + expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(false) + + hosts = ["host1", "host2"] + allocated_resources = [ + { + "hostname" => "host1" + }, + { + "hostname" => "host2" + } + ] + expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(true) + end end end From d963e357d37244d167d0f56a931b7c4caaa91ae8 Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Mon, 4 Nov 2019 13:30:58 -0800 Subject: [PATCH 094/265] Adding delete and get active requests --- lib/vmfloaty.rb | 1 + lib/vmfloaty/abs.rb | 133 ++++++++++++++--------- lib/vmfloaty/nonstandard_pooler.rb | 2 +- lib/vmfloaty/pooler.rb | 2 +- lib/vmfloaty/service.rb | 2 +- lib/vmfloaty/utils.rb | 8 +- spec/vmfloaty/abs_spec.rb | 16 +-- spec/vmfloaty/nonstandard_pooler_spec.rb | 14 +-- spec/vmfloaty/pooler_spec.rb | 6 +- 9 files changed, 109 insertions(+), 75 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index caf6a7a..285958c 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -33,6 +33,7 @@ class Vmfloaty c.option '--user STRING', String, 'User to authenticate with' c.option '--url STRING', String, 'URL of pooler service' c.option '--token STRING', String, 'Token for pooler service' + c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))' c.option '--notoken', 'Makes a request without a token' c.option '--force', 'Forces vmfloaty to get requested vms' c.option '--json', 'Prints retrieved vms in JSON format' diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 381d95b..29468c6 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -37,38 +37,39 @@ class ABS # } # - @@active_hostnames = Hash.new + @active_hostnames = {} def self.list_active(verbose, url, _token, user) - all_jobs = Array.new() - @@active_hostnames = Hash.new + all_jobs = [] + @active_hostnames = {} - self.get_active_requests(verbose, url, user).each do |reqHash| - all_jobs.push(reqHash['request']['job']['id']) - @@active_hostnames[reqHash['request']['job']['id']] = reqHash + get_active_requests(verbose, url, user).each do |req_hash| + all_jobs.push(req_hash['request']['job']['id']) + @active_hostnames[req_hash['request']['job']['id']] = req_hash end all_jobs end - def self.get_active_requests verbose, url, user + def self.get_active_requests(verbose, url, user) conn = Http.get_conn(verbose, url) res = conn.get 'status/queue' requests = JSON.parse(res.body) - retVal = [] + ret_val = [] requests.each do |req| - reqHash = JSON.parse(req) - next unless user == reqHash['request']['job']['user'] - retVal.push(reqHash) + req_hash = JSON.parse(req) + next unless user == req_hash['request']['job']['user'] + + ret_val.push(req_hash) end - retVal + ret_val end def self.all_job_resources_accounted_for(allocated_resources, hosts) - allocated_host_list = allocated_resources.map {|ar| ar["hostname"] } - return (allocated_host_list-hosts).empty? + allocated_host_list = allocated_resources.map { |ar| ar['hostname'] } + (allocated_host_list - hosts).empty? end def self.delete(verbose, url, hosts, token, user) @@ -77,19 +78,29 @@ class ABS conn.headers['X-AUTH-TOKEN'] = token if token puts "Trying to delete hosts #{hosts}" if verbose - requests = self.get_active_requests(verbose, url, user) + requests = get_active_requests(verbose, url, user) jobs_to_delete = [] - requests.each do |reqHash| - if reqHash['state'] == 'allocated' || reqHash['state'] == 'filled' - reqHash['allocated_resources'].each do |vm_name, i| - if hosts.include? vm_name["hostname"] - if (all_job_resources_accounted_for(job['allocated_resources'], hosts)) - jobs_to_delete.push(reqHash) - else - puts "Can't delete #{job_id}: #{hosts} does not include all of #{job['allocated_resources']}" - end + retStatus = {} + hosts.each do |host| + retStatus[host] = { + 'ok' => false + } + end + + requests.each do |req_hash| + next unless req_hash['state'] == 'allocated' || req_hash['state'] == 'filled' + + req_hash['allocated_resources'].each do |vm_name, _i| + if hosts.include? vm_name['hostname'] + if all_job_resources_accounted_for(req_hash['allocated_resources'], hosts) + retStatus[vm_name['hostname']] = { + 'ok' => true + } + jobs_to_delete.push(req_hash) + else + puts "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" end end end @@ -98,21 +109,22 @@ class ABS response_body = {} jobs_to_delete.each do |job| - reqObj = { - 'job_id': job['request']['job']['id'], - 'hosts': job['allocated_resources'], + req_obj = { + 'job_id' => job['request']['job']['id'], + 'hosts' => job['allocated_resources'], } - puts "Deleting #{reqObj}" if verbose + puts "Deleting #{req_obj}" if verbose - res = conn.post 'api/v2/return', reqObj.to_json - response_body[job_id] = res_body + return_result = conn.post 'return', req_obj.to_json + req_obj['hosts'].each do |host| + response_body[host["hostname"]] = { 'ok' => true } if return_result.body == "OK" + end end - return response_body + response_body end - # List available VMs in ABS def self.list(verbose, url, os_filter = nil) conn = Http.get_conn(verbose, url) @@ -143,7 +155,7 @@ class ABS end # Retrieve an OS from ABS. - def self.retrieve(verbose, os_types, token, url, user) + def self.retrieve(verbose, os_types, token, url, user, options) # # Contents of post must be like: # @@ -155,8 +167,7 @@ class ABS # "job": { # "id": "12345", # "tags": { - # "user": "jenkins", - # "jenkins_build_url": "https://jenkins/job/platform_puppet_intn-van-sys_master" + # "user": "username", # } # } # } @@ -164,35 +175,51 @@ class ABS conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - saved_job_id = Time.now.to_i + saved_job_id = DateTime.now.strftime('%Q') - reqObj = { + req_obj = { :resources => os_types, :job => { :id => saved_job_id, :tags => { - :user => user, - :url_string => "floaty://#{user}/#{saved_job_id}", + :user => user, }, }, } + if options["priority"] + if options["priority"] == "high" + req_obj[:priority] = 1 + elsif options["priority"] == "medium" + req_obj[:priority] = 2 + elsif options["priority"] == "low" + req_obj[:priority] = 3 + else + req_obj[:priority] = options["priority"].to_i + end + end + + puts "Posting to ABS #{req_obj.to_json}" if verbose + # os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') # raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? puts "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." - res = conn.post 'api/v2/request', reqObj.to_json + res = conn.post 'request', req_obj.to_json - i = 0 retries = 360 raise AuthError, "HTTP #{res.status}: The token provided could not authenticate to the pooler.\n#{res_body}" if res.status == 401 (1..retries).each do |i| - queue_place, res_body = check_queue(conn, saved_job_id, reqObj) + queue_place, res_body = check_queue(conn, saved_job_id, req_obj) return translated(res_body) if res_body - puts "Waiting 10 seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" - sleep(10) + + sleepSeconds = 10 if i >= 10 + sleepSeconds = i if i < 10 + puts "Waiting #{sleepSeconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + + sleep(sleepSeconds) end nil end @@ -215,11 +242,11 @@ class ABS vmpooler_formatted_body end - def self.check_queue(conn, job_id, reqObj) - queue_info_res = conn.get "/status/queue/info/#{job_id}" + def self.check_queue(conn, job_id, req_obj) + queue_info_res = conn.get "status/queue/info/#{job_id}" queue_info = JSON.parse(queue_info_res.body) - res = conn.post 'api/v2/request', reqObj.to_json + res = conn.post 'request', req_obj.to_json unless res.body.empty? res_body = JSON.parse(res.body) @@ -228,26 +255,28 @@ class ABS [queue_info['queue_place'], nil] end - def self.snapshot(verbose, url, hostname, token) + def self.snapshot(_verbose, _url, _hostname, _token) puts "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" end def self.status(verbose, url) conn = Http.get_conn(verbose, url) - res = conn.get '/status' - JSON.parse(res.body) + res = conn.get 'status' + + return res.body == "OK" end def self.summary(verbose, url) conn = Http.get_conn(verbose, url) - res = conn.get '/summary' + res = conn.get 'summary' JSON.parse(res.body) end def self.query(verbose, url, hostname) - return @@active_hostnames if @@active_hostnames + return @active_hostnames if @active_hostnames + puts "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" conn = Http.get_conn(verbose, url) diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index d094288..89f6c64 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) + def self.retrieve(verbose, os_type, token, url, _user, _options) conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 354b8a9..a735c3b 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -28,7 +28,7 @@ class Pooler vms end - def self.retrieve(verbose, os_type, token, url, user) + def self.retrieve(verbose, os_type, token, url, _user, _options) # NOTE: # Developers can use `Utils.generate_os_hash` to # generate the os_type param. diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 951db9c..28fc90c 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -78,7 +78,7 @@ class Service def retrieve(verbose, os_types, use_token = true) puts 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil - @service_object.retrieve verbose, os_types, token_value, url, user + @service_object.retrieve verbose, os_types, token_value, url, user, @config end def ssh(verbose, host_os, use_token = true) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index eb3464a..f70eb20 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -88,8 +88,8 @@ class Utils when 'ABS' # For ABS, 'hostname' variable is the jobID if host_data['state'] == 'allocated' || host_data['state'] == 'filled' - host_data['allocated_resources'].each do |vm_name, i| - puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name["hostname"]} (#{vm_name["type"]}) <#{host_data['state']}>" + host_data['allocated_resources'].each do |vm_name, _i| + puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" end end when 'Pooler' @@ -155,6 +155,9 @@ class Utils puts "#{name.ljust(width)} #{e.red}" end end + when 'ABS' + puts "ABS Not OK".red unless status_response + puts "ABS is OK".green if status_response else raise "Invalid service type #{service.type}" end @@ -205,6 +208,7 @@ class Utils end # Prioritize an explicitly specified url, user, or token if the user provided one + service_config['priority'] = options.priority unless options.priority.nil? service_config['url'] = options.url unless options.url.nil? service_config['token'] = options.token unless options.token.nil? service_config['user'] = options.user unless options.user.nil? diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index c59e14c..5a94b72 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -36,25 +36,25 @@ describe ABS do end it 'won\'t delete a job if not all vms are listed' do - hosts = ["host1"] + 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 = ['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 diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 6863078..911c96c 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -66,7 +66,7 @@ describe NonstandardPooler do @token_status_body_active = <<~BODY { "ok": true, - "user": 'first.last', + "user": "first.last", "created": "2017-09-18 01:25:41 +0000", "last_accessed": "2017-09-21 19:46:25 +0000", "reserved_hosts": ["sol10-9", "sol10-11"] @@ -75,7 +75,7 @@ describe NonstandardPooler do @token_status_body_empty = <<~BODY { "ok": true, - "user": 'first.last', + "user": "first.last", "created": "2017-09-18 01:25:41 +0000", "last_accessed": "2017-09-21 19:46:25 +0000", "reserved_hosts": [] @@ -88,7 +88,7 @@ describe NonstandardPooler do .with(false, @nspooler_url, 'token-value') .and_return(JSON.parse(@token_status_body_active)) - list = NonstandardPooler.list_active(false, @nspooler_url, 'token-value') + list = NonstandardPooler.list_active(false, @nspooler_url, 'token-value', 'user') expect(list).to eql ['sol10-9', 'sol10-11'] end end @@ -125,7 +125,7 @@ describe NonstandardPooler do .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 { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {}) }.to raise_error(AuthError) end it 'retrieves a single vm with a token' do @@ -134,7 +134,7 @@ describe NonstandardPooler do .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') + 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-11-sparc']['hostname']).to eq 'sol11-4.delivery.puppetlabs.net' @@ -146,7 +146,7 @@ describe NonstandardPooler do .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') + 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 @@ -246,7 +246,7 @@ describe NonstandardPooler do "sol10-11": { "fqdn": "sol10-11.delivery.puppetlabs.net", "os_triple": "solaris-10-sparc", - "reserved_by_user": 'first.last', + "reserved_by_user": "first.last", "reserved_for_reason": "testing", "hours_left_on_reservation": 29.12 } diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 62035e4..dffaf2f 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -53,7 +53,7 @@ describe Pooler do vm_hash = {} vm_hash['debian-7-i386'] = 1 - expect { Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError) + expect { Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {}) }.to raise_error(AuthError) end it 'retrieves a single vm with a token' do @@ -63,7 +63,7 @@ describe Pooler do vm_hash = {} 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, 'user', {}) expect(vm_req).to be_an_instance_of Hash expect(vm_req['ok']).to equal true expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6' @@ -77,7 +77,7 @@ describe Pooler do vm_hash = {} vm_hash['debian-7-i386'] = 2 vm_hash['centos-7-x86_64'] = 1 - vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) + vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {}) expect(vm_req).to be_an_instance_of Hash expect(vm_req['ok']).to equal true expect(vm_req['debian-7-i386']['hostname']).to be_an_instance_of Array From 9a2cd816df6ce5f4b5434ca5b728014a17ea5ac1 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Tue, 3 Dec 2019 17:06:08 -0800 Subject: [PATCH 095/265] Update Rubocop to not use old cop name --- .rubocop.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fd3b135..e80ae47 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -14,9 +14,9 @@ Style/TrailingCommaInArrayLiteral: Style/TrailingCommaInArguments: EnforcedStyleForMultiline: comma -Layout/AlignHash: +Layout/HashAlignment: EnforcedHashRocketStyle: table -Layout/IndentFirstHashElement: +Layout/FirstHashElementIndentation: EnforcedStyle: consistent Style/StderrPuts: From 1e67715e2c019f7ae597889053c24a34591f0abc Mon Sep 17 00:00:00 2001 From: Brandon High Date: Wed, 4 Dec 2019 16:40:57 -0800 Subject: [PATCH 096/265] Fix rubocop issues --- .rubocop.yml | 2 ++ lib/vmfloaty.rb | 2 +- lib/vmfloaty/abs.rb | 45 +++++++++++++++++++++---------------------- lib/vmfloaty/utils.rb | 4 ++-- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e80ae47..1bbc983 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -18,6 +18,8 @@ Layout/HashAlignment: EnforcedHashRocketStyle: table Layout/FirstHashElementIndentation: EnforcedStyle: consistent +Metrics/ParameterLists: + Enabled: False Style/StderrPuts: Enabled: false diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 285958c..3672c8b 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -17,7 +17,7 @@ require 'vmfloaty/ssh' class Vmfloaty include Commander::Methods - def run + def run # rubocop:disable Metrics/AbcSize program :version, Vmfloaty::VERSION program :description, 'A CLI helper tool for Puppet Labs VM poolers to help you stay afloat' diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 29468c6..18347ed 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -82,10 +82,10 @@ class ABS jobs_to_delete = [] - retStatus = {} + ret_status = {} hosts.each do |host| - retStatus[host] = { - 'ok' => false + ret_status[host] = { + 'ok' => false, } end @@ -95,11 +95,11 @@ class ABS req_hash['allocated_resources'].each do |vm_name, _i| if hosts.include? vm_name['hostname'] if all_job_resources_accounted_for(req_hash['allocated_resources'], hosts) - retStatus[vm_name['hostname']] = { - 'ok' => true + ret_status[vm_name['hostname']] = { + 'ok' => true, } jobs_to_delete.push(req_hash) - else + else puts "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" end end @@ -118,7 +118,7 @@ class ABS return_result = conn.post 'return', req_obj.to_json req_obj['hosts'].each do |host| - response_body[host["hostname"]] = { 'ok' => true } if return_result.body == "OK" + response_body[host['hostname']] = { 'ok' => true } if return_result.body == 'OK' end end @@ -187,16 +187,16 @@ class ABS }, } - if options["priority"] - if options["priority"] == "high" - req_obj[:priority] = 1 - elsif options["priority"] == "medium" - req_obj[:priority] = 2 - elsif options["priority"] == "low" - req_obj[:priority] = 3 - else - req_obj[:priority] = options["priority"].to_i - end + if options['priority'] + req_obj[:priority] = if options['priority'] == 'high' + 1 + elsif options['priority'] == 'medium' + 2 + elsif options['priority'] == 'low' + 3 + else + options['priority'].to_i + end end puts "Posting to ABS #{req_obj.to_json}" if verbose @@ -214,12 +214,11 @@ class ABS queue_place, res_body = check_queue(conn, saved_job_id, req_obj) return translated(res_body) if res_body - - sleepSeconds = 10 if i >= 10 - sleepSeconds = i if i < 10 - puts "Waiting #{sleepSeconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + sleep_seconds = 10 if i >= 10 + sleep_seconds = i if i < 10 + puts "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" - sleep(sleepSeconds) + sleep(sleep_seconds) end nil end @@ -264,7 +263,7 @@ class ABS res = conn.get 'status' - return res.body == "OK" + res.body == 'OK' end def self.summary(verbose, url) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index f70eb20..1e2e678 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -156,8 +156,8 @@ class Utils end end when 'ABS' - puts "ABS Not OK".red unless status_response - puts "ABS is OK".green if status_response + puts 'ABS Not OK'.red unless status_response + puts 'ABS is OK'.green if status_response else raise "Invalid service type #{service.type}" end From 17c18679e235ccbe3df5c1c85f25262556ed468e Mon Sep 17 00:00:00 2001 From: Brandon High Date: Tue, 3 Dec 2019 17:00:41 -0800 Subject: [PATCH 097/265] Update pooler provider to throw an exception if the API returns non-OK Prior to this commit the API could fail and return `ok: false` but floaty wouldn't recognize that as a failure. This commit updates the pooler code to check for `ok` and raise and error with the body of what the api returns if it's non-truthy. --- lib/vmfloaty/pooler.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index a735c3b..b8a492e 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -72,7 +72,14 @@ class Pooler end res_body = JSON.parse(response.body) - res_body + + if res_body['ok'] + res_body + elsif response.status == 401 + raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" + else + raise ModifyError, "HTTP #{response.status}: Failed to modify VMs from the pooler vm/#{hostname}. #{res_body}" + end end def self.disk(verbose, url, hostname, token, disk) From 6605a3eee6791cc160fbe050464920ddae144de5 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Thu, 5 Dec 2019 10:08:07 -0800 Subject: [PATCH 098/265] Minor version bump to 0.9.0 I figure adding a new service like ABS would necessitate at least a minor bump since it's more than a security/bug fix. --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 5bc74da..7a3f4de 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.8.2' + VERSION = '0.9.0' end From 2c456f1157bd671674bad8eee3d9de607d072938 Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Mon, 16 Dec 2019 08:03:44 -0800 Subject: [PATCH 099/265] ABS will sometimes return null values in the /status/queue endpoint --- Gemfile | 2 ++ lib/vmfloaty/abs.rb | 16 ++++++++++++---- spec/vmfloaty/abs_spec.rb | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index adb75fe..2d04715 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,8 @@ gemspec gem 'rake', :require => false group :test do + gem 'pry' + gem 'rb-readline' gem 'rspec', '~> 3.5.0' gem 'rubocop', '~> 0.52' gem 'webmock', '1.21.0' diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 18347ed..1cd9dc1 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -57,11 +57,19 @@ class ABS requests = JSON.parse(res.body) ret_val = [] - requests.each do |req| - req_hash = JSON.parse(req) - next unless user == req_hash['request']['job']['user'] - ret_val.push(req_hash) + requests.each do |req| + next if req == 'null' + + req_hash = JSON.parse(req) + + begin + next unless user == req_hash['request']['job']['user'] + + ret_val.push(req_hash) + rescue NoMethodError + puts "Warning: couldn't parse line returned from abs/status/queue: ".yellow + end end ret_val diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index 5a94b72..7e46a00 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -58,5 +58,39 @@ describe ABS do ] expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(true) end + + before :each do + @abs_url = 'https://abs.example.com' + end + + describe '#test_abs_status_queue_endpoint' do + before :each do + # rubocop:disable Metrics/LineLength + @active_requests_response = ' + [ + "{ \"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"take-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:45:29 +0000\":\"Allocated take-this.delivery.puppetlabs.net for job 1576255517241\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255517241\",\"tags\":{\"user\":\"test-user\"},\"user\":\"test-user\",\"time-received\":1576255519},\"priority\":1}}", + "null", + "{\"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"not-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:46:14 +0000\":\"Allocated not-this.delivery.puppetlabs.net for job 1576255565159\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255565159\",\"tags\":{\"user\":\"not-test-user\"},\"user\":\"not-test-user\",\"time-received\":1576255566},\"priority\":1}}" + ]' + # rubocop:enable Metrics/LineLength + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' + @test_user = 'test-user' + end + + it 'will skip a line with a null value returned from abs' do + stub_request(:get, 'https://abs.example.com/status/queue') + .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', + }], + ) + end + end end end From dc3bfecd288dce91251235c9b4cfd4cd5ad9a9a2 Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Tue, 14 Jan 2020 09:39:49 -0800 Subject: [PATCH 100/265] Adding spec test to ensure that all the interfaces are the same, while doing so, fix the broken interfaces for delete on vmpooler and nonstandard pooler(they were passed 5 by service.rb but expected 4) --- lib/vmfloaty/abs.rb | 12 ++++++++ lib/vmfloaty/nonstandard_pooler.rb | 2 +- lib/vmfloaty/pooler.rb | 2 +- spec/vmfloaty/nonstandard_pooler_spec.rb | 4 +-- spec/vmfloaty/pooler_spec.rb | 4 +-- spec/vmfloaty/vmfloaty_services_spec.rb | 39 ++++++++++++++++++++++++ 6 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 spec/vmfloaty/vmfloaty_services_spec.rb diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 1cd9dc1..6673eb3 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -290,4 +290,16 @@ class ABS res = conn.get "host/#{hostname}" JSON.parse(res.body) end + + def self.modify(_verbose, _url, _hostname, _token, _modify_hash) + raise NoMethodError, 'modify is not defined for ABS' + end + + def self.disk(_verbose, _url, _hostname, _token, _disk) + raise NoMethodError, 'disk is not defined for ABS' + end + + def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha) + raise NoMethodError, 'revert is not defined for ABS' + end end diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 89f6c64..90722c0 100644 --- a/lib/vmfloaty/nonstandard_pooler.rb +++ b/lib/vmfloaty/nonstandard_pooler.rb @@ -77,7 +77,7 @@ class NonstandardPooler raise ModifyError, 'Configured service type does not support snapshots' end - def self.delete(verbose, url, hosts, token) + def self.delete(verbose, url, hosts, token, _user) raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil? conn = Http.get_conn(verbose, url) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index b8a492e..c85daf3 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -94,7 +94,7 @@ class Pooler res_body end - def self.delete(verbose, url, hosts, token) + def self.delete(verbose, url, hosts, token, _user) raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' if token.nil? conn = Http.get_conn(verbose, url) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 911c96c..8bcfe3c 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -274,7 +274,7 @@ describe NonstandardPooler do .with(:headers => @auth_token_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', nil) expect(request['sol11-7']['ok']).to be true end @@ -283,7 +283,7 @@ describe NonstandardPooler do .with(:headers => @auth_token_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', nil) expect(request['fakehost']['ok']).to be false end end diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index dffaf2f..6d7def0 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -119,11 +119,11 @@ describe Pooler do .with(:headers => { 'X-Auth-Token' => 'mytokenfile' }) .to_return(:status => 200, :body => @delete_response_body_success, :headers => {}) - expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response + expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile', nil)).to eq @delete_response end it 'raises a token error if no token provided' do - expect { Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil) }.to raise_error(TokenError) + expect { Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil, nil) }.to raise_error(TokenError) end end diff --git a/spec/vmfloaty/vmfloaty_services_spec.rb b/spec/vmfloaty/vmfloaty_services_spec.rb new file mode 100644 index 0000000..4fe50e9 --- /dev/null +++ b/spec/vmfloaty/vmfloaty_services_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# All of the interfaces for the different services must be the +# same, otherwise there will be errors when you change the caller +# for the services from services.rb. +# + +require_relative '../../lib/vmfloaty/pooler' +require_relative '../../lib/vmfloaty/abs' +require_relative '../../lib/vmfloaty/nonstandard_pooler' + +shared_examples 'a vmfloaty service' do + it { is_expected.to respond_to(:delete).with(5).arguments } + it { is_expected.to respond_to(:disk).with(5).arguments } + it { is_expected.to respond_to(:list).with(3).arguments } + it { is_expected.to respond_to(:list_active).with(4).arguments } + it { is_expected.to respond_to(:modify).with(5).arguments } + it { is_expected.to respond_to(:retrieve).with(6).arguments } + it { is_expected.to respond_to(:revert).with(5).arguments } + it { is_expected.to respond_to(:query).with(3).arguments } + it { is_expected.to respond_to(:snapshot).with(4).arguments } + it { is_expected.to respond_to(:status).with(2).arguments } + it { is_expected.to respond_to(:summary).with(2).arguments } +end + +describe Pooler do + subject { Pooler } + it_behaves_like 'a vmfloaty service' +end + +describe ABS do + subject { ABS } + it_behaves_like 'a vmfloaty service' +end + +describe NonstandardPooler do + subject { NonstandardPooler } + it_behaves_like 'a vmfloaty service' +end From f1be1fec2335ae069c912d111ed84d76aeee5376 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Tue, 14 Jan 2020 10:03:34 -0800 Subject: [PATCH 101/265] Bump version.rb to 0.9.1 For 0.9.1 release. Includes: - Bug fix for delete action on vmpooler and nspooler #58 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 7a3f4de..7c890ac 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.9.0' + VERSION = '0.9.1' end From 51a7eb809e084c99f0c77421e65ae2379d0aa188 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Fri, 17 Jan 2020 15:12:22 -0800 Subject: [PATCH 102/265] (QENG-7604) Add support for Job IDs to ABS delete This commit adds support for passing in a JobID when deleting with ABS. --- lib/vmfloaty.rb | 4 +++- lib/vmfloaty/abs.rb | 5 +++++ spec/vmfloaty/abs_spec.rb | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 3672c8b..9165423 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -185,9 +185,11 @@ class Vmfloaty command :delete do |c| c.syntax = 'floaty delete hostname,hostname2 [options]' + c.syntax += "\n floaty delete job1,job2 [options] (only supported with ABS)" c.summary = 'Schedules the deletion of a host or hosts' - c.description = 'Given a comma separated list of hostnames, or --all for all vms, vmfloaty makes a request to the pooler service to schedule the deletion of those vms.' + c.description = 'Given a comma separated list of hostnames, or --all for all vms, vmfloaty makes a request to the pooler service to schedule the deletion of those vms. If you are using the ABS service, you can also pass in JobIDs here. Note that passing in a Job ID will delete *all* of the hosts in the job.' # rubocop:disable Layout/LineLength c.example 'Schedules the deletion of a host or hosts', 'floaty delete myhost1,myhost2 --url http://vmpooler.example.com' + c.example 'Schedules the deletion of a JobID or JobIDs', 'floaty delete 1579300120799,1579300120800 --url http://abs.example.com' c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--all', 'Deletes all vms acquired by a token' diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 6673eb3..259f411 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -100,6 +100,11 @@ class ABS requests.each do |req_hash| next unless req_hash['state'] == 'allocated' || req_hash['state'] == 'filled' + if hosts.include? req_hash['request']['job']['id'] + jobs_to_delete.push(req_hash) + next + end + req_hash['allocated_resources'].each do |vm_name, _i| if hosts.include? vm_name['hostname'] if all_job_resources_accounted_for(req_hash['allocated_resources'], hosts) diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index 7e46a00..b59380a 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -65,14 +65,14 @@ describe ABS do describe '#test_abs_status_queue_endpoint' do before :each do - # rubocop:disable Metrics/LineLength + # rubocop:disable Layout/LineLength @active_requests_response = ' [ "{ \"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"take-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:45:29 +0000\":\"Allocated take-this.delivery.puppetlabs.net for job 1576255517241\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255517241\",\"tags\":{\"user\":\"test-user\"},\"user\":\"test-user\",\"time-received\":1576255519},\"priority\":1}}", "null", "{\"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"not-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:46:14 +0000\":\"Allocated not-this.delivery.puppetlabs.net for job 1576255565159\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255565159\",\"tags\":{\"user\":\"not-test-user\"},\"user\":\"not-test-user\",\"time-received\":1576255566},\"priority\":1}}" ]' - # rubocop:enable Metrics/LineLength + # rubocop:enable Layout/LineLength @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' @test_user = 'test-user' end @@ -92,5 +92,35 @@ describe ABS do ) end end + + describe '#test_abs_delete_jobid' do + before :each do + # rubocop:disable Layout/LineLength + @active_requests_response = ' + [ + "{ \"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 } + # rubocop:enable Layout/LineLength + @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' + @test_user = 'test-user' + # Job ID + @hosts = ['1579300120799'] + end + + it 'will delete the whole job' do + stub_request(:get, 'https://abs.example.com/status/queue') + .to_return(:status => 200, :body => @active_requests_response, :headers => {}) + stub_request(:post, 'https://abs.example.com/return') + .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 }, + ) + end + end end end From ac14629eb391eaf4646a968b6a453c34daa86158 Mon Sep 17 00:00:00 2001 From: Mikker Gimenez-Peterson Date: Mon, 27 Jan 2020 15:16:20 -0800 Subject: [PATCH 103/265] SSH Command respects ABS now and tests should fail if the API changes again --- lib/vmfloaty/service.rb | 2 +- lib/vmfloaty/ssh.rb | 16 +++++++++---- spec/vmfloaty/ssh_spec.rb | 49 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 spec/vmfloaty/ssh_spec.rb diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 28fc90c..6a89b3d 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -91,7 +91,7 @@ class Service STDERR.puts 'Could not get token... requesting vm without a token anyway...' end end - Ssh.ssh(verbose, host_os, token_value, url) + Ssh.ssh(verbose, self, host_os, token_value) end def pretty_print_running(verbose, hostnames = []) diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index 9adee9c..f100b8b 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -14,21 +14,27 @@ class Ssh nil end - def self.ssh(verbose, host_os, token, url) + def self.command_string(verbose, service, host_os, use_token) ssh_path = which('ssh') raise 'Could not determine path to ssh' unless ssh_path os_types = {} os_types[host_os] = 1 - response = Pooler.retrieve(verbose, os_types, token, url) - raise "Could not get vm from vmpooler:\n #{response}" unless response['ok'] + response = service.retrieve(verbose, os_types, use_token) + raise "Could not get vm from #{service.type}:\n #{response}" unless response['ok'] user = /win/.match?(host_os) ? 'Administrator' : 'root' - hostname = "#{response[host_os]['hostname']}.#{response['domain']}" - cmd = "#{ssh_path} #{user}@#{hostname}" + hostname = response[host_os]['hostname'] + hostname = response[host_os]['hostname'][0] if response[host_os]['hostname'].is_a?(Array) + hostname = "#{hostname}.#{response['domain']}" unless hostname.end_with?('puppetlabs.net') + "#{ssh_path} #{user}@#{hostname}" + end + + def self.ssh(verbose, service, host_os, use_token) + cmd = command_string(verbose, service, host_os, use_token) # TODO: Should this respect more ssh settings? Can it be configured # by users ssh config and does this respect those settings? Kernel.exec(cmd) diff --git a/spec/vmfloaty/ssh_spec.rb b/spec/vmfloaty/ssh_spec.rb new file mode 100644 index 0000000..c780a88 --- /dev/null +++ b/spec/vmfloaty/ssh_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'vmfloaty/ssh' + +class ServiceStub + def retrieve(_verbose, os_types, _use_token) + if os_types.keys[0] == 'abs_host_string' + return { + os_types.keys[0] => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net'] }, + 'ok' => true, + } + end + + { + os_types.keys[0] => { 'hostname' => 'vmpooler-hostname' }, + 'domain' => 'delivery.puppetlabs.net', + 'ok' => true, + } + end + + def type + return 'abs' if os_types == 'abs_host_string' + return 'vmpooler' if os_types == 'vmpooler_host_string' + end +end + +describe Ssh do + before :each do + end + + it 'gets a hostname string for abs' do + verbose = false + service = ServiceStub.new + host_os = 'abs_host_string' + use_token = false + cmd = Ssh.command_string(verbose, service, host_os, use_token) + expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/) + end + + it 'gets a hostname string for vmpooler' do + verbose = false + service = ServiceStub.new + host_os = 'vmpooler_host_string' + use_token = false + cmd = Ssh.command_string(verbose, service, host_os, use_token) + expect(cmd).to match(/ssh root@vmpooler-hostname.delivery.puppetlabs.net/) + end +end From c417c3574c551fe84c6e27bebd5a5abc4d94e164 Mon Sep 17 00:00:00 2001 From: Nick Lewis Date: Tue, 28 Jan 2020 13:05:33 -0800 Subject: [PATCH 104/265] Bump faraday dependency for Ruby 2.7 compatibility The only significant changes between 0.15.4 and 0.17.3 are silencing some deprecation warnings on Ruby 2.7. --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 0e22a4a..27f335c 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -20,5 +20,5 @@ Gem::Specification.new do |s| s.add_dependency 'colorize', '~> 0.8.1' s.add_dependency 'commander', '~> 4.4.3' - s.add_dependency 'faraday', '~> 0.15.0' + s.add_dependency 'faraday', '~> 0.17.0' end From 05dd5bb6b240c53388ee8d65e1df02b8c94593cd Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 28 Jan 2020 13:47:13 -0800 Subject: [PATCH 105/265] Update PULL_REQUEST_TEMPLATE --- .github/PULL_REQUEST_TEMPLATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE index 2bc3c92..b1d9431 100644 --- a/.github/PULL_REQUEST_TEMPLATE +++ b/.github/PULL_REQUEST_TEMPLATE @@ -17,5 +17,5 @@ FIXME ## Reviewers -@demophoon +@highb @briancain From 331444751deb866f2b3a7a029e611d90fc52029e Mon Sep 17 00:00:00 2001 From: Brandon High Date: Wed, 5 Feb 2020 11:05:20 -0800 Subject: [PATCH 106/265] Create gempush.yml Github Action I think this action should be able to build/push the gem whenever a matching is pushed. --- .github/workflows/gempush.yml | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/gempush.yml diff --git a/.github/workflows/gempush.yml b/.github/workflows/gempush.yml new file mode 100644 index 0000000..b2abb6b --- /dev/null +++ b/.github/workflows/gempush.yml @@ -0,0 +1,41 @@ +name: Ruby Gem + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build: + name: Build + Publish + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Ruby 2.6 + uses: actions/setup-ruby@v1 + with: + version: 2.6.x + + - name: Publish to GPR + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:github: Bearer ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem build *.gemspec + gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem + env: + GEM_HOST_API_KEY: ${{secrets.GPR_AUTH_TOKEN}} + OWNER: username + + - name: Publish to RubyGems + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem build *.gemspec + gem push *.gem + env: + GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} From 1e38bb424471db81964aaaedd2f1a15be160a006 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Wed, 5 Feb 2020 11:08:10 -0800 Subject: [PATCH 107/265] Bump version.rb to 0.9.2 for release --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 7c890ac..145a681 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.9.1' + VERSION = '0.9.2' end From 6697077adf34ed8c72699e29e5e90ec2fcf30d49 Mon Sep 17 00:00:00 2001 From: Brandon High Date: Wed, 5 Feb 2020 15:50:53 -0800 Subject: [PATCH 108/265] Update gempush action to remove GPR publish We don't need to publish to GPR right now. --- .github/workflows/gempush.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/gempush.yml b/.github/workflows/gempush.yml index b2abb6b..0d8a445 100644 --- a/.github/workflows/gempush.yml +++ b/.github/workflows/gempush.yml @@ -17,18 +17,6 @@ jobs: with: version: 2.6.x - - name: Publish to GPR - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:github: Bearer ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - gem build *.gemspec - gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem - env: - GEM_HOST_API_KEY: ${{secrets.GPR_AUTH_TOKEN}} - OWNER: username - - name: Publish to RubyGems run: | mkdir -p $HOME/.gem From 4ff9b9d0d5ca556e2a854be9e254ffafcf91060a Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 1 Jul 2020 14:41:57 -0700 Subject: [PATCH 109/265] Remove old maintainer note --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 9e278fc..3e71791 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ A CLI helper tool for [Puppet Labs vmpooler](https://github.com/puppetlabs/vmpoo -This project is still supported by @briancain and @demophoon. Ping either of us if you'd like something merged and released. - ## Install Grab the latest from ruby gems... From d4bd4f5163991abfca2f12c77bb7f85f0dfa3eef Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 1 Jul 2020 14:52:39 -0700 Subject: [PATCH 110/265] Comment out rubocop rules that aren't helpful --- .rubocop.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1bbc983..7b9aed3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -14,14 +14,21 @@ Style/TrailingCommaInArrayLiteral: Style/TrailingCommaInArguments: EnforcedStyleForMultiline: comma +Layout/AlignHash: + Enabled: false Layout/HashAlignment: - EnforcedHashRocketStyle: table + EnforcedHashRocketStyle: table Layout/FirstHashElementIndentation: EnforcedStyle: consistent Metrics/ParameterLists: Enabled: False +Layout/SpaceAroundOperators: + Enabled: false Style/StderrPuts: Enabled: false Style/WordArray: Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false From e942e7534d71120057c39bdabdc2c074c6e2d2e3 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 1 Jul 2020 14:55:32 -0700 Subject: [PATCH 111/265] Remove rubocop --- .rubocop.yml | 34 ---------------------------------- .rubocop_todo.yml | 46 ---------------------------------------------- .travis.yml | 2 +- 3 files changed, 1 insertion(+), 81 deletions(-) delete mode 100644 .rubocop.yml delete mode 100644 .rubocop_todo.yml diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index 7b9aed3..0000000 --- a/.rubocop.yml +++ /dev/null @@ -1,34 +0,0 @@ -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: - Enabled: false -Layout/HashAlignment: - EnforcedHashRocketStyle: table -Layout/FirstHashElementIndentation: - EnforcedStyle: consistent -Metrics/ParameterLists: - Enabled: False -Layout/SpaceAroundOperators: - Enabled: false - -Style/StderrPuts: - Enabled: false -Style/WordArray: - Enabled: false - -Metrics/CyclomaticComplexity: - Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml deleted file mode 100644 index cb32ba8..0000000 --- a/.rubocop_todo.yml +++ /dev/null @@ -1,46 +0,0 @@ -# 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 diff --git a/.travis.yml b/.travis.yml index 041e835..3b2336c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ sudo: false language: ruby rvm: - 2.6.5 -script: bundle exec rake rubocop spec +script: bundle exec rake spec From 28fb9290d424b253c3bb7ac93b7f9a54bcdd64b1 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Thu, 2 Jul 2020 10:39:52 -0400 Subject: [PATCH 112/265] Update docs This chane updates docs to reflect that ownership has moved to the DIO team at Puppet. It also includes some formatting changes. --- .github/PULL_REQUEST_TEMPLATE | 1 + CODEOWNERS | 6 ++ README.md | 119 ++++++++++++++++++++++------------ float.jpg | Bin 0 -> 11329 bytes lib/vmfloaty.rb | 2 +- vmfloaty.gemspec | 12 +++- 6 files changed, 94 insertions(+), 46 deletions(-) create mode 100644 CODEOWNERS create mode 100644 float.jpg diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE index b1d9431..0259cfe 100644 --- a/.github/PULL_REQUEST_TEMPLATE +++ b/.github/PULL_REQUEST_TEMPLATE @@ -17,5 +17,6 @@ FIXME ## Reviewers +@puppetlabs/dio @highb @briancain diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..b5b2b0e --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,6 @@ +# Set Puppet's DIO team as the default code owner +* @puppetlabs/dio + +# External code owners +* @briancain +* @highb diff --git a/README.md b/README.md index 3e71791..b9c170d 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,61 @@ -vmfloaty -======== +# vmfloaty -[![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) [![Build Status](https://travis-ci.org/briancain/vmfloaty.svg?branch=master)](https://travis-ci.org/briancain/vmfloaty) +[![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) [![Build Status](https://travis-ci.com/puppetlabs/vmfloaty.svg?branch=master)](https://travis-ci.com/puppetlabs/vmfloaty) -A CLI helper tool for [Puppet Labs vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. +A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. - +![float image](float.jpg) + +- [Install](#install) +- [Usage](#usage) + - [Example workflow](#example-workflow) + - [vmfloaty dotfile](#vmfloaty-dotfile) + - [Basic configuration](#basic-configuration) + - [Default to Puppet's ABS instead of vmpooler](#default-to-puppets-abs-instead-of-vmpooler) + - [Configuring multiple services](#configuring-multiple-services) + - [Using a Nonstandard Pooler service](#using-a-nonstandard-pooler-service) + - [Valid config keys](#valid-config-keys) + - [Tab Completion](#tab-completion) +- [vmpooler API](#vmpooler-api) +- [Using the Pooler class](#using-the-pooler-class) + - [Example Projects](#example-projects) +- [Special thanks](#special-thanks) ## Install Grab the latest from ruby gems... -``` -$ gem install vmfloaty -... -... -$ floaty --help +```bash +gem install vmfloaty ``` ## Usage -``` - delete Schedules the deletion of a host or hosts - get Gets a vm or vms based on the os argument - help Display global or [command] help documentation - list Shows a list of available vms from the pooler or vms obtained with a token - modify Modify a vms tags, time to live, and disk space - query Get information about a given vm - revert Reverts a vm to a specified snapshot - snapshot Takes a snapshot of a given vm - ssh Grabs a single vm and sshs into it - status Prints the status of pools in vmpooler - summary Prints a summary of vmpooler - token Retrieves or deletes a token or checks token status +```plain +$ floaty --help + NAME: + + floaty + + DESCRIPTION: + + A CLI helper tool for Puppet's vmpooler to help you stay afloat + + COMMANDS: + + completion Outputs path to completion script + delete Schedules the deletion of a host or hosts + get Gets a vm or vms based on the os argument + help Display global or [command] help documentation + list Shows a list of available vms from the pooler or vms obtained with a token + modify Modify a VM's tags, time to live, disk space, or reservation reason + query Get information about a given vm + revert Reverts a vm to a specified snapshot + snapshot Takes a snapshot of a given vm + ssh Grabs a single vm and sshs into it + status Prints the status of pools in the pooler service + summary Prints a summary of a pooler service + token Retrieves or deletes a token or checks token status GLOBAL OPTIONS: @@ -50,7 +73,7 @@ $ floaty --help Grabbing a token for authenticated pooler requests: -``` +```bash floaty token get --user username --url https://vmpooler.example.net/api/v1 ``` @@ -58,7 +81,7 @@ This command will then ask you to log in. If successful, it will return a token Grabbing vms: -``` +```bash floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring --url https://vmpooler.example.net/api/v1 ``` @@ -69,7 +92,7 @@ If you do not wish to continually specify various config options with the cli, y #### Basic configuration ```yaml -# file at /Users/me/.vmfloaty.yml +# file at ~/.vmfloaty.yml url: 'https://vmpooler.example.net/api/v1' user: 'brian' token: 'tokenstring' @@ -77,6 +100,16 @@ token: 'tokenstring' Now vmfloaty will use those config files if no flag was specified. +#### Default to Puppet's ABS instead of vmpooler + +```yaml +# file at ~/.vmfloaty.yml +url: 'https://abs.example.net' +user: 'brian' +token: 'tokenstring' +type: 'abs' +``` + #### Configuring multiple services Most commands allow you to specify a `--service ` option to allow the use of multiple vmpooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services. @@ -103,14 +136,16 @@ services: Examples using the above configuration: List available vm types from our main vmpooler instance: -```sh + +```bash floaty list --service main # or, since the first configured service is used by default: floaty list ``` List available vm types from our alternate vmpooler instance: -```sh + +```bash floaty list --service alternate ``` @@ -138,7 +173,7 @@ services: With this configuration, you could list available OS types from nspooler like this: -```sh +```bash floaty list --service ns ``` @@ -146,20 +181,16 @@ floaty list --service ns Here are the keys that vmfloaty currently supports: -- verbose - + Boolean -- token - + String -- user - + String -- url - + String -- services - + Map +- verbose (Boolean) +- token (String) +- user (String) +- url (String) +- services (String) +- type (String) ### Tab Completion -There is a basic completion script for Bash (and possibly other shells) included with the gem in the [extras/completions](https://github.com/briancain/vmfloaty/blob/master/extras/completions) folder. To activate, that file simply needs to be sourced somehow in your shell profile. +There is a basic completion script for Bash (and possibly other shells) included with the gem in the [extras/completions](https://github.com/puppetlabs/vmfloaty/blob/master/extras/completions) folder. To activate, that file simply needs to be sourced somehow in your shell profile. For convenience, the path to the completion script for the currently active version of the gem can be found with the `floaty completion` subcommand. This makes it easy to add the completion script to your profile like so: @@ -184,6 +215,10 @@ vmfloaty providers a `Pooler` class that gives users the ability to make request ### Example Projects - [John McCabe: vmpooler-bitbar](https://github.com/johnmccabe/vmpooler-bitbar/) - + vmpooler status and management in your menubar with bitbar + - vmpooler status and management in your menubar with bitbar - [Brian Cain: vagrant-vmpooler](https://github.com/briancain/vagrant-vmpooler) - + Use Vagrant to manage your vmpooler instances + - Use Vagrant to manage your vmpooler instances + +## Special thanks + +Special thanks to [Brian Cain](https://github.com/briancain) as he is the original author of vmfloaty! Vast amounts of this code exist thanks to his efforts. diff --git a/float.jpg b/float.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87b06f47f2ed7e1e07c0504c8f1fe7e4d4ca76f3 GIT binary patch literal 11329 zcmex=Bm<7<_#hv=|r|I2c$Ng&3F_7#J8C z7#SECr5ISjYz77|Mrk-Zh*1NohKYfpJ(Gb2swRp70z9C62+h2J5vrPzfnfm?T=j_s z%m_9}PKf)l-z`)4L2nJwnAXhOlv#_$Ub8vET|3AX8 zRe*tsk(rr^g_)HVWDR32BNH(iUwW$pkka< z)WpdpCN3cY31zV>gMj@=@lFj8WtWA8I_!pnwFlCnN?g;T2@|B zS=HRq+ScCD*)?hMl&RCE&zL!D(c&dbmn~nha@D5ITefc7zGLUELx+zXJ$C%W$y1ju zU%7hi`i+~n9zJ^fP+YHVO%uGxm#LUdh!pzLV$^nWNRxWmSHVz&x9v*HkZf;&a zApu@KK|XG70WkqVVG&VLQ67GA2{91~ArVoL|F;>O8JSsFSXo#(Sy?$nc)58+NCyA! zGO#f4{=db*!_3IQB*-ktV9)S3Xi=92gNfi#iK8M6$vuIWdalWL)#NVtp?Cgm)U&nO zOAl0;9%=NJcd(j&XjxE?xXIiJm-1cm(l&2>FYt1n#AUTBrL|7iy*D&^dzV%k9hG9d zvsr+(l5hX-=pV|SI|QS8ox}Y&=Urpin9%d#T)4es{CxXu_m9o>f9!t5*Vbm|n?IK6 zDa%eB@)UFV>}@{NTwb%tY+dCot7Nr3T{qXs&Dv^N?7itfgYnBvI(^HEd-^0#PmJ95 zXL{mk(!Go;bbueoXR49F3x}ttKB;@y`ryxW#=HuvN$=I`54--5s`~!c^JDulO`Y<6HXm75D%$JzbZ0Qw zHgp>Qy3Su;|LAXt{I*xO?!K#_OuXIoUwB%lWcfI|*?4U!xkM0tXPr6#VTX%oStt?^p{$;-oD3k>5uhZ&A}J9O8Z9p&2@GyPqjKN+#hht!}N#esvmW} zW=|KNtGFXkI5F<;Z-JVWD|WmU{}}>#MXx?@UzekneVe;T%vd4g&&-JVQzK+w?|7{6 z;5oD0Ql6X3bKLHpKX1|8WUwPg=i?5}t*6$X`s#o2{r5Y63l{A$Km4Cz>-#3tipIUs ze^tLTb}D|J&i-S&TLk0R_2D1x_k6Jzk8&%n$@}GhC zWw=z|%1YkW9`0R{&udpLe*IU=H#&6d#gfTY%h1|1!j#s|Mi_~4c zXY%jt2Kk%wBsNYz%k!!*uf5?@ar@MrTKfTi{@ zr;)ur+hx7Q=KhS^mz}mR>-m%Y?K=O?mv89NY0iIqYqv(poxZ8bNAC0I{b7EzH~8@O z#95EMcV;Ilr%Vq#lRxkGgvGU5}5^R3*(oG?GxE{;mc}Yt8=1VmoAAmi3B#RSj_x0eD%}|&sV%UnbF_) z_{`-SiJA{I_olD@&%pJc!ThI8%|3|__MMNS{e>#hPTf5$H2s_4Po6byoYn@8-(S9s zdEZ%|GHuKL?x+uP`>qu&yQ$pw^u|7i6Pi|Y=FB@g@ke-d{gSVbW-qMh`hIBgLu1>S z_O`p_>{h?1_xk$!>5Ulob8D4*ShZIKb1>sx7r%L(|#@8dSB$jw$S#UZ)2`^)o4H5-%}@Q zHvQt?Wq0OY^je;C?b2iEDgPO`dA_`;JzDcLaaG0SZ&5#*<>uDfUR(U&_972!?j;+) zmjoX2T2mR=d-MJ6=38N>Q>Lb$_x!tV_4U(dZch`vzH6=C-SZoYUDIDkz3uNT>Glow z-Qm4jddHECUhQqce`|M#wPn8$4hoN!sb!d~CAJ>ox_BJ7>yabD?6_=K$)I9#}`eWDkNBMm^cG4BaCFeyRzfIU6 z=xxT#aBq>~XZf1siE%F<`txP{XW*#e&rcP*D7%T@s?O?_0qslMHB zYwaWc4y(g6_3vdWM9y?NzO$iniNuSd!Y}K-AE|mXPy1@Qo@ z9(h_i_|d$3fiFtKYql-f7C)13`O3RL76+P}t8*ABwa8C1{m&pD992~|eNN4m%&Kxf z?X{Op?y-x$o6}-dH}&$F{+xq|u0{M+^qcP-n$-f3l1zrrYTY$F?sulvrP$99 z{qW0Sn{blrO)bN4|92ZK5`V~CKb>Y$J2$U%OaHwc_J+Tn#eU7)Uo~&O`l`R-C;D{t zZ>?E3&3<<{@2wR-3%fekA75K}OFp&C__t0~Nbb^pugP!!eR;Z1{@#M9DXEu!eT@0G zarw_lZ;v_ETfI5^idE-^0@u0h)V&3Q-d;~w1Fv>I;6Jx4>P5ci?R)8K{vDI&y%sO< z>Ym=N7Lm>V8zQI4f4aCKHSvqI`}6o{|D?(Kr!2p$bAQ<1s`Np=$z-i0gV15IpEv47 z)_%79bIzXYjqlLVzrX*?^RK+x>qXCGS;gP` znSE(VZ=N{&+Qh7=G~=VC^X)3%&0ZP%BR=4_@AfmxI}_EPPN?r+xbF7RI+;s#1{Hj- z{ib#_y)>HCzdv8=)7t(}i^n_GRfk-z`!4Ezc-NbKqF2qgMV$&_dHM3+h41pG78Ue* z?C^{=Ty}Yv&F62WAM;jz_|I_s*Yv}>sTUu4rv5fwCCX{=b2iK8ZLW&#{~6-;Ee@Xb zv-#Wh54$7JKYTCq;$!P>&oIfnMJ#hqf4;r*xCD#Q^S=wUU&OOkOuKzdPV~~&)t)xD zt6!JQjLy5~@x1TO^RADZep(67$roDc+1Wowvt=8I!kEn-rgRenDg2) zEG|K3>J{TB@0YgE%@?alxt@44b@|I%tXq0@r_D=9o1(me`Rw$1z3|Cf3w9nq+jG5l z*0q4cUbB8IS+hU*uH8@nb!;AZ+S4Qe7nRc(7$5c8C9>Kr4pB?zL{iUEVEvAdPugo=dt&7 z{TJW-`&{mI`B!1Aj-l?Z>MLSmhcuc6&wA=iy;bozb=s&N?V z1s|UO;aXE~d&GOw>CpJCM;i~+P11kf{Nws{p;NWlXZKnC(YsQoR-rIg>yG!Tm!E1E zT`|1<>|=Y6@SVQ7n^-GmB`>?z(4^wfZhh-}Rrt{Zsmhz}H+8-;(R9f${vTf-znJ@<;mhoKihuVMe|LW# zbab7v{A}%C*Do=D6WIFc^M3};t?y_4XNWU={ON4*tnY7ZA9-us@|8YvO=_a7;-2jp z68{+vOquvAY&~;l|II)Bb~1sJLTmQjy0^;vi%nE)WD29`j`M1JoxfFnxcM=@|Lyas z<~K95znv_y(4FJ9zdPkW!-4GPtN%D_Tt0kTq_ggi@=9Mti%6Z&Jf-@@P4)rWukJV2 zbDPSy#c`fn%XD>5qR%U(EN_hNmL~y~7qy+qdCgjp^b^ODCD`@R8d(Uu0^Tqz3c+t0n*T zgiEfDD1Efo?bjV&!JOiIJN!lO+{~C3bT7-iAR@|*+vd9w$3^!mm-23HS}f`N>1gbn z{?5mfkIHk|1U_t=81_)-*0Zxuau+|b{xpyYIdHjd79&^k^C^s=+asH3%}Rs zb3FU8MrGN`qT3-$7uR*y?>qjwW6|b4w(D;GnD2D?Ypqr4jt%>__r1CoYRNCXBGrDP z=)&gL@t*sRAM&)=Ht+fW%fF`o<1+oI{7>LNL!+}}TUy`iBiFN2{zWpju42~tTP^B4 z|AS%t^jmCm?benYNv;-F-uS{O`_=j%n(KRR$NadutfJP-L`rU|)Q2LM?Rv5Q=BpU? z{}8QUZ+zntW|t{%viA6elJz}jvaEJY+ok*~zIj78icNniWh^VWK8 zVpNbnDj$Dp_xkpKs@H4SSLohvFU`Ko_qZ%3^5i!2=jt`?8aLm0oZsub?C_!M-sy=V zKkhZmkNbL5;D*t4!EF{Y%ML1QMkG8ha?H@9&+JS^J*LB*u)G`X`CBioq3-pM>A&~?%~~olbKTA>Mibl|Wt!szKe|6&-u6%OwYXG( z(W_l+vLx5ME$k>VV(F_0etTVZwbfKbFPqC{?rFm89mhjM3N92)pZIFS-lQMvAC+Fh zQqaLlrvD7Vf1k_`?I^Gpj#sO3{AjlO@#$~7KZ>m`UwbEAL+^e`M)AaLhM#!KEY9yO zpVihq$)}z9V)nc}8~S8#3oyUFwQVtKhBmnJARh=S;yxuriV3d%6q%* zF7lkesQ!cRe}>Nd$MOx`3t~Mk#aG0=ePgU8wHUtMRQ$90%Xj{_@#)jAe%n#8?Q4|$nLp8u5i*aq zByE}eEZ+7%gY^9WS3dFI>OZpb(SL?p=8yOmialB$Iqz=d?v79e`L?8-(79YU9J5)R z7b%E7|MhM0-~Es8Mt#}#pJ8iOxzM|>_Y0N(GrYO_a#qrV#`yU=i?2-Cz4_O#x%#UU zUR;Pz)2uyp+;`dWOS{$@*-br{x%$$sy@nN0TZ%khZaJ}majo|zG20y{jys2ZIr@8R z(%)Uz=JM4oH(l+tQ1Eq2m-mbqf z|A%kM`}hAA?dSVrSz!|2VI_O5Y<6tiwS-!;7|rva*Ke$USUdmcKl|@j%N`oq9pkf0 zKV2y1E^}I3>fC<@uK4cymH)5)40gC<8nL~{e*TH?C(l;P&Ak#nGy7M?1)JK{H*;@) zi}ib?Q6&Fh!Ff2>@cS!5}HYghWa>l-Unbbn5r@}J?p+OC3JcVX%O z3{i6WLcyg)J}$|-JpW$u{l|VsB#3!d)NkRRJB(dL0vKU9UcK&~wcYs#{qO%Sdj9E# z{jaNEJ1y3C+2_8kHRbP!lfU>lXRg)3=Tp)bdp*#9(YEK#!KLj}|Liw@YhgEMRl3Qn zmuK$(W4iwA;-g*SckQEI>sWC;D~afGvi-Sk*}3Pyc6F8+mB*tX)o2S&TKWUQwk2&7{huja(f%53WiKby-g@=rq=o3w%uW5%c12tNSo?ABq2J{z zqohy9yOi%r*{dD&hONI)fl0e}!?o`M$}#+5>zc$T{S~y!RL$Sj#cf>6@Z|E&>6^17 zGg7iHuRHGYv-7dZ`Lpm%@z)~fQh{|xE< zq7`eFY`(p$GwIIH>-TH=za`83t5~1&BmIN);dtJy-La9AV&g*_CT$O|IO5VH*2~US z;BPZW_;u`$8riJL!CNPOnz>ylb%vLyMsc;L$<=AALv!O!fBt0qw)#?6ir*%URLdYE zj^)>{%|Gu5N;&RP8ZzKC#ANRE=i-m;tM66xKf2zXzy9i^$G_dY3#IE%oAf_%{gsgZ zk2QYjCaYsTXUbMcs(f3|_GA7B`NQ!-U%Tf<=#@*-1WADp$7O$5tT&f! zpQkh{;Kli^4`c50PDy$mEHrn?+S0XK_un}`(PUNc z1CBl{<|uxcrKzv~>2A%jS4Cgfxd%^Pn{oejbdgF-f9SfpPyaN(=M?xauR6Qs+)+;V zlEkc_qU^rwd98bwe476-D0}&pWe+~b)jrOCuXX$s`?IP09V1WPc(Yh8QziG`sVJ@= z^S@2_QJbie7LpsQ7tO4|p= zq5@rc_EcWyV^H|@rsrSjugc%&qkidZYnsZJesz9N;kHbx%I%w${F7Mnx3qq;`~T~| zX8+?d{_x<(;RpWTz8GxTUMI0T`uYvVRZ0> z;QG7!1v1L&)Gp?Knd>B2m|UCp?edYsiWjf6$xmE=a(~Z%hK=^!|M;>$YQ2)mTlnzx z$|!AFFVC5(pRT>zq>VHHInV!Q1nqpCz}li>+R}YyOrGcD1dC6IUe^P8G>{Fa6cO z^w*zrOvjIun_Dn+OuuMKgUj#}WFxo}#@te{nI`khT4pONLheEQ|*eeXT~GtBzPdLhtDPd{EUCR{88=6Sr+U2|1&(?T`I5r&t-MI@xMd9+y67TKL4_=IPUM( zJ*BH$PA&!Z1bu{dd`)pb4^9>p0Zz@^Sj^V z`o!d*GY3P8JZ-f<>xcfB{WxCWRrZQ3Ijw7IJHzhu%HDQb`DUfuRr!g3vR}_{*e`6# z-zmo)a&_I=b8DBK{FdFx!Idg;%Hu%cB&%;HOcFm{`6&Fv>(JRB!J<PYOMO(*v zzuotGxvzi3)zaXaniZQAWc|PI|8+G?fy6hfs=cthrBsIX`f2nv8Yul z+v5bUF1{kXV#Ag5Q`Ik~1~&g^V2Z2FezLy9PU^Z1`wD4$ftTU4RFAz~`EAFy#dAJx za-5PkSG4on`fJs%8+j_&<+dLBvFX<7n2obe2X1NlcP=3G!Ok9!9@~TK)wV_YE!%Qm z+urrG#dGP_Ert`nZG69F-{1LX2oAz0tRy)U9rQbZ6FH$t2t5 z%F!#e?Weu`GxMALAK~JMn}66pFueY5QO0^3|BCOgWO%wu|K3qZ-pCbEzc)T2;n%hN zwmr7V5AFG1?$VpdbnE4<(k*4vE-X0UanWhTpN6$I)w6zknOv1BT((R3=W(NBrwxyV z9zFeb+rL=xlNsO{9n**Rx4!GRHUH4j-FH++BMzUNUUF9R^rWoVezgw^`;X4&s4;xRt@Pe@ z?yOs}Y{woyt!bH4B{+ZKT3xmO4DUY2n7^6+D7shc`w=b7D6m{N zOET<{>8Gb@c;Zo-N&#w!Eh}uCsHePH2$Fsz1THhdy4LsS=yPtohJxrs>DyZv`JY zKUyz;K419##!J)ROiZ2-zoz%+gF4Z#`A6Q19(~}?@@m(SmdXi7H?i6u*REM%ZyYah zRO^-SGxz(-lg>T=(P^pv(Q-Yv@#=T0yw@#%HHWuhZ`6#RYn9)v58wZA`I+P0UZFi= z4iTSEtWdqUxcIx*{H)ivE=Dio__iYINcz$WU-@;_;njDZ*l(C@8?~(4y_f&)$*(ro zy}$8)%Y2<=s~M5Ey4EkNR=2F3yUFU&UgK|-9~D0=Kf;}nT01Rj(ciw9FT8V(-EU5* zKd^ePnD>^pW0xb}YTYh{fwZrq$td(-@dU`F!Ji0zQ-zH`M`f}&@ zQ^liEeOk}{NmOjIm#a|rz9!f>E#sTt;vcE;Q;$Ehk9worw(pivaMz@p^G|<$ah^Xc zBum>%cloQfqoUqA-T9L0YlS?fy`EILM%F+0_1VBizSS$z%T15Hy8fS`de-(;S+u3WZT_Q^`FVTnAJnP^To*pI zIVRfaKZ9YClcTi$LX{2YziYpcXZewK|KL86OIy4{wOM<2IqmLHnP92%UFF#xsr=WH zJkydxlOw4+3NGnf1(%uiT#jLey#o7);SW-T94gSm{1xf zJ44QW8*j<1b<=a#W^NBNpRnfJcEK${Zg<*(46>iZx*a|$zp1>t_1?Vy47cWqT~WOi zdR%DL-y2VIY9=+*g}u1({Py!zpHsKq%~*YD{?RADf7vZh$&KT(&&+*R&9`~c-HM<; zu9`;CmVdAOc-X%1i`~^~zpGX?S1;ZpEv0#5EV(8e<|9FntNsa*2tLGPpswNI==SF4M=_;uKsuFzpJKO75~1{ zlWF(XTX}uffor9_YgE{q4?f=;I63J1-)!r^J)hq`@%h}-zgF#CZ|1tlm|xM~41Y}6 zSkWE!q4mms)i-JX&Itc!&=qD1l@HabxB7MM(ND$rDgA5fyesk_vEFa230?A|>+I~e zQn8m}-UJoB;8XG8+v#+GKPLQT?)q-st!K3^2X3C?onFr6&%N@5#$n~3*DpSux_7C$ z?|b-|5~{rA@V&CAb{TF?G$U2@=6t3Ox$eutf_%bI@ppV*#{ zHcgS-(Glr0J)ZuZQXe<<&HP!SUvlMM9}Rz|(b;#G|NV017P;mtzr)iX$BTg{*Ldxg z8YSJk>g3Ece_o~kU5DC;ueNQza=IVqxBU~WNYyjtbe+57lw-cYUERZvtplqzSIs}S zFK@%;J)XaV{y1c>{#d!Z!t7#)G^b0a;ipy46`v;eY**lUER%lnSaR+3cNxF0%AMXm z+e$O&+4rR%7MFi3`B1m?@q4*f^+Kg59Jf!3lse<(+&*KD(7q-EGv=eUUfTAK7uM96 zF24D4R_?B-h+D^$+C*NgvY&r_Z${V;9j!w_Pxjuvy6^48u;p8({$dpgjD6+~np#|%0{q0p- z-*?){WNl|x?w0tV7wVm|XyeZm$D0x9GR(mh+26M9y4Vtx-?zuIocF<5F&3r%E4?4 zL*^bHZRW-|ymi%ex9+o++Bf}Y5PZWw)AV`!`<#Htte_(s-BNk(<)}1ojo~r3IPr2$ zxS85ME0LvA8^UUX|MG8oD5EAUI{VVMNk8&c=7(+j&tO0Ca7EhpbGtG*PxO?0H@$vz zW%Z*y!T#6Rnau8MGgqE6(c_NY{A;_q;7F- z>+AMwLE!1ecfR7{ikIz{{<|7FJ?Q(opw~yfP5XJjXyzAowT=3FN~NASN*4cpX(2yV zU0do{&(cjMrLX@pY>MA@?O0vm+kd{bwZA25T&5rS&%nQ~#^96Yjt_qt6EjmdSm(?% zd^)3nX~M^^|G0iAeU6$Rv@`j$x8^^Qm(&((|H z-?WK-z|Zb3d%wfRH@Uvxz>GICC0`Pqq1-R1=!f4SN`#>J}23y?0GUcE^7ZL`&sMVq}9&PsS*8c^<(iP-JjR~ zsb+;=WJ`FNa=F?1SKF~LRplOayRTo)buNndQSQC?z8HEVK{1)W*6TU})vR$mFv z6KD12+Iu$o?%w-nPA!cLxu3A8C#@%K_nD?HLpKfP|Cj#;sZHSGWnRj_zGCST+sx_< zjIK;w3>;_EU(b`jY~#J$J8^YHbXJ&Ak7s^4*J)|~(mZXa=1Wu8ncRuJY#07x;(rE~ zmp@`3^PA;z>f4Byy@^>j0)$!dugxukqN9S z&B{0Y=iS%l6!^!Q{pHKw`-f)juiByYz~F0X;r4}JZ^-GK{b1IkZK-$Z`p5ep?Zs-G ze{0qxeOSBMxBkQTIIaEFZ?=8B`}pOP6Hoqy9*Y0reKbl_>Ak}>ol{?hUVb-x{JAIm zU4EDS6H)aG{~5G?us^>3r#9|C!`^t?&V!d1f7n)cd{UvDu~F}9H|@C2{|vM3B!8!V zoPYAuyFK@RKHvDgE;c*q{K0=(S5I~OGDqyzz2Le$=H&cS#^J*M+!Oy*U%x5OTz@^{ zuWRL%l`D4}zcKu=^Wn;sj@t8$E9$=m{W$ulJ9XCKhu`)H{(FCG?c*)yub-R9@yE3~ zyy-u~gBkxB1hy{Tf5hro_ro1tO$-y?KV#p2YLSV=cis4wg+m`})O) zpShgwv%=FK-CQr7cICNN$eiT7mDxYG?Pq@4-!A{bufO#lzrp$Sy6=1S9_KzZRTsRa zdCX#akCx!|_wQ`3UyhP*-*TVl<;BcjzOCD4Ckq@YyEb7>;EHd7N8^@ Date: Tue, 7 Jul 2020 10:12:23 -0400 Subject: [PATCH 113/265] Fix formatting of CODEOWNERS --- CODEOWNERS | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index b5b2b0e..321cebf 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,6 +1,3 @@ -# Set Puppet's DIO team as the default code owner -* @puppetlabs/dio +# Set the default code owners +* @puppetlabs/dio @briancain @highb -# External code owners -* @briancain -* @highb From a6f53c0310f264ed1ec38ddc5d66900bb0d58747 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Thu, 2 Jul 2020 11:42:31 -0400 Subject: [PATCH 114/265] Add Dependabot and Coveralls This adds Dependabot to keep things updated and Coveralls so we can see how code coverage changes over time. Coveralls / SimpleCov are configured so that both the SimpleCov html report and the Coveralls report are generated. This facilitates easily seeing coverage locally in addtion to via CI. --- .coveralls.yml | 1 + .dependabot/config.yml | 7 +++++++ .gitignore | 1 + Gemfile | 1 + README.md | 5 ++++- spec/spec_helper.rb | 11 +++++++++++ 6 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .coveralls.yml create mode 100644 .dependabot/config.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..cf27a37 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +service_name: travis-pro diff --git a/.dependabot/config.yml b/.dependabot/config.yml new file mode 100644 index 0000000..ec01275 --- /dev/null +++ b/.dependabot/config.yml @@ -0,0 +1,7 @@ +--- +version: 1 + +update_configs: + - package_manager: 'ruby:bundler' + directory: '/' + update_schedule: 'daily' diff --git a/.gitignore b/.gitignore index f211644..5102fb1 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ build/ ## Environment normalisation: /.bundle/ +/vendor/ /lib/bundler/man/ # for a library or gem, you might want to ignore these files since the code is diff --git a/Gemfile b/Gemfile index 2d04715..e848044 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ gemspec gem 'rake', :require => false group :test do + gem 'coveralls', '~> 0.8.23' gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.5.0' diff --git a/README.md b/README.md index b9c170d..9a8e44f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # vmfloaty -[![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) [![Build Status](https://travis-ci.com/puppetlabs/vmfloaty.svg?branch=master)](https://travis-ci.com/puppetlabs/vmfloaty) +[![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) +[![Build Status](https://travis-ci.com/puppetlabs/vmfloaty.svg?branch=master)](https://travis-ci.com/puppetlabs/vmfloaty) +[![Coverage Status](https://coveralls.io/repos/github/puppetlabs/vmfloaty/badge.svg?branch=master)](https://coveralls.io/github/puppetlabs/vmfloaty?branch=master) +[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=puppetlabs/vmfloaty)](https://dependabot.com) A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 558a0ad..e23a554 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,16 @@ # frozen_string_literal: true +require 'simplecov' +require 'coveralls' + +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ + SimpleCov::Formatter::HTMLFormatter, + Coveralls::SimpleCov::Formatter +]) +SimpleCov.start do + add_filter %r{^/spec/} +end + require 'vmfloaty' require 'webmock/rspec' From 458ddf192dc081a54148cf0559e7c6d9302647e1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2020 14:21:10 +0000 Subject: [PATCH 115/265] Update rspec requirement from ~> 3.5.0 to ~> 3.9.0 Updates the requirements on [rspec](https://github.com/rspec/rspec) to permit the latest version. - [Release notes](https://github.com/rspec/rspec/releases) - [Commits](https://github.com/rspec/rspec/compare/v3.5.0...v3.9.0) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index e848044..b8bcc0f 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,7 @@ group :test do gem 'coveralls', '~> 0.8.23' gem 'pry' gem 'rb-readline' - gem 'rspec', '~> 3.5.0' + gem 'rspec', '~> 3.9.0' gem 'rubocop', '~> 0.52' gem 'webmock', '1.21.0' end From d0f7452998eec5952d69c5e6ec578ddc55443a4d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2020 14:35:22 +0000 Subject: [PATCH 116/265] Update commander requirement from ~> 4.4.3 to >= 4.4.3, < 4.6.0 Updates the requirements on [commander](https://github.com/commander-rb/commander) to permit the latest version. - [Release notes](https://github.com/commander-rb/commander/releases) - [Changelog](https://github.com/commander-rb/commander/blob/master/History.rdoc) - [Commits](https://github.com/commander-rb/commander/compare/v4.4.3...v4.5.2) Signed-off-by: dependabot-preview[bot] --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 8bf8907..572c255 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -25,6 +25,6 @@ Gem::Specification.new do |s| 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', '< 4.6.0' s.add_dependency 'faraday', '~> 0.17.0' end From 980793c9798f20948f2646357c1812a717ce7151 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2020 14:43:17 +0000 Subject: [PATCH 117/265] Update Dependabot config file --- .dependabot/config.yml | 7 ------- .github/dependabot.yml | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .dependabot/config.yml create mode 100644 .github/dependabot.yml diff --git a/.dependabot/config.yml b/.dependabot/config.yml deleted file mode 100644 index ec01275..0000000 --- a/.dependabot/config.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -version: 1 - -update_configs: - - package_manager: 'ruby:bundler' - directory: '/' - update_schedule: 'daily' diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..c8f8016 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: +- package-ecosystem: bundler + directory: "/" + schedule: + interval: daily + time: "13:00" + open-pull-requests-limit: 10 From 05a133fc7215e6347b2d6f7974be0753f848c898 Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Fri, 22 May 2020 15:36:21 -0700 Subject: [PATCH 118/265] Add support for ondemand provisioning to vmfloaty This commit adds support for provisioning instances on demand with vmpooler. Additionally, this change adds a capability to detect on demand pools available in ABS. Without this change vmfloaty does not support provisioning instances via the vmpooler ondemand endpoints. --- lib/vmfloaty.rb | 9 +++++++-- lib/vmfloaty/abs.rb | 10 +++++++++- lib/vmfloaty/pooler.rb | 36 +++++++++++++++++++++++++++++++++--- lib/vmfloaty/service.rb | 8 ++++++-- lib/vmfloaty/utils.rb | 4 +++- spec/vmfloaty/pooler_spec.rb | 20 ++++++++++++++++++++ 6 files changed, 78 insertions(+), 9 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 9eec698..9ba0bd0 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -37,6 +37,7 @@ class Vmfloaty c.option '--notoken', 'Makes a request without a token' c.option '--force', 'Forces vmfloaty to get requested vms' c.option '--json', 'Prints retrieved vms in JSON format' + c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID' c.action do |args, options| verbose = options.verbose || config['verbose'] service = Service.new(options, config) @@ -63,9 +64,13 @@ class Vmfloaty exit 1 end - response = service.retrieve(verbose, os_types, use_token) + response = service.retrieve(verbose, os_types, use_token, options.ondemand) + request_id = response['request_id'] if options.ondemand + response = service.wait_for_request(verbose, request_id) if options.ondemand + hosts = Utils.standardize_hostnames(response) - if options.json + + if options.json || options.ondemand puts JSON.pretty_generate(hosts) else puts Utils.format_host_output(hosts) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 259f411..d644472 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -150,6 +150,14 @@ class ABS os_list << '*** VMPOOLER Pools ***' os_list += JSON.parse(res_body['vmpooler_platforms']) + res = conn.get 'status/platforms/ondemand_vmpooler' + res_body = JSON.parse(res.body) + unless res_body['ondemand_vmpooler_platforms'] == '[]' + os_list << '' + os_list << '*** VMPOOLER ONDEMAND Pools ***' + os_list += JSON.parse(res_body['ondemand_vmpooler_platforms']) + end + res = conn.get 'status/platforms/nspooler' res_body = JSON.parse(res.body) os_list << '' @@ -168,7 +176,7 @@ class ABS end # Retrieve an OS from ABS. - def self.retrieve(verbose, os_types, token, url, user, options) + def self.retrieve(verbose, os_types, token, url, user, options, _ondemand = nil) # # Contents of post must be like: # diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index c85daf3..8cd11e1 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -28,7 +28,7 @@ class Pooler vms end - def self.retrieve(verbose, os_type, token, url, _user, _options) + def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil) # NOTE: # Developers can use `Utils.generate_os_hash` to # generate the os_type param. @@ -38,7 +38,8 @@ class Pooler os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? - response = conn.post "vm/#{os_string}" + response = conn.post "vm/#{os_string}" unless ondemand + response ||= conn.post "ondemandvm/#{os_string}" res_body = JSON.parse(response.body) @@ -46,11 +47,40 @@ class Pooler res_body elsif response.status == 401 raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}" + 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}" + raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/vm/#{os_string}. #{res_body}" unless ondemand + raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/ondemandvm/#{os_string}. #{res_body}" end end + def self.wait_for_request(verbose, request_id, url, timeout = 300) + start_time = Time.now + while check_ondemandvm(verbose, request_id, url) == false + return false if (Time.now - start_time).to_i > timeout + + STDOUT.puts "waiting for request #{request_id} to be fulfilled" + sleep 5 + end + STDOUT.puts "The request has been fulfilled" + check_ondemandvm(verbose, request_id, url) + end + + def self.check_ondemandvm(verbose, request_id, url) + conn = Http.get_conn(verbose, url) + + response = conn.get "ondemandvm/#{request_id}" + res_body = JSON.parse(response.body) + return res_body if response.status == 200 + + return false if response.status == 202 + + raise "HTTP #{response.status}: The request cannot be found, or an unknown error occurred" if response.status == 404 + + false + end + 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? diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 6a89b3d..87428f7 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -75,10 +75,14 @@ class Service @service_object.list_active verbose, url, token, user end - def retrieve(verbose, os_types, use_token = true) + def retrieve(verbose, os_types, use_token = true, ondemand = nil) puts 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil - @service_object.retrieve verbose, os_types, token_value, url, user, @config + @service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand + end + + def wait_for_request(verbose, requestid) + @service_object.wait_for_request verbose, requestid, url end def ssh(verbose, host_os, use_token = true) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 1e2e678..105c374 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -45,7 +45,9 @@ class Utils result = {} - response_body.each do |os, value| + STDOUT.puts "response body is #{response_body}" + filtered_response_body = response_body.reject { |key, _| key == 'request_id' || key == 'ready' } + filtered_response_body.each do |os, value| hostnames = Array(value['hostname']) hostnames.map! { |host| "#{host}.#{domain}" } if domain result[os] = hostnames diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 6d7def0..7d83c79 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -84,6 +84,26 @@ describe Pooler do expect(vm_req['debian-7-i386']['hostname']).to eq %w[sc0o4xqtodlul5w 4m4dkhqiufnjmxy] expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q' end + + context 'with ondemand provisioning' 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 => {}) + + stub_request(:get, "#{@vmpooler_url}/ondemandvm/1234") + .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {}) + + vm_hash = {} + vm_hash['debian-7-i386'] = 1 + Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {}, true) + vm_req = Pooler.check_ondemandvm(false, '1234', @vmpooler_url) + expect(vm_req).to be_an_instance_of Hash + expect(vm_req['ok']).to equal true + expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6' + end + end end describe '#modify' do From 7b0a7679daed55106a25a53e6c858927fab9490d Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Fri, 22 May 2020 15:36:49 -0700 Subject: [PATCH 119/265] Add Dockerfile to make it easier to test changes to vmfloaty by using Docker --- .dockerignore | 12 ++++++++++++ Dockerfile | 6 ++++++ 2 files changed, 18 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6174523 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +**/*.yml +**/*.yaml +**/*.md +**/*example +**/Dockerfile* +Gemfile.lock +Rakefile +coverage +spec +examples +scripts +vendor diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c564fa8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM ruby:2.7 + +COPY ./ ./ + +RUN apt-get update && apt-get install -y less +RUN gem install bundler && bundle install && gem build vmfloaty.gemspec && gem install vmfloaty*.gem From a2453162529ab97c463c7d6f5ca9cd0a23fd0c3b Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Tue, 4 Aug 2020 15:16:19 -0700 Subject: [PATCH 120/265] Bump version to 0.10.0 for release --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 145a681..d7cf0c0 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.9.2' + VERSION = '0.10.0' end From 309929f8d82717890810ead91537bccdcdf0dbb8 Mon Sep 17 00:00:00 2001 From: Belen Bustamante Date: Thu, 6 Aug 2020 11:50:43 -0700 Subject: [PATCH 121/265] Update travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3b2336c..770839e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ -sudo: false language: ruby +dist: xenial +os: + - linux rvm: - 2.6.5 script: bundle exec rake spec From 4755343df2d19a2c75048f20413b5dd5bf35f953 Mon Sep 17 00:00:00 2001 From: Austin Blatt Date: Mon, 10 Aug 2020 15:41:02 -0700 Subject: [PATCH 122/265] Print all non-success output to STDERR --- lib/vmfloaty.rb | 38 ++++++++++++++++++------------------- lib/vmfloaty/abs.rb | 18 +++++++++--------- lib/vmfloaty/service.rb | 15 +++------------ lib/vmfloaty/utils.rb | 24 +++++++++++------------ spec/vmfloaty/utils_spec.rb | 8 ++++---- 5 files changed, 47 insertions(+), 56 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 9ba0bd0..3f572e4 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -71,9 +71,9 @@ class Vmfloaty hosts = Utils.standardize_hostnames(response) if options.json || options.ondemand - puts JSON.pretty_generate(hosts) + STDOUT.puts JSON.pretty_generate(hosts) else - puts Utils.format_host_output(hosts) + STDOUT.puts Utils.format_host_output(hosts) end end end @@ -99,15 +99,15 @@ class Vmfloaty running_vms = service.list_active(verbose) host = URI.parse(service.url).host if running_vms.empty? - puts "You have no running VMs on #{host}" + STDOUT.puts "You have no running VMs on #{host}" else - puts "Your VMs on #{host}:" + STDOUT.puts "Your VMs on #{host}:" Utils.pretty_print_hosts(verbose, service, running_vms) end else # list available vms from pooler os_list = service.list(verbose, filter) - puts os_list + STDOUT.puts os_list end end end @@ -178,11 +178,11 @@ class Vmfloaty end if ok if modify_all - puts 'Successfully modified all VMs.' + STDOUT.puts 'Successfully modified all VMs.' else - puts "Successfully modified VM #{hostname}." + STDOUT.puts "Successfully modified VM #{hostname}." end - puts 'Use `floaty list --active` to see the results.' + STDOUT.puts 'Use `floaty list --active` to see the results.' end end end @@ -214,11 +214,11 @@ class Vmfloaty if delete_all running_vms = service.list_active(verbose) if running_vms.empty? - STDERR.puts 'You have no running VMs.' + STDOUT.puts 'You have no running VMs.' else - Utils.pretty_print_hosts(verbose, service, running_vms) + Utils.pretty_print_hosts(verbose, service, running_vms, true) # Confirm deletion - puts + STDERR.puts confirmed = true confirmed = agree('Delete all these VMs? [y/N]') unless force if confirmed @@ -256,10 +256,10 @@ class Vmfloaty end unless successes.empty? - puts unless failures.empty? - puts 'Scheduled the following VMs for deletion:' + STDERR.puts unless failures.empty? + STDOUT.puts 'Scheduled the following VMs for deletion:' successes.each do |hostname| - puts "- #{hostname}" + STDOUT.puts "- #{hostname}" end end @@ -288,7 +288,7 @@ class Vmfloaty exit 1 end - puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid." + STDOUT.puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid." pp snapshot_req end end @@ -379,15 +379,15 @@ class Vmfloaty case action when 'get' token = service.get_new_token(verbose) - puts token + STDOUT.puts token when 'delete' result = service.delete_token(verbose, options.token) - puts result + STDOUT.puts result when 'status' token_value = options.token token_value = args[1] if token_value.nil? status = service.token_status(verbose, token_value) - puts status + STDOUT.puts status when nil STDERR.puts 'No action provided' exit 1 @@ -450,7 +450,7 @@ class Vmfloaty completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__) if File.exist?(completion_file) - puts completion_file + STDOUT.puts completion_file exit 0 else STDERR.puts "Could not find completion file for '#{shell}': No such file #{completion_file}" diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index d644472..d05ee4e 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -68,7 +68,7 @@ class ABS ret_val.push(req_hash) rescue NoMethodError - puts "Warning: couldn't parse line returned from abs/status/queue: ".yellow + STDERR.puts "Warning: couldn't parse line returned from abs/status/queue: ".yellow end end @@ -85,7 +85,7 @@ class ABS conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - puts "Trying to delete hosts #{hosts}" if verbose + STDERR.puts "Trying to delete hosts #{hosts}" if verbose requests = get_active_requests(verbose, url, user) jobs_to_delete = [] @@ -113,7 +113,7 @@ class ABS } jobs_to_delete.push(req_hash) else - puts "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" + STDERR.puts "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" end end end @@ -127,7 +127,7 @@ class ABS 'hosts' => job['allocated_resources'], } - puts "Deleting #{req_obj}" if verbose + STDERR.puts "Deleting #{req_obj}" if verbose return_result = conn.post 'return', req_obj.to_json req_obj['hosts'].each do |host| @@ -220,11 +220,11 @@ class ABS end end - puts "Posting to ABS #{req_obj.to_json}" if verbose + STDERR.puts "Posting to ABS #{req_obj.to_json}" if verbose # os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') # raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? - puts "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." + STDERR.puts "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." res = conn.post 'request', req_obj.to_json retries = 360 @@ -237,7 +237,7 @@ class ABS sleep_seconds = 10 if i >= 10 sleep_seconds = i if i < 10 - puts "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + STDERR.puts "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" sleep(sleep_seconds) end @@ -276,7 +276,7 @@ class ABS end def self.snapshot(_verbose, _url, _hostname, _token) - puts "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" + STDERR.puts "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" end def self.status(verbose, url) @@ -297,7 +297,7 @@ class ABS def self.query(verbose, url, hostname) return @active_hostnames if @active_hostnames - puts "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" + STDERR.puts "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" conn = Http.get_conn(verbose, url) res = conn.get "host/#{hostname}" diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 87428f7..a5feac8 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -36,7 +36,7 @@ class Service def user unless @config['user'] - puts "Enter your #{@config['url']} service username:" + STDERR.puts "Enter your #{@config['url']} service username:" @config['user'] = STDIN.gets.chomp end @config['user'] @@ -44,7 +44,7 @@ class Service def token unless @config['token'] - puts 'No token found. Retrieving a token...' + STDERR.puts 'No token found. Retrieving a token...' @config['token'] = get_new_token(nil) end @config['token'] @@ -76,7 +76,7 @@ class Service end def retrieve(verbose, os_types, use_token = true, ondemand = nil) - puts 'Requesting a vm without a token...' unless use_token + STDERR.puts 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil @service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand end @@ -98,15 +98,6 @@ class Service Ssh.ssh(verbose, self, host_os, token_value) end - def pretty_print_running(verbose, hostnames = []) - if hostnames.empty? - puts 'You have no running VMs.' - else - puts 'Running VMs:' - @service_object.pretty_print_hosts(verbose, hostnames, url) - end - end - def query(verbose, hostname) @service_object.query verbose, url, hostname end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 105c374..8076ec7 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -45,7 +45,7 @@ class Utils result = {} - STDOUT.puts "response body is #{response_body}" + STDERR.puts "response body is #{response_body}" filtered_response_body = response_body.reject { |key, _| key == 'request_id' || key == 'ready' } filtered_response_body.each do |os, value| hostnames = Array(value['hostname']) @@ -79,7 +79,7 @@ class Utils os_types end - def self.pretty_print_hosts(verbose, service, hostnames = []) + def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false) hostnames = [hostnames] unless hostnames.is_a? Array hostnames.each do |hostname| begin @@ -91,7 +91,7 @@ class Utils # For ABS, 'hostname' variable is the jobID if host_data['state'] == 'allocated' || host_data['state'] == 'filled' host_data['allocated_resources'].each do |vm_name, _i| - puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" + STDOUT.puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" end end when 'Pooler' @@ -99,13 +99,13 @@ class Utils tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] - puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" + STDOUT.puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? line += ')' - puts line + STDOUT.puts line else raise "Invalid service type #{service.type}" end @@ -133,12 +133,12 @@ class Utils pending = pool['pending'] missing = max - ready - pending char = 'o' - puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" + STDOUT.puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" rescue StandardError => e - puts "#{name.ljust(width)} #{e.red}" + STDERR.puts "#{name.ljust(width)} #{e.red}" end end - puts message.colorize(status_response['status']['ok'] ? :default : :red) + STDOUT.puts message.colorize(status_response['status']['ok'] ? :default : :red) when 'NonstandardPooler' pools = status_response pools.delete 'ok' @@ -152,14 +152,14 @@ class Utils 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}" + STDOUT.puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" rescue StandardError => e - puts "#{name.ljust(width)} #{e.red}" + STDERR.puts "#{name.ljust(width)} #{e.red}" end end when 'ABS' - puts 'ABS Not OK'.red unless status_response - puts 'ABS is OK'.green if status_response + STDERR.puts 'ABS Not OK'.red unless status_response + STDOUT.puts 'ABS is OK'.green if status_response else raise "Invalid service type #{service.type}" end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 7fd795b..4d31d24 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -169,7 +169,7 @@ describe Utils do } } output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)' - expect(Utils).to receive(:puts).with(output) + expect(STDOUT).to receive(:puts).with(output) service = Service.new(MockOptions.new, 'url' => url) allow(service).to receive(:query) @@ -195,7 +195,7 @@ describe Utils do } } 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(STDOUT).to receive(:puts).with(output) service = Service.new(MockOptions.new, 'url' => url) allow(service).to receive(:query) @@ -216,7 +216,7 @@ describe Utils do } } output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)' - expect(Utils).to receive(:puts).with(output) + expect(STDOUT).to receive(:puts).with(output) service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') allow(service).to receive(:query) @@ -237,7 +237,7 @@ describe Utils do } } output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)' - expect(Utils).to receive(:puts).with(output) + expect(STDOUT).to receive(:puts).with(output) service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') allow(service).to receive(:query) From 8ec90007ca46b04704b7921dc5dc29f3c84704ed Mon Sep 17 00:00:00 2001 From: barriserloth Date: Tue, 11 Aug 2020 10:31:14 -0700 Subject: [PATCH 123/265] Use Logger for non-result output This adds the Logger class for log output, all of which goes to STDERR, and uses puts to send only the command result to STDOUT. --- lib/vmfloaty.rb | 78 ++++++++++++++++++++++------------------- lib/vmfloaty/abs.rb | 18 +++++----- lib/vmfloaty/conf.rb | 2 +- lib/vmfloaty/logger.rb | 11 ++++++ lib/vmfloaty/pooler.rb | 4 +-- lib/vmfloaty/service.rb | 10 +++--- lib/vmfloaty/utils.rb | 25 +++++++------ 7 files changed, 81 insertions(+), 67 deletions(-) create mode 100644 lib/vmfloaty/logger.rb diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 3f572e4..3693b4e 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -13,10 +13,15 @@ require 'vmfloaty/conf' require 'vmfloaty/utils' require 'vmfloaty/service' require 'vmfloaty/ssh' +require 'vmfloaty/logger' class Vmfloaty include Commander::Methods + def self.logger + @logger ||= FloatyLogger.new + end + 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" @@ -45,7 +50,7 @@ class Vmfloaty force = options.force if args.empty? - STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' + logger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' exit 1 end @@ -54,13 +59,13 @@ class Vmfloaty max_pool_request = 5 large_pool_requests = os_types.select { |_, v| v > max_pool_request } if !large_pool_requests.empty? && !force - STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag." - STDERR.puts 'Try again with `floaty get --force`' + logger.error "Requesting vms over #{max_pool_request} requires a --force flag." + logger.error 'Try again with `floaty get --force`' exit 1 end if os_types.empty? - STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' + logger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' exit 1 end @@ -71,9 +76,9 @@ class Vmfloaty hosts = Utils.standardize_hostnames(response) if options.json || options.ondemand - STDOUT.puts JSON.pretty_generate(hosts) + puts JSON.pretty_generate(hosts) else - STDOUT.puts Utils.format_host_output(hosts) + puts Utils.format_host_output(hosts) end end end @@ -99,15 +104,15 @@ class Vmfloaty running_vms = service.list_active(verbose) host = URI.parse(service.url).host if running_vms.empty? - STDOUT.puts "You have no running VMs on #{host}" + puts "You have no running VMs on #{host}" else - STDOUT.puts "Your VMs on #{host}:" + puts "Your VMs on #{host}:" Utils.pretty_print_hosts(verbose, service, running_vms) end else # list available vms from pooler os_list = service.list(verbose, filter) - STDOUT.puts os_list + puts os_list end end end @@ -151,7 +156,7 @@ class Vmfloaty modify_all = options.all if hostname.nil? && !modify_all - STDERR.puts 'ERROR: Provide a hostname or specify --all.' + logger.error 'ERROR: Provide a hostname or specify --all.' exit 1 end running_vms = modify_all ? service.list_active(verbose) : hostname.split(',') @@ -172,17 +177,17 @@ class Vmfloaty begin modified_hash[vm] = service.modify(verbose, vm, modify_hash) rescue ModifyError => e - STDERR.puts e + logger.error e ok = false end end if ok if modify_all - STDOUT.puts 'Successfully modified all VMs.' + puts 'Successfully modified all VMs.' else - STDOUT.puts "Successfully modified VM #{hostname}." + puts "Successfully modified VM #{hostname}." end - STDOUT.puts 'Use `floaty list --active` to see the results.' + puts 'Use `floaty list --active` to see the results.' end end end @@ -214,11 +219,10 @@ class Vmfloaty if delete_all running_vms = service.list_active(verbose) if running_vms.empty? - STDOUT.puts 'You have no running VMs.' + puts 'You have no running VMs.' else Utils.pretty_print_hosts(verbose, service, running_vms, true) # Confirm deletion - STDERR.puts confirmed = true confirmed = agree('Delete all these VMs? [y/N]') unless force if confirmed @@ -243,23 +247,23 @@ class Vmfloaty end end else - STDERR.puts 'You did not provide any hosts to delete' + logger.info 'You did not provide any hosts to delete' exit 1 end unless failures.empty? - STDERR.puts 'Unable to delete the following VMs:' + logger.info 'Unable to delete the following VMs:' failures.each do |hostname| - STDERR.puts "- #{hostname}" + logger.info "- #{hostname}" end - STDERR.puts 'Check `floaty list --active`; Do you need to specify a different service?' + logger.info 'Check `floaty list --active`; Do you need to specify a different service?' end unless successes.empty? - STDERR.puts unless failures.empty? - STDOUT.puts 'Scheduled the following VMs for deletion:' + logger.info unless failures.empty? + puts 'Scheduled the following VMs for deletion:' successes.each do |hostname| - STDOUT.puts "- #{hostname}" + puts "- #{hostname}" end end @@ -284,11 +288,11 @@ class Vmfloaty begin snapshot_req = service.snapshot(verbose, hostname) rescue TokenError, ModifyError => e - STDERR.puts e + logger.error e exit 1 end - STDOUT.puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid." + puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid." pp snapshot_req end end @@ -309,12 +313,12 @@ class Vmfloaty hostname = args[0] snapshot_sha = args[1] || options.snapshot - STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot + logger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot begin revert_req = service.revert(verbose, hostname, snapshot_sha) rescue TokenError, ModifyError => e - STDERR.puts e + logger.error e exit 1 end @@ -379,24 +383,24 @@ class Vmfloaty case action when 'get' token = service.get_new_token(verbose) - STDOUT.puts token + puts token when 'delete' result = service.delete_token(verbose, options.token) - STDOUT.puts result + puts result when 'status' token_value = options.token token_value = args[1] if token_value.nil? status = service.token_status(verbose, token_value) - STDOUT.puts status + puts status when nil - STDERR.puts 'No action provided' + logger.error 'No action provided' exit 1 else - STDERR.puts "Unknown action: #{action}" + logger.error "Unknown action: #{action}" exit 1 end rescue TokenError => e - STDERR.puts e + logger.error e exit 1 end exit 0 @@ -420,13 +424,13 @@ class Vmfloaty use_token = !options.notoken if args.empty? - STDERR.puts 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.' + logger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.' exit 1 end host_os = args.first - STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1 + logger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1 service.ssh(verbose, host_os, use_token) exit 0 @@ -450,10 +454,10 @@ class Vmfloaty completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__) if File.exist?(completion_file) - STDOUT.puts completion_file + puts completion_file exit 0 else - STDERR.puts "Could not find completion file for '#{shell}': No such file #{completion_file}" + logger.error "Could not find completion file for '#{shell}': No such file #{completion_file}" exit 1 end end diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index d05ee4e..a06dee1 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -68,7 +68,7 @@ class ABS ret_val.push(req_hash) rescue NoMethodError - STDERR.puts "Warning: couldn't parse line returned from abs/status/queue: ".yellow + Vmfloaty.logger.warn "Warning: couldn't parse line returned from abs/status/queue: " end end @@ -85,7 +85,7 @@ class ABS conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - STDERR.puts "Trying to delete hosts #{hosts}" if verbose + Vmfloaty.logger.info "Trying to delete hosts #{hosts}" if verbose requests = get_active_requests(verbose, url, user) jobs_to_delete = [] @@ -113,7 +113,7 @@ class ABS } jobs_to_delete.push(req_hash) else - STDERR.puts "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" + Vmfloaty.logger.info "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" end end end @@ -127,7 +127,7 @@ class ABS 'hosts' => job['allocated_resources'], } - STDERR.puts "Deleting #{req_obj}" if verbose + Vmfloaty.logger.info "Deleting #{req_obj}" if verbose return_result = conn.post 'return', req_obj.to_json req_obj['hosts'].each do |host| @@ -220,11 +220,11 @@ class ABS end end - STDERR.puts "Posting to ABS #{req_obj.to_json}" if verbose + Vmfloaty.logger.info "Posting to ABS #{req_obj.to_json}" if verbose # os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') # raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? - STDERR.puts "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." + Vmfloaty.logger.info "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." res = conn.post 'request', req_obj.to_json retries = 360 @@ -237,7 +237,7 @@ class ABS sleep_seconds = 10 if i >= 10 sleep_seconds = i if i < 10 - STDERR.puts "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + Vmfloaty.logger.info "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" sleep(sleep_seconds) end @@ -276,7 +276,7 @@ class ABS end def self.snapshot(_verbose, _url, _hostname, _token) - STDERR.puts "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" + Vmfloaty.logger.info "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" end def self.status(verbose, url) @@ -297,7 +297,7 @@ class ABS def self.query(verbose, url, hostname) return @active_hostnames if @active_hostnames - STDERR.puts "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" + Vmfloaty.logger.info "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" conn = Http.get_conn(verbose, url) res = conn.get "host/#{hostname}" diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb index 5e572fa..3742fb3 100644 --- a/lib/vmfloaty/conf.rb +++ b/lib/vmfloaty/conf.rb @@ -8,7 +8,7 @@ class Conf begin conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml") rescue StandardError - STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" + Vmfloaty.logger.warn "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" end conf end diff --git a/lib/vmfloaty/logger.rb b/lib/vmfloaty/logger.rb new file mode 100644 index 0000000..623e8a4 --- /dev/null +++ b/lib/vmfloaty/logger.rb @@ -0,0 +1,11 @@ +require 'logger' + +class FloatyLogger < ::Logger + def initialize + super(STDERR) + self.level = ::Logger::INFO + self.formatter = proc do |severity, datetime, progname, msg| + "#{msg}\n" + end + end +end \ No newline at end of file diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 8cd11e1..ffc0a3f 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -60,10 +60,10 @@ class Pooler while check_ondemandvm(verbose, request_id, url) == false return false if (Time.now - start_time).to_i > timeout - STDOUT.puts "waiting for request #{request_id} to be fulfilled" + Vmfloaty.logger.info "waiting for request #{request_id} to be fulfilled" sleep 5 end - STDOUT.puts "The request has been fulfilled" + Vmfloaty.logger.info "The request has been fulfilled" check_ondemandvm(verbose, request_id, url) end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index a5feac8..39bd20e 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -36,7 +36,7 @@ class Service def user unless @config['user'] - STDERR.puts "Enter your #{@config['url']} service username:" + Vmfloaty.logger.info "Enter your #{@config['url']} service username:" @config['user'] = STDIN.gets.chomp end @config['user'] @@ -44,7 +44,7 @@ class Service def token unless @config['token'] - STDERR.puts 'No token found. Retrieving a token...' + Vmfloaty.logger.info 'No token found. Retrieving a token...' @config['token'] = get_new_token(nil) end @config['token'] @@ -76,7 +76,7 @@ class Service end def retrieve(verbose, os_types, use_token = true, ondemand = nil) - STDERR.puts 'Requesting a vm without a token...' unless use_token + Vmfloaty.logger.info 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil @service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand end @@ -91,8 +91,8 @@ class Service begin token_value = token || get_new_token(verbose) rescue TokenError => e - STDERR.puts e - STDERR.puts 'Could not get token... requesting vm without a token anyway...' + Vmfloaty.logger.error e + Vmfloaty.logger.info 'Could not get token... requesting vm without a token anyway...' end end Ssh.ssh(verbose, self, host_os, token_value) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 8076ec7..6edca63 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -45,7 +45,6 @@ class Utils result = {} - STDERR.puts "response body is #{response_body}" filtered_response_body = response_body.reject { |key, _| key == 'request_id' || key == 'ready' } filtered_response_body.each do |os, value| hostnames = Array(value['hostname']) @@ -91,7 +90,7 @@ class Utils # For ABS, 'hostname' variable is the jobID if host_data['state'] == 'allocated' || host_data['state'] == 'filled' host_data['allocated_resources'].each do |vm_name, _i| - STDOUT.puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" + puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" end end when 'Pooler' @@ -99,19 +98,19 @@ class Utils tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] - STDOUT.puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" + puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? line += ')' - STDOUT.puts line + puts line else raise "Invalid service type #{service.type}" end rescue StandardError => e - STDERR.puts("Something went wrong while trying to gather information on #{hostname}:") - STDERR.puts(e) + Vmfloaty.logger.error("Something went wrong while trying to gather information on #{hostname}:") + Vmfloaty.logger.error(e) end end end @@ -133,12 +132,12 @@ class Utils pending = pool['pending'] missing = max - ready - pending char = 'o' - STDOUT.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 StandardError => e - STDERR.puts "#{name.ljust(width)} #{e.red}" + Vmfloaty.logger.error "#{name.ljust(width)} #{e.red}" end end - STDOUT.puts message.colorize(status_response['status']['ok'] ? :default : :red) + puts message.colorize(status_response['status']['ok'] ? :default : :red) when 'NonstandardPooler' pools = status_response pools.delete 'ok' @@ -152,14 +151,14 @@ class Utils pending = pool['pending'] || 0 # not available for nspooler missing = max - ready - pending char = 'o' - STDOUT.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 StandardError => e - STDERR.puts "#{name.ljust(width)} #{e.red}" + Vmfloaty.logger.error "#{name.ljust(width)} #{e.red}" end end when 'ABS' - STDERR.puts 'ABS Not OK'.red unless status_response - STDOUT.puts 'ABS is OK'.green if status_response + Vmfloaty.logger.error 'ABS Not OK' unless status_response + puts 'ABS is OK'.green if status_response else raise "Invalid service type #{service.type}" end From 35faeab6beec058d1a9a523c30d6590b4ece256a Mon Sep 17 00:00:00 2001 From: Austin Blatt Date: Wed, 12 Aug 2020 09:49:15 -0700 Subject: [PATCH 124/265] Move logger instance to class var in FloatyLogger This moves the instance of the logger class to a class variable in the `FloatyLogger` class and provides three class methods to log with in the rest of the project `FloatyLogger.info`, `FloatyLogger.warn`, and `FloatyLogger.error`. --- lib/vmfloaty.rb | 44 +++++++++++++++++++---------------------- lib/vmfloaty/abs.rb | 18 ++++++++--------- lib/vmfloaty/conf.rb | 2 +- lib/vmfloaty/logger.rb | 18 ++++++++++++++++- lib/vmfloaty/pooler.rb | 4 ++-- lib/vmfloaty/service.rb | 10 +++++----- lib/vmfloaty/utils.rb | 10 +++++----- 7 files changed, 59 insertions(+), 47 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 3693b4e..d1c2df2 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -18,10 +18,6 @@ require 'vmfloaty/logger' class Vmfloaty include Commander::Methods - def self.logger - @logger ||= FloatyLogger.new - end - 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" @@ -50,7 +46,7 @@ class Vmfloaty force = options.force if args.empty? - logger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' + FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' exit 1 end @@ -59,13 +55,13 @@ class Vmfloaty max_pool_request = 5 large_pool_requests = os_types.select { |_, v| v > max_pool_request } if !large_pool_requests.empty? && !force - logger.error "Requesting vms over #{max_pool_request} requires a --force flag." - logger.error 'Try again with `floaty get --force`' + FloatyLogger.error "Requesting vms over #{max_pool_request} requires a --force flag." + FloatyLogger.error 'Try again with `floaty get --force`' exit 1 end if os_types.empty? - logger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' + FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' exit 1 end @@ -156,7 +152,7 @@ class Vmfloaty modify_all = options.all if hostname.nil? && !modify_all - logger.error 'ERROR: Provide a hostname or specify --all.' + FloatyLogger.error 'ERROR: Provide a hostname or specify --all.' exit 1 end running_vms = modify_all ? service.list_active(verbose) : hostname.split(',') @@ -177,7 +173,7 @@ class Vmfloaty begin modified_hash[vm] = service.modify(verbose, vm, modify_hash) rescue ModifyError => e - logger.error e + FloatyLogger.error e ok = false end end @@ -247,20 +243,20 @@ class Vmfloaty end end else - logger.info 'You did not provide any hosts to delete' + FloatyLogger.info 'You did not provide any hosts to delete' exit 1 end unless failures.empty? - logger.info 'Unable to delete the following VMs:' + FloatyLogger.info 'Unable to delete the following VMs:' failures.each do |hostname| - logger.info "- #{hostname}" + FloatyLogger.info "- #{hostname}" end - logger.info 'Check `floaty list --active`; Do you need to specify a different service?' + FloatyLogger.info 'Check `floaty list --active`; Do you need to specify a different service?' end unless successes.empty? - logger.info unless failures.empty? + FloatyLogger.info unless failures.empty? puts 'Scheduled the following VMs for deletion:' successes.each do |hostname| puts "- #{hostname}" @@ -288,7 +284,7 @@ class Vmfloaty begin snapshot_req = service.snapshot(verbose, hostname) rescue TokenError, ModifyError => e - logger.error e + FloatyLogger.error e exit 1 end @@ -313,12 +309,12 @@ class Vmfloaty hostname = args[0] snapshot_sha = args[1] || options.snapshot - logger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot + FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot begin revert_req = service.revert(verbose, hostname, snapshot_sha) rescue TokenError, ModifyError => e - logger.error e + FloatyLogger.error e exit 1 end @@ -393,14 +389,14 @@ class Vmfloaty status = service.token_status(verbose, token_value) puts status when nil - logger.error 'No action provided' + FloatyLogger.error 'No action provided' exit 1 else - logger.error "Unknown action: #{action}" + FloatyLogger.error "Unknown action: #{action}" exit 1 end rescue TokenError => e - logger.error e + FloatyLogger.error e exit 1 end exit 0 @@ -424,13 +420,13 @@ class Vmfloaty use_token = !options.notoken if args.empty? - logger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.' + FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.' exit 1 end host_os = args.first - logger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1 + FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1 service.ssh(verbose, host_os, use_token) exit 0 @@ -457,7 +453,7 @@ class Vmfloaty puts completion_file exit 0 else - logger.error "Could not find completion file for '#{shell}': No such file #{completion_file}" + FloatyLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}" exit 1 end end diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index a06dee1..9a6358a 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -68,7 +68,7 @@ class ABS ret_val.push(req_hash) rescue NoMethodError - Vmfloaty.logger.warn "Warning: couldn't parse line returned from abs/status/queue: " + FloatyLogger.warn "Warning: couldn't parse line returned from abs/status/queue: " end end @@ -85,7 +85,7 @@ class ABS conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - Vmfloaty.logger.info "Trying to delete hosts #{hosts}" if verbose + FloatyLogger.info "Trying to delete hosts #{hosts}" if verbose requests = get_active_requests(verbose, url, user) jobs_to_delete = [] @@ -113,7 +113,7 @@ class ABS } jobs_to_delete.push(req_hash) else - Vmfloaty.logger.info "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" + FloatyLogger.info "When using ABS you must delete all vms that you requested at the same time: Can't delete #{req_hash['request']['job']['id']}: #{hosts} does not include all of #{req_hash['allocated_resources']}" end end end @@ -127,7 +127,7 @@ class ABS 'hosts' => job['allocated_resources'], } - Vmfloaty.logger.info "Deleting #{req_obj}" if verbose + FloatyLogger.info "Deleting #{req_obj}" if verbose return_result = conn.post 'return', req_obj.to_json req_obj['hosts'].each do |host| @@ -220,11 +220,11 @@ class ABS end end - Vmfloaty.logger.info "Posting to ABS #{req_obj.to_json}" if verbose + FloatyLogger.info "Posting to ABS #{req_obj.to_json}" if verbose # os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') # raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? - Vmfloaty.logger.info "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." + FloatyLogger.info "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." res = conn.post 'request', req_obj.to_json retries = 360 @@ -237,7 +237,7 @@ class ABS sleep_seconds = 10 if i >= 10 sleep_seconds = i if i < 10 - Vmfloaty.logger.info "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + FloatyLogger.info "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" sleep(sleep_seconds) end @@ -276,7 +276,7 @@ class ABS end def self.snapshot(_verbose, _url, _hostname, _token) - Vmfloaty.logger.info "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" + FloatyLogger.info "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" end def self.status(verbose, url) @@ -297,7 +297,7 @@ class ABS def self.query(verbose, url, hostname) return @active_hostnames if @active_hostnames - Vmfloaty.logger.info "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" + FloatyLogger.info "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" conn = Http.get_conn(verbose, url) res = conn.get "host/#{hostname}" diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb index 3742fb3..0b61f30 100644 --- a/lib/vmfloaty/conf.rb +++ b/lib/vmfloaty/conf.rb @@ -8,7 +8,7 @@ class Conf begin conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml") rescue StandardError - Vmfloaty.logger.warn "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" + FloatyLogger.warn "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" end conf end diff --git a/lib/vmfloaty/logger.rb b/lib/vmfloaty/logger.rb index 623e8a4..d669d78 100644 --- a/lib/vmfloaty/logger.rb +++ b/lib/vmfloaty/logger.rb @@ -1,6 +1,22 @@ require 'logger' class FloatyLogger < ::Logger + def self.logger + @@logger ||= FloatyLogger.new + end + + def self.info(msg) + FloatyLogger.logger.info msg + end + + def self.warn(msg) + FloatyLogger.logger.warn msg + end + + def self.error(msg) + FloatyLogger.logger.error msg + end + def initialize super(STDERR) self.level = ::Logger::INFO @@ -8,4 +24,4 @@ class FloatyLogger < ::Logger "#{msg}\n" end end -end \ No newline at end of file +end diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index ffc0a3f..fb811cf 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -60,10 +60,10 @@ class Pooler while check_ondemandvm(verbose, request_id, url) == false return false if (Time.now - start_time).to_i > timeout - Vmfloaty.logger.info "waiting for request #{request_id} to be fulfilled" + FloatyLogger.info "waiting for request #{request_id} to be fulfilled" sleep 5 end - Vmfloaty.logger.info "The request has been fulfilled" + FloatyLogger.info "The request has been fulfilled" check_ondemandvm(verbose, request_id, url) end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 39bd20e..11ddc29 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -36,7 +36,7 @@ class Service def user unless @config['user'] - Vmfloaty.logger.info "Enter your #{@config['url']} service username:" + FloatyLogger.info "Enter your #{@config['url']} service username:" @config['user'] = STDIN.gets.chomp end @config['user'] @@ -44,7 +44,7 @@ class Service def token unless @config['token'] - Vmfloaty.logger.info 'No token found. Retrieving a token...' + FloatyLogger.info 'No token found. Retrieving a token...' @config['token'] = get_new_token(nil) end @config['token'] @@ -76,7 +76,7 @@ class Service end def retrieve(verbose, os_types, use_token = true, ondemand = nil) - Vmfloaty.logger.info 'Requesting a vm without a token...' unless use_token + FloatyLogger.info 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil @service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand end @@ -91,8 +91,8 @@ class Service begin token_value = token || get_new_token(verbose) rescue TokenError => e - Vmfloaty.logger.error e - Vmfloaty.logger.info 'Could not get token... requesting vm without a token anyway...' + FloatyLogger.error e + FloatyLogger.info 'Could not get token... requesting vm without a token anyway...' end end Ssh.ssh(verbose, self, host_os, token_value) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 6edca63..0c2328b 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -109,8 +109,8 @@ class Utils raise "Invalid service type #{service.type}" end rescue StandardError => e - Vmfloaty.logger.error("Something went wrong while trying to gather information on #{hostname}:") - Vmfloaty.logger.error(e) + FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:") + FloatyLogger.error(e) end end end @@ -134,7 +134,7 @@ class Utils char = 'o' puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" rescue StandardError => e - Vmfloaty.logger.error "#{name.ljust(width)} #{e.red}" + FloatyLogger.error "#{name.ljust(width)} #{e.red}" end end puts message.colorize(status_response['status']['ok'] ? :default : :red) @@ -153,11 +153,11 @@ class Utils char = 'o' puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" rescue StandardError => e - Vmfloaty.logger.error "#{name.ljust(width)} #{e.red}" + FloatyLogger.error "#{name.ljust(width)} #{e.red}" end end when 'ABS' - Vmfloaty.logger.error 'ABS Not OK' unless status_response + FloatyLogger.error 'ABS Not OK' unless status_response puts 'ABS is OK'.green if status_response else raise "Invalid service type #{service.type}" From b44b9c6e9898c0179a9264b7d37b322d399e23b9 Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Wed, 12 Aug 2020 11:47:58 -0700 Subject: [PATCH 125/265] Bump version for 0.11.0 release --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index d7cf0c0..c738404 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.10.0' + VERSION = '0.11.0' end From d22e2b41946dd134e8f426f40298f0803d176ff6 Mon Sep 17 00:00:00 2001 From: "Sean P. McDonald" Date: Tue, 11 Aug 2020 15:07:59 -0500 Subject: [PATCH 126/265] (new-feature) Add json option to list/delete command This commit adds an option `--json` to the list and delete commands. When the json flag is used the commands will print output as formatted JSON rather than pretty printed strings. --- lib/vmfloaty.rb | 42 ++++++++++++++++++++------- lib/vmfloaty/utils.rb | 66 ++++++++++++++++++++++++++++--------------- 2 files changed, 76 insertions(+), 32 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index d1c2df2..19e194a 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -87,6 +87,7 @@ class Vmfloaty c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' c.option '--active', 'Prints information about active vms for a given token' + c.option '--json', 'Prints information as JSON' c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| @@ -100,10 +101,18 @@ class Vmfloaty running_vms = service.list_active(verbose) host = URI.parse(service.url).host if running_vms.empty? - puts "You have no running VMs on #{host}" + if options.json + puts {}.to_json + else + FloatyLogger.info "You have no running VMs on #{host}" + end else - puts "Your VMs on #{host}:" - Utils.pretty_print_hosts(verbose, service, running_vms) + if options.json + puts Utils.get_host_data(verbose, service, running_vms).to_json + else + puts "Your VMs on #{host}:" + Utils.pretty_print_hosts(verbose, service, running_vms) + end end else # list available vms from pooler @@ -200,6 +209,7 @@ class Vmfloaty c.option '--service STRING', String, 'Configured pooler service name' c.option '--all', 'Deletes all vms acquired by a token' c.option '-f', 'Does not prompt user when deleting all vms' + c.option '--json', 'Outputs hosts scheduled for deletion as JSON' c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' c.action do |args, options| @@ -215,12 +225,18 @@ class Vmfloaty if delete_all running_vms = service.list_active(verbose) if running_vms.empty? - puts 'You have no running VMs.' + if options.json + puts {}.to_json + else + FloatyLogger.info "You have no running VMs." + end else - Utils.pretty_print_hosts(verbose, service, running_vms, true) - # Confirm deletion confirmed = true - confirmed = agree('Delete all these VMs? [y/N]') unless force + unless force + Utils.pretty_print_hosts(verbose, service, running_vms, true) + # Confirm deletion + confirmed = agree('Delete all these VMs? [y/N]') + end if confirmed response = service.delete(verbose, running_vms) response.each do |hostname, result| @@ -257,9 +273,15 @@ class Vmfloaty unless successes.empty? FloatyLogger.info unless failures.empty? - puts 'Scheduled the following VMs for deletion:' - successes.each do |hostname| - puts "- #{hostname}" + if options.json + puts successes.to_json + else + puts 'Scheduled the following VMs for deletion:' + output = '' + successes.each do |hostname| + output += "- #{hostname}\n" + end + puts output end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 0c2328b..0940fa4 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -79,40 +79,62 @@ class Utils end def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false) + fetched_data = self.get_host_data(verbose, service, hostnames) + fetched_data.each do |hostname, host_data| + case service.type + when 'ABS' + # For ABS, 'hostname' variable is the jobID + host_data['allocated_resources'].each do |vm_name, _i| + puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" + end + when 'Pooler' + tag_pairs = [] + tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? + duration = "#{host_data['running']}/#{host_data['lifetime']} hours" + metadata = [host_data['template'], duration, *tag_pairs] + puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" + when 'NonstandardPooler' + line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" + line += ", #{host_data['hours_left_on_reservation']}h remaining" + line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? + line += ')' + puts line + else + raise "Invalid service type #{service.type}" + end + end + end + + def self.get_host_data(verbose, service, hostnames = []) + result = {} hostnames = [hostnames] unless hostnames.is_a? Array hostnames.each do |hostname| begin response = service.query(verbose, hostname) host_data = response[hostname] - - case service.type - when 'ABS' - # For ABS, 'hostname' variable is the jobID - if host_data['state'] == 'allocated' || host_data['state'] == 'filled' - host_data['allocated_resources'].each do |vm_name, _i| - puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" - end - end - when 'Pooler' - tag_pairs = [] - tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? - duration = "#{host_data['running']}/#{host_data['lifetime']} hours" - metadata = [host_data['template'], duration, *tag_pairs] - puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" - when 'NonstandardPooler' - line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" - line += ", #{host_data['hours_left_on_reservation']}h remaining" - line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? - line += ')' - puts line + if block_given? + yield host_data result else - raise "Invalid service type #{service.type}" + 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 end rescue StandardError => e FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:") FloatyLogger.error(e) end end + result end def self.pretty_print_status(verbose, service) From 1eaa80706c775661a3993dae8922ac2d1dc4ff7e Mon Sep 17 00:00:00 2001 From: "Sean P. McDonald" Date: Tue, 11 Aug 2020 15:09:58 -0500 Subject: [PATCH 127/265] (maint) Fail in ABS when queue requests don't return 200/202 When ABS returns an http status code other than 200 or 202, the ABS code should fail --- lib/vmfloaty/abs.rb | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 9a6358a..8c37072 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -229,10 +229,10 @@ class ABS retries = 360 - raise AuthError, "HTTP #{res.status}: The token provided could not authenticate to the pooler.\n#{res_body}" if res.status == 401 + validate_queue_status_response(res.status, res.body, "Initial request", verbose) (1..retries).each do |i| - queue_place, res_body = check_queue(conn, saved_job_id, req_obj) + queue_place, res_body = check_queue(conn, saved_job_id, req_obj, verbose) return translated(res_body) if res_body sleep_seconds = 10 if i >= 10 @@ -262,11 +262,12 @@ class ABS vmpooler_formatted_body end - def self.check_queue(conn, job_id, req_obj) + def self.check_queue(conn, job_id, req_obj, verbose) queue_info_res = conn.get "status/queue/info/#{job_id}" queue_info = JSON.parse(queue_info_res.body) res = conn.post 'request', req_obj.to_json + validate_queue_status_response(res.status, res.body, "Check queue request", verbose) unless res.body.empty? res_body = JSON.parse(res.body) @@ -315,4 +316,21 @@ class ABS def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha) raise NoMethodError, 'revert is not defined for ABS' end + + # Validate the http code returned during a queue status request. + # + # Return a success message that can be displayed if the status code is + # success, otherwise raise an error. + def self.validate_queue_status_response(status_code, body, request_name, verbose) + case status_code + when 200 + "#{request_name} returned success (Code 200)" if verbose + when 202 + "#{request_name} returned accepted, processing (Code 202)" if verbose + when 401 + raise AuthError, "HTTP #{status_code}: The token provided could not authenticate.\n#{body}" + else + raise "HTTP #{status_code}: #{request_name} request to ABS failed!\n#{body}" + end + end end From e684933525997be8289e554f3ff8eeb02917da5b Mon Sep 17 00:00:00 2001 From: Jarret Lavallee Date: Thu, 13 Aug 2020 12:37:09 -0600 Subject: [PATCH 128/265] (maint) Fix the argument list for nonstandardpooler Prior to this commit, 7 arguments would be sent into the `retrieve` method in nonstandardpooler. There were only 6 arguments in the method definition so an error would be thrown. This commit adds the `ondemand` argument to the `retrieve` method, but does not utilize it. --- lib/vmfloaty/nonstandard_pooler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 90722c0..5d755a9 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) + def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil) conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token From 701534872df4092aadd1beaf1094e79150f6a1db Mon Sep 17 00:00:00 2001 From: Christopher Thorn Date: Thu, 20 Aug 2020 09:31:11 -0700 Subject: [PATCH 129/265] (maint) Fix using ABS service without a .vmfloaty.yml file If you do not use a config file, and define everything on the command line, previously the service always defaulted to vmpooler. Even if you requested ABS. This PR fixes that, now we'll see if the config has no service defined and we defined on the command line a service, we'll use that service. --- lib/vmfloaty/utils.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 0c2328b..94e1f9d 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -206,6 +206,9 @@ class Utils # If the service is configured but some values are missing, use the top-level defaults to fill them in service_config.merge! config['services'][options.service] end + # No config file but service is declared on command line + elsif !config['services'] && options.service + service_config['type'] = options.service end # Prioritize an explicitly specified url, user, or token if the user provided one From 3f10e987b496a6678353cde07eb120526de29451 Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Thu, 20 Aug 2020 14:05:35 -0700 Subject: [PATCH 130/265] Update version for 0.11.1 release --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index c738404..81d81fd 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.11.0' + VERSION = '0.11.1' end From 04c73a970d991be59d3f17a7883508ce00c8ba60 Mon Sep 17 00:00:00 2001 From: Nate Wolfe Date: Fri, 21 Aug 2020 14:38:04 -0700 Subject: [PATCH 131/265] (maint) Remove warning about missing configuration file Previously the CLI would emit a warning about missing configuration file, but a configuration file does not appear to be a requirement, at least based on the documentation and the fact that everything can be specified directly on the command line. This commit simply removes the warning. Users will no longer get a warning when doing things like `floaty --version`, `floaty help`, and any other subcommand. --- lib/vmfloaty/conf.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb index 0b61f30..904020d 100644 --- a/lib/vmfloaty/conf.rb +++ b/lib/vmfloaty/conf.rb @@ -8,7 +8,7 @@ class Conf begin conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml") rescue StandardError - FloatyLogger.warn "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml" + # ignore end conf end From 8341a5f45dbae17accf3ff8b3631637e566d4e62 Mon Sep 17 00:00:00 2001 From: Nate Wolfe Date: Fri, 21 Aug 2020 15:45:10 -0700 Subject: [PATCH 132/265] (maint) Mention configuration file in CLI help text description So users can be aware of the configuration file since it will no longer be emitted as a warning during CLI invocation. --- lib/vmfloaty.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 19e194a..7734778 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -20,7 +20,7 @@ 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" + 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 From 9a44cc480efda5d817665f44eaa67e87cb8db731 Mon Sep 17 00:00:00 2001 From: Nate Wolfe Date: Mon, 24 Aug 2020 12:11:06 -0700 Subject: [PATCH 133/265] (maint) Add --user CLI option on delete and list subcommands To support usage without a configuration file. --- lib/vmfloaty.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 7734778..b2fb65a 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -90,6 +90,7 @@ class Vmfloaty c.option '--json', 'Prints information as JSON' c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' + c.option '--user STRING', String, 'User to authenticate with' c.action do |args, options| verbose = options.verbose || config['verbose'] @@ -212,6 +213,7 @@ class Vmfloaty c.option '--json', 'Outputs hosts scheduled for deletion as JSON' c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' + c.option '--user STRING', String, 'User to authenticate with' c.action do |args, options| verbose = options.verbose || config['verbose'] service = Service.new(options, config) From cb1ea8247bf78a90e3ebc25b5079bd570da34496 Mon Sep 17 00:00:00 2001 From: Nate Wolfe Date: Mon, 24 Aug 2020 14:20:28 -0700 Subject: [PATCH 134/265] WIP (DIO-911) Include job_id in ABS --json output Prior to this commit, when using --service=abs and --json the job_id value is not included in the JSON blob, which makes it difficult for calling code to grab both the job_id and the hosts without text processing the log messages printed to standard error. --- lib/vmfloaty/abs.rb | 6 +++--- lib/vmfloaty/utils.rb | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 8c37072..42ba28a 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -233,7 +233,7 @@ class ABS (1..retries).each do |i| queue_place, res_body = check_queue(conn, saved_job_id, req_obj, verbose) - return translated(res_body) if res_body + return translated(res_body, saved_job_id) if res_body sleep_seconds = 10 if i >= 10 sleep_seconds = i if i < 10 @@ -247,8 +247,8 @@ 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) - vmpooler_formatted_body = {} + def self.translated(res_body, 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 diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 2a4cbce..f262d9e 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -45,6 +45,10 @@ class Utils result = {} + # ABS has a job_id associated with hosts so pass that along + 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.each do |os, value| hostnames = Array(value['hostname']) @@ -57,7 +61,8 @@ class Utils def self.format_host_output(hosts) hosts.flat_map do |os, names| - names.map { |name| "- #{name} (#{os})" } + # Assume hosts are stored in Arrays and ignore everything else + names.map { |name| "- #{name} (#{os})" } if names.is_a? Array end.join("\n") end From dbf6c54173395839de92c7aed34603f47f1cd1b0 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Thu, 10 Sep 2020 13:49:46 -0500 Subject: [PATCH 135/265] The main goal for this PR is to enable using all of the vmfloaty scenarios when the service is set to ABS. Since ABS does not implement all the services, it fallsback on vmpooler when needed (example increasing the lifetime value) - Validating JSON can be parsed before parsing, as it used to throw uncaught errors - self.list_active is returning hosts for both nspooler and vmpooler but was returning job_ids for abs. Now standardized the returned values for use in the "modify" cli, and created a separate list_active_job_ids for the cases where a job_id list is expected - added a way to change the service in place for methods that do not make sense for ABS, and instead fallback on using vmpooler in those cases: 1. summary 2. modify 3. snapshot 4. revert 5. disk For those methods in the class itself, raising a NoMethodError, in case it is used directly - query now returns the queue info. For information on VMs, users should use --service vmpooler - pretty_print_hosts (used in list, and delete scenarios) will now print the job_id ABS information and indent each VM within and print it's metadata. Useful for knowing the running time and extending it. - added a new utility method to get the config for the vmpooler service, used for the fallback - added a passthrough for the vmpooler token to use when running ABS. This enables vmpooler to track the VMs used by each token (user). Also aligns the list between both ABS and vmpooler. Fixes the bit-bar issue where the VMs do not appear when created via ABS --- lib/vmfloaty.rb | 26 ++++++-- lib/vmfloaty/abs.rb | 133 +++++++++++++++++++++++++++------------- lib/vmfloaty/service.rb | 20 ++++++ lib/vmfloaty/utils.rb | 38 ++++++++++-- 4 files changed, 166 insertions(+), 51 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index b2fb65a..129cd16 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -99,7 +99,12 @@ class Vmfloaty if options.active # list active vms - running_vms = service.list_active(verbose) + 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 host = URI.parse(service.url).host if running_vms.empty? if options.json @@ -126,7 +131,7 @@ class Vmfloaty command :query do |c| c.syntax = 'floaty query hostname [options]' c.summary = 'Get information about a given vm' - c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm.' + c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm. If using ABS, you can query a job_id' c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com' c.option '--verbose', 'Enables verbose output' c.option '--service STRING', String, 'Configured pooler service name' @@ -165,7 +170,12 @@ class Vmfloaty FloatyLogger.error 'ERROR: Provide a hostname or specify --all.' exit 1 end - running_vms = modify_all ? service.list_active(verbose) : hostname.split(',') + running_vms = + if modify_all + service.list_active(verbose) + else + hostname.split(',') + end tags = options.tags ? JSON.parse(options.tags) : nil modify_hash = { @@ -189,7 +199,7 @@ class Vmfloaty end if ok if modify_all - puts 'Successfully modified all VMs.' + puts "Successfully modified all #{running_vms.count} VMs." else puts "Successfully modified VM #{hostname}." end @@ -225,7 +235,12 @@ class Vmfloaty successes = [] if delete_all - running_vms = service.list_active(verbose) + 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 if running_vms.empty? if options.json puts {}.to_json @@ -274,7 +289,6 @@ class Vmfloaty end unless successes.empty? - FloatyLogger.info unless failures.empty? if options.json puts successes.to_json else diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 8c37072..43734cd 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -2,6 +2,7 @@ require 'vmfloaty/errors' require 'vmfloaty/http' +require 'vmfloaty/utils' require 'faraday' require 'json' @@ -36,39 +37,59 @@ class ABS # } # } # - @active_hostnames = {} - def self.list_active(verbose, url, _token, user) - all_jobs = [] + def self.list_active_job_ids(verbose, url, user) + all_job_ids = [] @active_hostnames = {} - get_active_requests(verbose, url, user).each do |req_hash| - all_jobs.push(req_hash['request']['job']['id']) - @active_hostnames[req_hash['request']['job']['id']] = req_hash + @active_hostnames[req_hash['request']['job']['id']] = req_hash # full hash saved for later retrieval + all_job_ids.push(req_hash['request']['job']['id']) end - all_jobs + all_job_ids + end + + 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 + end + end + + hosts end def self.get_active_requests(verbose, url, user) conn = Http.get_conn(verbose, url) res = conn.get 'status/queue' - requests = JSON.parse(res.body) + if valid_json?(res.body) + requests = JSON.parse(res.body) + else + FloatyLogger.warn "Warning: couldn't parse body returned from abs/status/queue" + end ret_val = [] requests.each do |req| next if req == 'null' - req_hash = JSON.parse(req) + if valid_json?(req) + req_hash = JSON.parse(req) + else + FloatyLogger.warn "Warning: couldn't parse request returned from abs/status/queue" + next + end begin next unless user == req_hash['request']['job']['user'] ret_val.push(req_hash) rescue NoMethodError - FloatyLogger.warn "Warning: couldn't parse line returned from abs/status/queue: " + FloatyLogger.warn "Warning: couldn't parse user returned from abs/status/queue: " end end @@ -145,30 +166,43 @@ class ABS os_list = [] res = conn.get 'status/platforms/vmpooler' - - res_body = JSON.parse(res.body) - os_list << '*** VMPOOLER Pools ***' - os_list += JSON.parse(res_body['vmpooler_platforms']) + if valid_json?(res.body) + res_body = JSON.parse(res.body) + if res_body.key?('vmpooler_platforms') + os_list << '*** VMPOOLER Pools ***' + os_list += JSON.parse(res_body['vmpooler_platforms']) + end + end res = conn.get 'status/platforms/ondemand_vmpooler' - res_body = JSON.parse(res.body) - unless res_body['ondemand_vmpooler_platforms'] == '[]' - os_list << '' - os_list << '*** VMPOOLER ONDEMAND Pools ***' - os_list += JSON.parse(res_body['ondemand_vmpooler_platforms']) + if valid_json?(res.body) + res_body = JSON.parse(res.body) + if res_body.key?('ondemand_vmpooler_platforms') && res_body['ondemand_vmpooler_platforms'] != '[]' + os_list << '' + os_list << '*** VMPOOLER ONDEMAND Pools ***' + os_list += JSON.parse(res_body['ondemand_vmpooler_platforms']) + end end res = conn.get 'status/platforms/nspooler' - res_body = JSON.parse(res.body) - os_list << '' - os_list << '*** NSPOOLER Pools ***' - os_list += JSON.parse(res_body['nspooler_platforms']) + if valid_json?(res.body) + res_body = JSON.parse(res.body) + if res_body.key?('nspooler_platforms') + os_list << '' + os_list << '*** NSPOOLER Pools ***' + os_list += JSON.parse(res_body['nspooler_platforms']) + end + end res = conn.get 'status/platforms/aws' - res_body = JSON.parse(res.body) - os_list << '' - os_list << '*** AWS Pools ***' - os_list += JSON.parse(res_body['aws_platforms']) + if valid_json?(res.body) + res_body = JSON.parse(res.body) + if res_body.key?('aws_platforms') + os_list << '' + os_list << '*** AWS Pools ***' + os_list += JSON.parse(res_body['aws_platforms']) + end + end os_list.delete 'ok' @@ -197,7 +231,7 @@ class ABS conn.headers['X-AUTH-TOKEN'] = token if token saved_job_id = DateTime.now.strftime('%Q') - + vmpooler_config = Utils.get_vmpooler_service_config req_obj = { :resources => os_types, :job => { @@ -206,6 +240,7 @@ class ABS :user => user, }, }, + :vm_token => vmpooler_config['token'] # request with this token, on behalf of this user } if options['priority'] @@ -264,12 +299,17 @@ class ABS def self.check_queue(conn, job_id, req_obj, verbose) queue_info_res = conn.get "status/queue/info/#{job_id}" - queue_info = JSON.parse(queue_info_res.body) + if valid_json?(queue_info_res.body) + queue_info = JSON.parse(queue_info_res.body) + else + FloatyLogger.warn "Could not parse the status/queue/info/#{job_id}" + return [nil, nil] + end res = conn.post 'request', req_obj.to_json validate_queue_status_response(res.status, res.body, "Check queue request", verbose) - unless res.body.empty? + unless res.body.empty? || !valid_json?(res.body) res_body = JSON.parse(res.body) return queue_info['queue_place'], res_body end @@ -277,7 +317,7 @@ class ABS end def self.snapshot(_verbose, _url, _hostname, _token) - FloatyLogger.info "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" + raise NoMethodError, "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)" end def self.status(verbose, url) @@ -289,20 +329,24 @@ class ABS end def self.summary(verbose, url) - conn = Http.get_conn(verbose, url) - - res = conn.get 'summary' - JSON.parse(res.body) + raise NoMethodError, 'summary is not defined for ABS' end - def self.query(verbose, url, hostname) - return @active_hostnames if @active_hostnames + def self.query(verbose, url, job_id) + # return saved hostnames from the last time list_active was run + # preventing having to query the API again. + # This works as long as query is called after list_active + return @active_hostnames if @active_hostnames && !@active_hostnames.empty? - FloatyLogger.info "For vmpooler/snapshot information, use '--service vmpooler' (even for vms checked out with ABS)" + # If using the cli query job_id conn = Http.get_conn(verbose, url) - - res = conn.get "host/#{hostname}" - JSON.parse(res.body) + queue_info_res = conn.get "status/queue/info/#{job_id}" + if valid_json?(queue_info_res.body) + queue_info = JSON.parse(queue_info_res.body) + else + FloatyLogger.warn "Could not parse the status/queue/info/#{job_id}" + end + queue_info end def self.modify(_verbose, _url, _hostname, _token, _modify_hash) @@ -333,4 +377,11 @@ class ABS raise "HTTP #{status_code}: #{request_name} request to ABS failed!\n#{body}" end end + + def self.valid_json?(json) + JSON.parse(json) + return true + rescue TypeError, JSON::ParserError => e + return false + end end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 11ddc29..d512c4d 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -7,11 +7,13 @@ require 'vmfloaty/ssh' class Service attr_reader :config + attr_accessor :silent def initialize(options, config_hash = {}) options ||= Commander::Command::Options.new @config = Utils.get_service_config config_hash, options @service_object = Utils.get_service_object @config['type'] + @silent = false end def method_missing(method_name, *args, &block) @@ -103,6 +105,7 @@ class Service end def modify(verbose, hostname, modify_hash) + maybe_use_vmpooler @service_object.modify verbose, url, hostname, token, modify_hash end @@ -115,18 +118,35 @@ class Service end def summary(verbose) + maybe_use_vmpooler @service_object.summary verbose, url end def snapshot(verbose, hostname) + maybe_use_vmpooler @service_object.snapshot verbose, url, hostname, token end def revert(verbose, hostname, snapshot_sha) + maybe_use_vmpooler @service_object.revert verbose, url, hostname, token, snapshot_sha end def disk(verbose, hostname, disk) + maybe_use_vmpooler @service_object.disk(verbose, url, hostname, token, disk) end + + # some methods do not exist for ABS, and if possible should target the Pooler service + def maybe_use_vmpooler + if @service_object.is_a?(ABS.class) + if !self.silent + FloatyLogger.info "The service in use is ABS, but the requested method should run against vmpooler directly, using vmpooler config from ~/.vmfloaty.yml" + self.silent = true + end + + @config = Utils.get_vmpooler_service_config + @service_object = Pooler + end + end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 2a4cbce..ed01ac6 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -3,6 +3,7 @@ require 'vmfloaty/abs' require 'vmfloaty/nonstandard_pooler' require 'vmfloaty/pooler' +require 'vmfloaty/conf' class Utils # TODO: Takes the json response body from an HTTP GET @@ -78,21 +79,28 @@ class Utils os_types end - def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false) + def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false, indent = 0) fetched_data = self.get_host_data(verbose, service, hostnames) fetched_data.each do |hostname, host_data| case service.type when 'ABS' - # For ABS, 'hostname' variable is the jobID + # For ABS, 'hostname' variable is the jobID + # + # Create a vmpooler service to query each hostname there so as to get the metadata too + + vmpooler_service = service.clone + vmpooler_service.silent = true + vmpooler_service.maybe_use_vmpooler + puts "- [JobID:#{host_data['request']['job']['id']}] <#{host_data['state']}>" host_data['allocated_resources'].each do |vm_name, _i| - puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>" + self.pretty_print_hosts(verbose, vmpooler_service, vm_name['hostname'].split('.')[0], print_to_stderr, indent+2) end when 'Pooler' tag_pairs = [] tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] - puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})" + puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" @@ -241,4 +249,26 @@ class Utils service_config end + + # This method gets the vmpooler service configured in ~/.vmfloaty + def self.get_vmpooler_service_config + 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', + } + + # at a minimum, the url needs to be configured + if config['services'] && config['services']['vmpooler'] && config['services']['vmpooler']['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'] + else + raise ArgumentError, "Could not find a configured service named 'vmpooler' in ~/.vmfloaty.yml use this format:\nservices:\n vmpooler:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" + end + + service_config + end end From c65b72d86bbf7a9ba9b6f9b2323c65ad2e59d9c4 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 11 Sep 2020 09:32:16 -0500 Subject: [PATCH 136/265] Document the ~/.vmfloaty content for ABS usage --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9a8e44f..b74637c 100644 --- a/README.md +++ b/README.md @@ -105,12 +105,20 @@ Now vmfloaty will use those config files if no flag was specified. #### Default to Puppet's ABS instead of vmpooler +When the --service is not specified on the command line, the first one is selected, so put ABS first. +Also provide a "vmpooler" service that ABS can use as fallback for operations targeting vmpooler directly ```yaml # file at ~/.vmfloaty.yml -url: 'https://abs.example.net' -user: 'brian' -token: 'tokenstring' -type: 'abs' +services: + abs: + url: 'https://abs/api/v2' + type: 'abs' + user: 'samuel' + token: 'foo' + vmpooler: + url: 'http://vmpooler' + user: 'samuel' + token: 'bar' ``` #### Configuring multiple services From 4b7cbbf0e521d02984e6c09504ae3c4d0f891852 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Tue, 15 Sep 2020 11:21:58 -0500 Subject: [PATCH 137/265] fix abs spec tests --- spec/vmfloaty/abs_spec.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index b59380a..c075c56 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -10,14 +10,15 @@ describe ABS do end describe '#format' do - it 'returns an hash formatted like a vmpooler return' do + it 'returns an hash formatted like a vmpooler return, plus the job_id' do + 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' }, ] - vmpooler_formatted_response = ABS.translated(abs_formatted_response) + vmpooler_formatted_response = ABS.translated(abs_formatted_response, job_id) vmpooler_formatted_compare = { 'centos-7.2-x86_64' => {}, @@ -29,6 +30,8 @@ describe ABS do vmpooler_formatted_compare['ok'] = true + vmpooler_formatted_compare['job_id'] = job_id + expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare) vmpooler_formatted_response.delete('ok') vmpooler_formatted_compare.delete('ok') From 5333158bdcd177b915dc4cef2a2805d9ee5a67af Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Wed, 16 Sep 2020 11:23:01 -0500 Subject: [PATCH 138/265] (maint) Support any vmpooler for ABS via vmpooler_fallback Before this change, the fallback vmpooler for ABS had to be named 'vmpooler' and it only supported one. With this new code, users can set a key within an 'abs' service type called vmpooler_fallback that points to any other service configured in the ~/.vmfloaty.yml config file. If not set, the appropriate error message is returned, with an example configuration. Added the various use cases for the config to the unit tests --- lib/vmfloaty/abs.rb | 14 ++++----- lib/vmfloaty/service.rb | 4 +-- lib/vmfloaty/utils.rb | 12 +++++--- spec/vmfloaty/utils_spec.rb | 57 +++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 43734cd..164e7ff 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -210,7 +210,7 @@ class ABS end # Retrieve an OS from ABS. - def self.retrieve(verbose, os_types, token, url, user, options, _ondemand = nil) + def self.retrieve(verbose, os_types, token, url, user, config, _ondemand = nil) # # Contents of post must be like: # @@ -231,7 +231,7 @@ class ABS conn.headers['X-AUTH-TOKEN'] = token if token saved_job_id = DateTime.now.strftime('%Q') - vmpooler_config = Utils.get_vmpooler_service_config + vmpooler_config = Utils.get_vmpooler_service_config(config['vmpooler_fallback']) req_obj = { :resources => os_types, :job => { @@ -243,15 +243,15 @@ class ABS :vm_token => vmpooler_config['token'] # request with this token, on behalf of this user } - if options['priority'] - req_obj[:priority] = if options['priority'] == 'high' + if config['priority'] + req_obj[:priority] = if config['priority'] == 'high' 1 - elsif options['priority'] == 'medium' + elsif config['priority'] == 'medium' 2 - elsif options['priority'] == 'low' + elsif config['priority'] == 'low' 3 else - options['priority'].to_i + config['priority'].to_i end end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index d512c4d..a0303c4 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -141,11 +141,11 @@ class Service def maybe_use_vmpooler if @service_object.is_a?(ABS.class) if !self.silent - FloatyLogger.info "The service in use is ABS, but the requested method should run against vmpooler directly, using vmpooler config from ~/.vmfloaty.yml" + 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 - @config = Utils.get_vmpooler_service_config + @config = Utils.get_vmpooler_service_config(@config['vmpooler_fallback']) @service_object = Pooler end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index ed01ac6..391fd72 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -251,7 +251,7 @@ class Utils end # This method gets the vmpooler service configured in ~/.vmfloaty - def self.get_vmpooler_service_config + def self.get_vmpooler_service_config(vmpooler_fallback) config = Conf.read_config # The top-level url, user, and token values in the config file are treated as defaults service_config = { @@ -262,11 +262,15 @@ class Utils } # at a minimum, the url needs to be configured - if config['services'] && config['services']['vmpooler'] && config['services']['vmpooler']['url'] + 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'] + service_config.merge! config['services'][vmpooler_fallback] else - raise ArgumentError, "Could not find a configured service named 'vmpooler' in ~/.vmfloaty.yml use this format:\nservices:\n vmpooler:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" + 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 end service_config diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 4d31d24..e58fab2 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -247,4 +247,61 @@ describe Utils do Utils.pretty_print_hosts(nil, service, hostname) end end + + describe '#get_vmpooler_service_config' do + let(:Conf) { double } + it 'returns an error if the vmpooler_fallback is not setup' do + config = { + 'user' => 'foo', + 'services' => { + '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) + 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' + } + } + } + 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/) + 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' + }, + 'myvmpooler' => { + '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' + }) + end + end end From 9e61247cfe7136dbd54ab9840fe751852e63d761 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Wed, 16 Sep 2020 10:30:46 -0400 Subject: [PATCH 139/265] Add service command This change creates the `floaty service` command with two valid arguemnts: types and examples - `floaty service types` prints out a list of valid types for use in a service definition in ~/.vmfloaty.yml - `floaty service examples` prints out example configuration files for both a single service and multiple services. --- README.md | 96 +++++----------------------------- extras/completions/floaty.bash | 2 +- lib/vmfloaty.rb | 64 +++++++++++++++++++++++ lib/vmfloaty/utils.rb | 11 ++-- spec/vmfloaty/utils_spec.rb | 8 +++ 5 files changed, 93 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index b74637c..83e94cc 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,8 @@ A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler - [Example workflow](#example-workflow) - [vmfloaty dotfile](#vmfloaty-dotfile) - [Basic configuration](#basic-configuration) - - [Default to Puppet's ABS instead of vmpooler](#default-to-puppets-abs-instead-of-vmpooler) - - [Configuring multiple services](#configuring-multiple-services) - - [Using a Nonstandard Pooler service](#using-a-nonstandard-pooler-service) + - [Using multiple services](#using-multiple-services) + - [Using backends besides VMPooler](#using-backends-besides-vmpooler) - [Valid config keys](#valid-config-keys) - [Tab Completion](#tab-completion) - [vmpooler API](#vmpooler-api) @@ -54,6 +53,7 @@ $ floaty --help modify Modify a VM's tags, time to live, disk space, or reservation reason query Get information about a given vm revert Reverts a vm to a specified snapshot + service Display information about floaty services and their configuration snapshot Takes a snapshot of a given vm ssh Grabs a single vm and sshs into it status Prints the status of pools in the pooler service @@ -90,10 +90,12 @@ floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring ### vmfloaty dotfile -If you do not wish to continually specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example: +If you do not wish to continually specify various config options with the cli, you can `~/.vmfloaty.yml` for some defaults. You can get a list of valid service types and example configuration files via `floaty service types` and `floaty service examples`, respectively. #### Basic configuration +This is the simplest type of configuration where you only need a single service: + ```yaml # file at ~/.vmfloaty.yml url: 'https://vmpooler.example.net/api/v1' @@ -101,92 +103,19 @@ user: 'brian' token: 'tokenstring' ``` -Now vmfloaty will use those config files if no flag was specified. +Run `floaty service examples` to see additional configuration options -#### Default to Puppet's ABS instead of vmpooler +#### Using multiple services -When the --service is not specified on the command line, the first one is selected, so put ABS first. -Also provide a "vmpooler" service that ABS can use as fallback for operations targeting vmpooler directly -```yaml -# file at ~/.vmfloaty.yml -services: - abs: - url: 'https://abs/api/v2' - type: 'abs' - user: 'samuel' - token: 'foo' - vmpooler: - url: 'http://vmpooler' - user: 'samuel' - token: 'bar' -``` - -#### Configuring multiple services - -Most commands allow you to specify a `--service ` option to allow the use of multiple vmpooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services. - -To configure multiple services, you can set up your `~/.vmfloaty.yml` config file like this: - -```yaml -# file at /Users/me/.vmfloaty.yml -user: 'brian' -services: - main: - url: 'https://vmpooler.example.net/api/v1' - token: 'tokenstring' - alternate: - url: 'https://vmpooler.example.com/api/v1' - token: 'alternate-tokenstring' -``` +Most commands allow you to specify a `--service ` option to allow the use of multiple pooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services. - If you run `floaty` without a `--service ` option, vmfloaty will use the first configured service by default. - With the config file above, the default would be to use the 'main' vmpooler instance. - If keys are missing for a configured service, vmfloaty will attempt to fall back to the top-level values. - With the config file above, 'brian' will be used as the username for both configured services, since neither specifies a username. + This makes it so you can specify things like `user` once at the top of your `~/.vmfloaty.yml`. -Examples using the above configuration: +#### Using backends besides VMPooler -List available vm types from our main vmpooler instance: - -```bash -floaty list --service main -# or, since the first configured service is used by default: -floaty list -``` - -List available vm types from our alternate vmpooler instance: - -```bash -floaty list --service alternate -``` - -#### Using a Nonstandard Pooler service - -vmfloaty is capable of working with Puppet's [nonstandard pooler](https://github.com/puppetlabs/nspooler) in addition to the default vmpooler API. To add a nonstandard pooler service, specify an API `type` value in your service configuration, like this: - -```yaml -# file at /Users/me/.vmfloaty.yml -user: 'brian' -services: - vm: - url: 'https://vmpooler.example.net/api/v1' - token: 'tokenstring' - ns: - url: 'https://nspooler.example.net/api/v1' - token: 'nspooler-tokenstring' - type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service - abs: - url: 'https://abs.example.net/' - token: 'abs-tokenstring' - type: 'abs' # <-- 'type' is necessary for any non-vmpooler service - -``` - -With this configuration, you could list available OS types from nspooler like this: - -```bash -floaty list --service ns -``` +vmfloaty supports additional backends besides VMPooler. To see a complete list, run `floaty service types`. The output of `floaty service examples` will show you how to configure each of the supported backends. #### Valid config keys @@ -198,6 +127,7 @@ Here are the keys that vmfloaty currently supports: - url (String) - services (String) - type (String) +- vmpooler_fallback (String) ### Tab Completion diff --git a/extras/completions/floaty.bash b/extras/completions/floaty.bash index 1d1e69d..5adee75 100644 --- a/extras/completions/floaty.bash +++ b/extras/completions/floaty.bash @@ -7,7 +7,7 @@ _vmfloaty() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - subcommands="delete get help list modify query revert snapshot ssh status summary token" + subcommands="delete get help list modify query revert service snapshot ssh status summary token" template_subcommands="get ssh" hostname_subcommands="delete modify query revert snapshot" diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 129cd16..e1cbb20 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -497,6 +497,70 @@ class Vmfloaty end end + command :service do |c| + c.syntax = 'floaty service ' + c.summary = 'Display information about floaty services and their configuration' + c.description = 'Display information about floaty services to aid in setting up a configuration file.' + 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| + action = args.first + + example_config = Utils.strip_heredoc(<<-CONFIG) + # Sample ~/.vmfloaty.yml with just vmpooler + user: 'jdoe' + url: 'https://vmpooler.example.net' + token: '456def789' + + # Sample ~/.vmfloaty.yml with multiple services + # Note: when the --service is not specified on the command line, + # the first service listed here is selected automatically + user: 'jdoe' + services: + abs-prod: + type: 'abs' + url: 'https://abs.example.net/api/v2' + token: '123abc456' + vmpooler_fallback: 'vmpooler-prod' + nspooler-prod: + type: 'nspooler' + url: 'https://nspooler.example.net' + token: '789ghi012' + vmpooler-dev: + type: 'vmpooler' + url: 'https://vmpooler-dev.example.net' + token: '987dsa654' + vmpooler-prod: + type: 'vmpooler' + url: 'https://vmpooler.example.net' + token: '456def789' + + CONFIG + + types_output = Utils.strip_heredoc(<<-TYPES) + The values on the left below can be used in ~/.vmfloaty.yml as the value of type: + + abs: Puppet's Always Be Scheduling + nspooler: Puppet's Non-standard Pooler, aka NSPooler + vmpooler: Puppet's VMPooler + TYPES + + case action + when 'examples' + FloatyLogger.info example_config + when 'types' + FloatyLogger.info types_output + when nil + FloatyLogger.error 'No action provided' + exit 1 + else + FloatyLogger.error "Unknown action: #{action}" + exit 1 + end + end + end + run! end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index ed01ac6..9384ea0 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -203,12 +203,15 @@ class Utils end def self.get_service_object(type = '') - nspooler_strings = %w[ns nspooler nonstandard nonstandard_pooler] abs_strings = %w[abs alwaysbescheduling always_be_scheduling] - if nspooler_strings.include? type.downcase - NonstandardPooler - elsif abs_strings.include? type.downcase + nspooler_strings = %w[ns nspooler nonstandard nonstandard_pooler] + vmpooler_strings = %w[vmpooler] + if abs_strings.include? type.downcase ABS + elsif nspooler_strings.include? type.downcase + NonstandardPooler + elsif vmpooler_strings.include? type.downcase + Pooler else Pooler end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 4d31d24..032dbcb 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -77,9 +77,17 @@ describe Utils do expect(Utils.get_service_object).to be Pooler end + it 'uses abs when told explicitly' do + expect(Utils.get_service_object('abs')).to be ABS + end + it 'uses nspooler when told explicitly' do expect(Utils.get_service_object('nspooler')).to be NonstandardPooler end + + it 'uses vmpooler when told explicitly' do + expect(Utils.get_service_object('vmpooler')).to be Pooler + end end describe '#get_service_config' do From 4df970b21fd835e4e46133780b95f997e706602e Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Mon, 21 Sep 2020 14:39:10 -0500 Subject: [PATCH 140/265] (maint) Fix for ABS PR#306 that includes json responses Before this change ABS sometiimes returned a string of JSON with escaped quotes, that had to be parsed again With this change, floaty should accept both the legacy and the new full JSON responses. --- lib/vmfloaty/abs.rb | 28 +++++++++++++++++++++++----- spec/vmfloaty/abs_spec.rb | 6 +++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 6b5c0e1..d75a658 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -77,8 +77,10 @@ class ABS requests.each do |req| next if req == 'null' - if valid_json?(req) + if valid_json?(req) # legacy ABS had another JSON string always-be-scheduling/pull/306 req_hash = JSON.parse(req) + elsif req.is_a?(Hash) + req_hash = req else FloatyLogger.warn "Warning: couldn't parse request returned from abs/status/queue" next @@ -170,7 +172,11 @@ class ABS res_body = JSON.parse(res.body) if res_body.key?('vmpooler_platforms') os_list << '*** VMPOOLER Pools ***' - os_list += JSON.parse(res_body['vmpooler_platforms']) + if res_body['vmpooler_platforms'].is_a?(Hash) + os_list += res_body['vmpooler_platforms'] + else + os_list += JSON.parse(res_body['vmpooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + end end end @@ -180,7 +186,11 @@ class ABS if res_body.key?('ondemand_vmpooler_platforms') && res_body['ondemand_vmpooler_platforms'] != '[]' os_list << '' os_list << '*** VMPOOLER ONDEMAND Pools ***' - os_list += JSON.parse(res_body['ondemand_vmpooler_platforms']) + if res_body['ondemand_vmpooler_platforms'].is_a?(Hash) + os_list += res_body['ondemand_vmpooler_platforms'] + else + os_list += JSON.parse(res_body['ondemand_vmpooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + end end end @@ -190,7 +200,11 @@ class ABS if res_body.key?('nspooler_platforms') os_list << '' os_list << '*** NSPOOLER Pools ***' - os_list += JSON.parse(res_body['nspooler_platforms']) + if res_body['nspooler_platforms'].is_a?(Hash) + os_list += res_body['nspooler_platforms'] + else + os_list += JSON.parse(res_body['nspooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + end end end @@ -200,7 +214,11 @@ class ABS if res_body.key?('aws_platforms') os_list << '' os_list << '*** AWS Pools ***' - os_list += JSON.parse(res_body['aws_platforms']) + if res_body['aws_platforms'].is_a?(Hash) + os_list += res_body['aws_platforms'] + else + os_list += JSON.parse(res_body['aws_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + end end end diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index c075c56..5e82993 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -71,9 +71,9 @@ describe ABS do # rubocop:disable Layout/LineLength @active_requests_response = ' [ - "{ \"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"take-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:45:29 +0000\":\"Allocated take-this.delivery.puppetlabs.net for job 1576255517241\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255517241\",\"tags\":{\"user\":\"test-user\"},\"user\":\"test-user\",\"time-received\":1576255519},\"priority\":1}}", + { "state":"allocated","last_processed":"2019-12-16 23:00:34 +0000","allocated_resources":[{"hostname":"take-this.delivery.puppetlabs.net","type":"win-2012r2-x86_64","engine":"vmpooler"}],"audit_log":{"2019-12-13 16:45:29 +0000":"Allocated take-this.delivery.puppetlabs.net for job 1576255517241"},"request":{"resources":{"win-2012r2-x86_64":1},"job":{"id":"1576255517241","tags":{"user":"test-user"},"user":"test-user","time-received":1576255519},"priority":1}}, "null", - "{\"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"not-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:46:14 +0000\":\"Allocated not-this.delivery.puppetlabs.net for job 1576255565159\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255565159\",\"tags\":{\"user\":\"not-test-user\"},\"user\":\"not-test-user\",\"time-received\":1576255566},\"priority\":1}}" + {"state":"allocated","last_processed":"2019-12-16 23:00:34 +0000","allocated_resources":[{"hostname":"not-this.delivery.puppetlabs.net","type":"win-2012r2-x86_64","engine":"vmpooler"}],"audit_log":{"2019-12-13 16:46:14 +0000":"Allocated not-this.delivery.puppetlabs.net for job 1576255565159"},"request":{"resources":{"win-2012r2-x86_64":1},"job":{"id":"1576255565159","tags":{"user":"not-test-user"},"user":"not-test-user","time-received":1576255566},"priority":1}} ]' # rubocop:enable Layout/LineLength @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' @@ -101,7 +101,7 @@ describe ABS do # rubocop:disable Layout/LineLength @active_requests_response = ' [ - "{ \"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}}" + { "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 } # rubocop:enable Layout/LineLength From cd7c0fae134747607a4299a881e80689223fe49e Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Mon, 21 Sep 2020 15:20:22 -0500 Subject: [PATCH 141/265] Adding spec tests for #list --- lib/vmfloaty/abs.rb | 24 ++++++++++----------- spec/vmfloaty/abs_spec.rb | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index d75a658..2426c32 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -172,10 +172,10 @@ 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?(Hash) - os_list += res_body['vmpooler_platforms'] - else + 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 end end @@ -186,10 +186,10 @@ class ABS if res_body.key?('ondemand_vmpooler_platforms') && res_body['ondemand_vmpooler_platforms'] != '[]' os_list << '' os_list << '*** VMPOOLER ONDEMAND Pools ***' - if res_body['ondemand_vmpooler_platforms'].is_a?(Hash) - os_list += res_body['ondemand_vmpooler_platforms'] - else + if res_body['ondemand_vmpooler_platforms'].is_a?(String) os_list += JSON.parse(res_body['ondemand_vmpooler_platforms']) # legacy ABS had another JSON string always-be-scheduling/pull/306 + else + os_list += res_body['ondemand_vmpooler_platforms'] end end end @@ -200,10 +200,10 @@ class ABS if res_body.key?('nspooler_platforms') os_list << '' os_list << '*** NSPOOLER Pools ***' - if res_body['nspooler_platforms'].is_a?(Hash) - os_list += res_body['nspooler_platforms'] - else + 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 end end @@ -214,10 +214,10 @@ class ABS if res_body.key?('aws_platforms') os_list << '' os_list << '*** AWS Pools ***' - if res_body['aws_platforms'].is_a?(Hash) - os_list += res_body['aws_platforms'] - else + 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 end end diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index 5e82993..40804cf 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -9,6 +9,50 @@ describe ABS do before :each do end + describe '#list' do + it 'skips empty platforms and lists aws' do + stub_request(:get, "http://foo/status/platforms/vmpooler"). + to_return(:status => 200, :body => "", :headers => {}) + stub_request(:get, "http://foo/status/platforms/ondemand_vmpooler"). + to_return(:status => 200, :body => "", :headers => {}) + stub_request(:get, "http://foo/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/status/platforms/aws"). + to_return(:status => 200, :body => body, :headers => {}) + + + 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") + end + it 'legacy JSON string, prior to PR 306' do + stub_request(:get, "http://foo/status/platforms/vmpooler"). + to_return(:status => 200, :body => "", :headers => {}) + stub_request(:get, "http://foo/status/platforms/ondemand_vmpooler"). + to_return(:status => 200, :body => "", :headers => {}) + stub_request(:get, "http://foo/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/status/platforms/aws"). + to_return(:status => 200, :body => body, :headers => {}) + + 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") + 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" From 40072e90e45c6427839cdc8cea81139f567c4d85 Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Fri, 21 Aug 2020 11:42:12 -0700 Subject: [PATCH 142/265] Fix `print_to_stderr` option for Utils.pretty_print_hosts Previously this option had no effect on the output. This commit makes the option effective and also refactors the tests for this method to cover this case. --- lib/vmfloaty/utils.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 9478d04..f6d69ef 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -85,6 +85,8 @@ class Utils end 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.each do |hostname, host_data| case service.type @@ -96,7 +98,8 @@ class Utils vmpooler_service = service.clone vmpooler_service.silent = true vmpooler_service.maybe_use_vmpooler - puts "- [JobID:#{host_data['request']['job']['id']}] <#{host_data['state']}>" + output_target.puts "- [JobID:#{host_data['request']['job']['id']}] <#{host_data['state']}>" + host_data['allocated_resources'].each do |vm_name, _i| self.pretty_print_hosts(verbose, vmpooler_service, vm_name['hostname'].split('.')[0], print_to_stderr, indent+2) end @@ -105,13 +108,13 @@ class Utils tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['template'], duration, *tag_pairs] - puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) + output_target.puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? line += ')' - puts line + output_target.puts line else raise "Invalid service type #{service.type}" end From b31f44fb40d2f711ff4267e250b1fbc67e9fb447 Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Fri, 21 Aug 2020 11:43:36 -0700 Subject: [PATCH 143/265] Add `--hostnameonly` option to `floaty list --active` Adds an option to the `floaty list` subcommand so that, when listing active hosts, floaty will output just the hostnames, without any additional information or formatting. Hostnames will be separated by a newline. This functionality is primarily intended for consuming by tooling (such as the tab completion scripts). --- lib/vmfloaty.rb | 5 +++ lib/vmfloaty/utils.rb | 15 +++++++ spec/vmfloaty/utils_spec.rb | 83 +++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index e1cbb20..7d015f3 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -88,6 +88,7 @@ class Vmfloaty c.option '--service STRING', String, 'Configured pooler service name' c.option '--active', 'Prints information about active vms for a given token' c.option '--json', 'Prints information as JSON' + c.option '--hostnameonly', 'When listing active vms, prints only hostnames, one per line' c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' c.option '--user STRING', String, 'User to authenticate with' @@ -115,6 +116,10 @@ class Vmfloaty 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) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index f6d69ef..65cc053 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -84,6 +84,21 @@ class Utils os_types end + def self.print_fqdn_for_host(service, hostname, host_data) + case service.type + when 'ABS' + host_data['allocated_resources'].each do |vm_name, _i| + puts vm_name['hostname'] + end + when 'Pooler' + puts "#{hostname}.#{host_data['domain']}" + when 'NonstandardPooler' + puts host_data['fqdn'] + else + raise "Invalid service type #{service.type}" + end + end + def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false, indent = 0) output_target = print_to_stderr ? $stderr : $stdout diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 3941eb2..48f6a3e 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -162,6 +162,89 @@ describe Utils do end end + describe '#print_fqdn_for_host' do + let(:url) { 'http://pooler.example.com' } + + subject { Utils.print_fqdn_for_host(service, hostname, host_data) } + + describe 'with vmpooler host' do + let(:service) { Service.new(MockOptions.new, 'url' => url) } + let(:hostname) { 'mcpy42eqjxli9g2' } + let(:domain) { 'delivery.mycompany.net' } + let(:fqdn) { [hostname, domain].join('.') } + + let(:host_data) do + { + 'template' => 'ubuntu-1604-x86_64', + 'lifetime' => 12, + '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) + + subject + end + end + + describe 'with nonstandard pooler host' do + let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') } + 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, + } + end + let(:fqdn) { hostname } # for nspooler these are the same + + it 'outputs fqdn for host' do + expect(STDOUT).to receive(:puts).with(fqdn) + + subject + end + end + + describe 'with ABS host' do + let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') } + let(:hostname) { '1597952189390' } + let(:fqdn) { 'example-noun.delivery.puppetlabs.net' } + let(:template) { 'ubuntu-1604-x86_64' } + + # This seems to be the miminal stub response from ABS for the current output + let(:host_data) do + { + 'state' => 'allocated', + 'allocated_resources' => [ + { + 'hostname' => fqdn, + 'type' => template, + 'enging' => 'vmpooler', + }, + ], + 'request' => { + 'job' => { + 'id' => hostname, + } + }, + } + end + + it 'outputs fqdn for host' do + expect(STDOUT).to receive(:puts).with(fqdn) + + subject + end + end + end + describe '#pretty_print_hosts' do let(:url) { 'http://pooler.example.com' } From 57e7542f7312676f77f7aa86a6edd1f3ef34c667 Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Fri, 21 Aug 2020 11:46:10 -0700 Subject: [PATCH 144/265] Add tab completion script for zsh This commit adds a new tab completion script for zsh. It also fixes the completion script for bash to work with ABS backends. --- extras/completions/floaty.bash | 2 +- extras/completions/floaty.zsh | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 extras/completions/floaty.zsh diff --git a/extras/completions/floaty.bash b/extras/completions/floaty.bash index 5adee75..0c18c49 100644 --- a/extras/completions/floaty.bash +++ b/extras/completions/floaty.bash @@ -21,7 +21,7 @@ _vmfloaty() COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") ) elif [[ $hostname_subcommands =~ (^| )$prev($| ) ]] ; then - _vmfloaty_active_hostnames=$(floaty list --active 2>/dev/null | grep '^-' | cut -d' ' -f2) + _vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null) COMPREPLY=( $(compgen -W "${_vmfloaty_active_hostnames}" -- "${cur}") ) else COMPREPLY=( $(compgen -W "${subcommands}" -- "${cur}") ) diff --git a/extras/completions/floaty.zsh b/extras/completions/floaty.zsh new file mode 100644 index 0000000..77edf17 --- /dev/null +++ b/extras/completions/floaty.zsh @@ -0,0 +1,37 @@ +_floaty() +{ + local line subcommands template_subcommands hostname_subcommands + + subcommands="delete get help list modify query revert snapshot ssh status summary token" + + template_subcommands=("get" "ssh") + hostname_subcommands=("delete" "modify" "query" "revert" "snapshot") + + _arguments -C \ + "1: :(${subcommands})" \ + "*::arg:->args" + + if ((template_subcommands[(Ie)$line[1]])); then + _floaty_template_sub + elif ((hostname_subcommands[(Ie)$line[1]])); then + _floaty_hostname_sub + fi +} + +_floaty_template_sub() +{ + if [[ -z "$_vmfloaty_avail_templates" ]] ; then + _vmfloaty_avail_templates=$(floaty list 2>/dev/null) + fi + + _arguments "1: :(${_vmfloaty_avail_templates})" +} + +_floaty_hostname_sub() +{ + _vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null) + + _arguments "1: :(${_vmfloaty_active_hostnames})" +} + +compdef _floaty floaty From dee735e017cc709cea06d2a107f14f49b66a4fde Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Mon, 24 Aug 2020 16:22:03 -0700 Subject: [PATCH 145/265] (FIXUP) Collect hostnames in array before outputting --- lib/vmfloaty/utils.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 65cc053..1f2418a 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -87,9 +87,13 @@ class Utils def self.print_fqdn_for_host(service, hostname, host_data) case service.type when 'ABS' + abs_hostnames = [] + host_data['allocated_resources'].each do |vm_name, _i| - puts vm_name['hostname'] + abs_hostnames << vm_name['hostname'] end + + puts abs_hostnames.join("\n") when 'Pooler' puts "#{hostname}.#{host_data['domain']}" when 'NonstandardPooler' From e269d71fea047c9c6afafa12b810041eb643a6a6 Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Mon, 21 Sep 2020 16:58:50 -0700 Subject: [PATCH 146/265] Add README for zsh tab completion --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 83e94cc..54e246e 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,12 @@ If you are running on macOS and use Homebrew's `bash-completion` formula, you ca ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty ``` +There is also tab completion for zsh: + +```zsh +source $(floaty completion --shell zsh) +``` + ## vmpooler API This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md). From 8546c1c4b67cae464ecf96baa29112e342dbe4d9 Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Mon, 21 Sep 2020 16:59:04 -0700 Subject: [PATCH 147/265] WIP: fixup specs after rebase --- spec/vmfloaty/utils_spec.rb | 240 +++++++++++++++++++++++++----------- 1 file changed, 169 insertions(+), 71 deletions(-) diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 48f6a3e..af3a3fa 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -247,95 +247,193 @@ describe Utils do describe '#pretty_print_hosts' do let(:url) { 'http://pooler.example.com' } + let(:verbose) { nil } + let(:print_to_stderr) { false } - it 'prints a vmpooler output with host fqdn, template and duration info' do - hostname = 'mcpy42eqjxli9g2' - response_body = { hostname => { - 'template' => 'ubuntu-1604-x86_64', - 'lifetime' => 12, - 'running' => 9.66, - 'state' => 'running', - 'ip' => '127.0.0.1', - 'domain' => 'delivery.mycompany.net', - } } - output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)' - - expect(STDOUT).to receive(:puts).with(output) - - service = Service.new(MockOptions.new, 'url' => url) + before(:each) do allow(service).to receive(:query) - .with(nil, hostname) + .with(anything, hostname) .and_return(response_body) - - Utils.pretty_print_hosts(nil, service, hostname) end - it 'prints a vmpooler output with host fqdn, template, duration info, and tags when supplied' do - hostname = 'aiydvzpg23r415q' - response_body = { hostname => { - 'template' => 'redhat-7-x86_64', - 'lifetime' => 48, - 'running' => 7.67, - 'state' => 'running', - 'tags' => { - 'user' => 'bob', - 'role' => 'agent', - }, - 'ip' => '127.0.0.1', - 'domain' => 'delivery.mycompany.net', - } } - output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)' + subject { Utils.pretty_print_hosts(verbose, service, hostname, print_to_stderr) } - expect(STDOUT).to receive(:puts).with(output) + describe 'with vmpooler service' do + let(:service) { Service.new(MockOptions.new, 'url' => url) } - service = Service.new(MockOptions.new, 'url' => url) - allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + let(:hostname) { 'mcpy42eqjxli9g2' } + let(:domain) { 'delivery.mycompany.net' } + let(:fqdn) { [hostname, domain].join('.') } - Utils.pretty_print_hosts(nil, service, hostname) + let(:response_body) do + { + hostname => { + 'template' => 'ubuntu-1604-x86_64', + 'lifetime' => 12, + 'running' => 9.66, + 'state' => 'running', + 'ip' => '127.0.0.1', + 'domain' => domain, + } + } + end + + let(:default_output) { "- #{fqdn} (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) + + subject + end + + context 'when tags are supplied' do + let(:hostname) { 'aiydvzpg23r415q' } + let(:response_body) do + { + hostname => { + 'template' => 'redhat-7-x86_64', + 'lifetime' => 48, + 'running' => 7.67, + 'state' => 'running', + 'tags' => { + 'user' => 'bob', + 'role' => 'agent', + }, + 'ip' => '127.0.0.1', + 'domain' => domain, + } + } + end + + it 'prints output with host fqdn, template, duration info, and tags' do + output = "- #{fqdn} (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" + + expect(STDOUT).to receive(:puts).with(output) + + subject + end + end + + context 'when print_to_stderr option is true' do + let(:print_to_stderr) { true } + + it 'outputs to stderr instead of stdout' do + expect(STDERR).to receive(:puts).with(default_output) + + subject + end + end end - it 'prints a nonstandard pooler output with host, template, and time remaining' do - hostname = 'sol11-9.delivery.mycompany.net' - response_body = { hostname => { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => '', - 'hours_left_on_reservation' => 35.89, - } } - output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)' + describe 'with nonstandard pooler service' do + let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') } - expect(STDOUT).to receive(:puts).with(output) + let(:hostname) { 'sol11-9.delivery.mycompany.net' } + 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, + } + } + end - service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') - allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + let(:default_output) { "- #{hostname} (solaris-11-sparc, 35.89h remaining)" } - Utils.pretty_print_hosts(nil, service, hostname) + it 'prints output with host, template, and time remaining' do + expect(STDOUT).to receive(:puts).with(default_output) + + subject + end + + context 'when reason is supplied' 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, + } + } + end + + 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) + + subject + end + end + + context 'when print_to_stderr option is true' do + let(:print_to_stderr) { true } + + it 'outputs to stderr instead of stdout' do + expect(STDERR).to receive(:puts).with(default_output) + + subject + end + end end - it 'prints a nonstandard pooler output with host, template, time remaining, and reason' do - hostname = 'sol11-9.delivery.mycompany.net' - response_body = { hostname => { - 'fqdn' => hostname, - 'os_triple' => 'solaris-11-sparc', - 'reserved_by_user' => 'first.last', - 'reserved_for_reason' => 'testing', - 'hours_left_on_reservation' => 35.89, - } } - output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)' + describe 'with ABS service' do + let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') } - expect(STDOUT).to receive(:puts).with(output) + let(:hostname) { '1597952189390' } + let(:fqdn) { 'example-noun.delivery.puppetlabs.net' } + let(:template) { 'ubuntu-1604-x86_64' } - service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') - allow(service).to receive(:query) - .with(nil, hostname) - .and_return(response_body) + # 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', + }, + ], + 'request' => { + 'job' => { + 'id' => hostname, + } + }, + } + } + end - Utils.pretty_print_hosts(nil, service, hostname) + let(:default_output) { "- [JobID:#{hostname}] #{fqdn} (#{template}) " } + + before(:each) do + allow(Utils).to receive(:get_vmpooler_service_config).and_return({ + 'url' => 'http://vmpooler.example.com', + 'token' => 'krypto-knight' + }) + end + + it 'prints output with job id, host, and template' do + expect(STDOUT).to receive(:puts).with(default_output) + + subject + end + + context 'when print_to_stderr option is true' do + let(:print_to_stderr) { true } + + it 'outputs to stderr instead of stdout' do + expect(STDERR).to receive(:puts).with(default_output) + + subject + end + end end end From 45f0ef031edde2e2da95f5a896f73844a7725334 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Tue, 22 Sep 2020 09:15:15 -0500 Subject: [PATCH 148/265] Fix spec tests for ABS pretty print ABS now returns the ABS job_id on the first line, then every vmpooler hostname indented. It queries them from vmpooler to get the metadata like lifetime etc --- spec/vmfloaty/utils_spec.rb | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index af3a3fa..561c38b 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -387,6 +387,7 @@ describe Utils do let(:hostname) { '1597952189390' } let(:fqdn) { 'example-noun.delivery.puppetlabs.net' } + 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 @@ -410,17 +411,41 @@ describe Utils do } end - let(:default_output) { "- [JobID:#{hostname}] #{fqdn} (#{template}) " } + # The vmpooler response contains metadata that is printed + let(:domain) { 'delivery.mycompany.net' } + let(:response_body_vmpooler) do + { + fqdn_hostname => { + 'template' => 'redhat-7-x86_64', + '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' }) + allow(service).to receive(:query) + .with(anything, fqdn_hostname) + .and_return(response_body_vmpooler) end + let(:default_output_first_line) { "- [JobID:#{hostname}] " } + let(:default_output_second_line) { " - example-noun.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" } + it 'prints output with job id, host, and template' do - expect(STDOUT).to receive(:puts).with(default_output) + expect(STDOUT).to receive(:puts).with(default_output_first_line) + expect(STDOUT).to receive(:puts).with(default_output_second_line) subject end @@ -429,7 +454,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) + expect(STDERR).to receive(:puts).with(default_output_first_line) + expect(STDERR).to receive(:puts).with(default_output_second_line) subject end From 2b56448d50b0d4fbddcae72c4ac08d9ae760ea93 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Tue, 22 Sep 2020 09:53:13 -0500 Subject: [PATCH 149/265] Fix pretty print when multiple backend services are returned by ABS. Added test with vmpooler and nspooler result --- lib/vmfloaty/utils.rb | 16 +++--- spec/vmfloaty/utils_spec.rb | 97 +++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 9 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 1f2418a..a569415 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -114,13 +114,17 @@ class Utils # # Create a vmpooler service to query each hostname there so as to get the metadata too - vmpooler_service = service.clone - vmpooler_service.silent = true - vmpooler_service.maybe_use_vmpooler output_target.puts "- [JobID:#{host_data['request']['job']['id']}] <#{host_data['state']}>" - - host_data['allocated_resources'].each do |vm_name, _i| - self.pretty_print_hosts(verbose, vmpooler_service, vm_name['hostname'].split('.')[0], print_to_stderr, indent+2) + host_data['allocated_resources'].each do |allocated_resources, _i| + if allocated_resources['engine'] == "vmpooler" + 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) + else + #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 when 'Pooler' tag_pairs = [] diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 561c38b..e26e0f1 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -386,7 +386,7 @@ describe Utils do let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') } let(:hostname) { '1597952189390' } - let(:fqdn) { 'example-noun.delivery.puppetlabs.net' } + let(:fqdn) { 'example-noun.delivery.mycompany.net' } let(:fqdn_hostname) {'example-noun'} let(:template) { 'ubuntu-1604-x86_64' } @@ -416,7 +416,7 @@ describe Utils do let(:response_body_vmpooler) do { fqdn_hostname => { - 'template' => 'redhat-7-x86_64', + 'template' => template, 'lifetime' => 48, 'running' => 7.67, 'state' => 'running', @@ -441,7 +441,7 @@ describe Utils do end let(:default_output_first_line) { "- [JobID:#{hostname}] " } - let(:default_output_second_line) { " - example-noun.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" } + let(:default_output_second_line) { " - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" } it 'prints output with job id, host, and template' do expect(STDOUT).to receive(:puts).with(default_output_first_line) @@ -461,6 +461,97 @@ describe Utils do end end end + + describe 'with ABS service returning vmpooler and nspooler resources' do + let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') } + + 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(: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, + } + }, + } + } + end + + # The vmpooler response contains metadata that is printed + 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, + } + } + end + + before(:each) do + allow(Utils).to receive(:get_vmpooler_service_config).and_return({ + 'url' => 'http://vmpooler.example.com', + 'token' => 'krypto-knight' + }) + allow(service).to receive(:query) + .with(anything, fqdn_hostname) + .and_return(response_body_vmpooler) + end + + let(:default_output_first_line) { "- [JobID:#{hostname}] " } + let(:default_output_second_line) { " - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" } + 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) + + subject + end + + context 'when print_to_stderr option is true' 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) + + subject + end + end + end end describe '#get_vmpooler_service_config' do From d9b5bb5e892bad38c2ce9551412d274c3b271dcc Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Tue, 22 Sep 2020 12:02:56 -0400 Subject: [PATCH 150/265] Bump to version 1.0.0 --- lib/vmfloaty/version.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 81d81fd..18711c4 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '0.11.1' + VERSION = '1.0.0' end + From c5b9e1d184e122add1172c8382ac2b38ed8f716a Mon Sep 17 00:00:00 2001 From: Jesse Scott Date: Tue, 22 Sep 2020 12:07:11 -0700 Subject: [PATCH 151/265] Update completion scripts for `service` subcommands --- extras/completions/floaty.bash | 24 ++++++++++++++++-------- extras/completions/floaty.zsh | 20 +++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/extras/completions/floaty.bash b/extras/completions/floaty.bash index 0c18c49..17a5b24 100644 --- a/extras/completions/floaty.bash +++ b/extras/completions/floaty.bash @@ -2,29 +2,37 @@ _vmfloaty() { - local cur prev subcommands template_subcommands hostname_subcommands + local cur prev commands template_arg_commands hostname_arg_commands service_subcommands + COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - subcommands="delete get help list modify query revert service snapshot ssh status summary token" - template_subcommands="get ssh" - hostname_subcommands="delete modify query revert snapshot" + commands="delete get help list modify query revert service snapshot ssh status summary token" + template_arg_commands="get ssh" + hostname_arg_commands="delete modify query revert snapshot" + service_subcommands="types examples" if [[ $cur == -* ]] ; then # TODO: option completion COMPREPLY=() - elif [[ $template_subcommands =~ (^| )$prev($| ) ]] ; then + elif [[ $template_arg_commands =~ (^| )$prev($| ) ]] ; then if [[ -z "$_vmfloaty_avail_templates" ]] ; then + # TODO: need a --hostnameonly equivalent here because the section headers of + # `floaty list` are adding some spurious entries (including files in current + # directory because part of the headers is `**` which is getting expanded) _vmfloaty_avail_templates=$(floaty list 2>/dev/null) fi COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") ) - elif [[ $hostname_subcommands =~ (^| )$prev($| ) ]] ; then + elif [[ $hostname_arg_commands =~ (^| )$prev($| ) ]] ; then _vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null) COMPREPLY=( $(compgen -W "${_vmfloaty_active_hostnames}" -- "${cur}") ) - else - COMPREPLY=( $(compgen -W "${subcommands}" -- "${cur}") ) + elif [[ "service" == $prev ]] ; then + COMPREPLY=( $(compgen -W "${service_subcommands}" -- "${cur}") ) + elif [[ $1 == $prev ]] ; then + # only show top level commands we are at root + COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) fi } complete -F _vmfloaty floaty diff --git a/extras/completions/floaty.zsh b/extras/completions/floaty.zsh index 77edf17..1dbc292 100644 --- a/extras/completions/floaty.zsh +++ b/extras/completions/floaty.zsh @@ -1,26 +1,32 @@ _floaty() { - local line subcommands template_subcommands hostname_subcommands + local line commands template_arg_commands hostname_arg_commands service_subcommands - subcommands="delete get help list modify query revert snapshot ssh status summary token" + commands="delete get help list modify query revert service snapshot ssh status summary token" - template_subcommands=("get" "ssh") - hostname_subcommands=("delete" "modify" "query" "revert" "snapshot") + template_arg_commands=("get" "ssh") + hostname_arg_commands=("delete" "modify" "query" "revert" "snapshot") + service_subcommands=("types" "examples") _arguments -C \ - "1: :(${subcommands})" \ + "1: :(${commands})" \ "*::arg:->args" - if ((template_subcommands[(Ie)$line[1]])); then + if ((template_arg_commands[(Ie)$line[1]])); then _floaty_template_sub - elif ((hostname_subcommands[(Ie)$line[1]])); then + elif ((hostname_arg_commands[(Ie)$line[1]])); then _floaty_hostname_sub + elif [[ "service" == $line[1] ]]; then + _arguments "1: :(${service_subcommands})" fi } _floaty_template_sub() { if [[ -z "$_vmfloaty_avail_templates" ]] ; then + # TODO: need a --hostnameonly equivalent here because the section headers of + # `floaty list` are adding some spurious entries (including files in current + # directory because part of the headers is `**` which is getting expanded) _vmfloaty_avail_templates=$(floaty list 2>/dev/null) fi From 5c8aa13081a6f00bebc80d56a9f4ec149ae22b3f Mon Sep 17 00:00:00 2001 From: Christopher Thorn Date: Wed, 23 Sep 2020 15:06:24 -0700 Subject: [PATCH 152/265] (maint) Add vmpooler_fallback to the get service check Previously the vmpooler_fallback setting was not being recognizied, this PR will fix it. --- lib/vmfloaty/utils.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index a569415..5f43345 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -254,6 +254,7 @@ class Utils 'url' => config['url'], 'user' => config['user'], 'token' => config['token'], + 'vmpooler_fallback' => config['vmpooler_fallback'], 'type' => config['type'] || 'vmpooler', } From 3a60ffbdbd58daaa964c4b62bfa92e991681090c Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Thu, 24 Sep 2020 09:46:22 -0500 Subject: [PATCH 153/265] (maint) Don't require config file for list --active Will fallback to printing ABS information, which is less than what you get if vmpooler_fallback is available --- lib/vmfloaty/utils.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index a569415..5a2775b 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -116,7 +116,7 @@ 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" + if allocated_resources['engine'] == "vmpooler" && service.config["vmpooler_fallback"] vmpooler_service = service.clone vmpooler_service.silent = true vmpooler_service.maybe_use_vmpooler From 6deadb22674e8a1b0bee4a77b3547b161f78ce14 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Thu, 24 Sep 2020 10:00:15 -0500 Subject: [PATCH 154/265] Fix tests --- spec/vmfloaty/utils_spec.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index e26e0f1..a90d3b1 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -5,6 +5,11 @@ require 'json' require 'commander/command' require_relative '../../lib/vmfloaty/utils' +# allow changing config in service for tests +class Service + attr_writer :config +end + describe Utils do describe '#standardize_hostnames' do before :each do @@ -441,7 +446,7 @@ describe Utils do end let(:default_output_first_line) { "- [JobID:#{hostname}] " } - let(:default_output_second_line) { " - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" } + 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) @@ -450,6 +455,16 @@ describe Utils do 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'} + service.config.merge! fallback + default_output_second_line=" - #{fqdn} (#{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 + context 'when print_to_stderr option is true' do let(:print_to_stderr) { true } @@ -529,7 +544,7 @@ describe Utils do end let(:default_output_first_line) { "- [JobID:#{hostname}] " } - let(:default_output_second_line) { " - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" } + let(:default_output_second_line) { " - #{fqdn} (#{template})" } let(:default_output_third_line) { " - #{fqdn_ns} (#{template_ns})" } it 'prints output with job id, host, and template' do From 56f0896d48c6e23dc22e3a935ac918673f1b4980 Mon Sep 17 00:00:00 2001 From: Nate Wolfe Date: Wed, 23 Sep 2020 15:52:32 -0700 Subject: [PATCH 155/265] (maint) Don't require configuration file for get Make the vmpooler_fallback optional for cases when there's no configuration file and everything is specified on the CLI invocation. --- lib/vmfloaty/abs.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 2426c32..a2bb6bc 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -249,7 +249,6 @@ class ABS conn.headers['X-AUTH-TOKEN'] = token if token saved_job_id = DateTime.now.strftime('%Q') - vmpooler_config = Utils.get_vmpooler_service_config(config['vmpooler_fallback']) req_obj = { :resources => os_types, :job => { @@ -258,9 +257,14 @@ class ABS :user => user, }, }, - :vm_token => vmpooler_config['token'] # request with this token, on behalf of this user } + if config['vmpooler_fallback'] + vmpooler_config = Utils.get_vmpooler_service_config(config['vmpooler_fallback']) + # request with this token, on behalf of this user + req_obj[:vm_token] = vmpooler_config['token'] + end + if config['priority'] req_obj[:priority] = if config['priority'] == 'high' 1 From fbd98f93aefc722a3821401a07bbbef1ff15b89d Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 9 Oct 2020 10:18:53 -0500 Subject: [PATCH 156/265] (maint) Fix bug with detecting ABS service Before this change the code would try to check if an object was ABS by using is_a? which is only for instances of a class. It also compared with ABS.class which returns the Class class. Now fixed by comparing the object to the static class --- lib/vmfloaty/service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index a0303c4..ee41648 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -139,7 +139,7 @@ class Service # some methods do not exist for ABS, and if possible should target the Pooler service def maybe_use_vmpooler - if @service_object.is_a?(ABS.class) + 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" self.silent = true From e0fac0bb6c9ee7771f506b1a98cd9a9d0eba793f Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 9 Oct 2020 10:23:23 -0500 Subject: [PATCH 157/265] (maint) Add more uniqueness to jobid Before this change there was a non zero chance that two requests could be received at the same millisecond and have the same jobid. Added the username as a prefix to the job id --- lib/vmfloaty/abs.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 2426c32..1d1755a 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -248,7 +248,7 @@ class ABS conn = Http.get_conn(verbose, url) conn.headers['X-AUTH-TOKEN'] = token if token - saved_job_id = DateTime.now.strftime('%Q') + saved_job_id = user + "-" + DateTime.now.strftime('%Q') vmpooler_config = Utils.get_vmpooler_service_config(config['vmpooler_fallback']) req_obj = { :resources => os_types, From 671623bc4f13d77ff91c2b755560520cdd6c5f0f Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 9 Oct 2020 10:37:16 -0500 Subject: [PATCH 158/265] handle ctrl-c and term signal and return useful message on how to query ABS for the state of the request or to delete it --- lib/vmfloaty/abs.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 1d1755a..4eb657e 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -284,15 +284,20 @@ class ABS validate_queue_status_response(res.status, res.body, "Initial request", verbose) - (1..retries).each do |i| - queue_place, res_body = check_queue(conn, saved_job_id, req_obj, verbose) - return translated(res_body, saved_job_id) if res_body + begin + (1..retries).each do |i| + queue_place, res_body = check_queue(conn, saved_job_id, req_obj, verbose) + return translated(res_body, saved_job_id) if res_body - sleep_seconds = 10 if i >= 10 - sleep_seconds = i if i < 10 - FloatyLogger.info "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + sleep_seconds = 10 if i >= 10 + sleep_seconds = i if i < 10 + FloatyLogger.info "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" - sleep(sleep_seconds) + sleep(sleep_seconds) + end + rescue SystemExit, Interrupt + FloatyLogger.info "\n\nFloaty interrupted, you can query the state of your request via\n1) `floaty query #{saved_job_id}` or delete it via\n2) `floaty delete #{saved_job_id}`" + exit 1 end nil end From 846cc7050c9d46eb966d3976612efd1601309daa Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 16 Oct 2020 13:14:57 -0500 Subject: [PATCH 159/265] when missing, adds the api/v2 to the url endpoint --- lib/vmfloaty/abs.rb | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 42c1df0..873a0e0 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -64,7 +64,7 @@ class ABS end def self.get_active_requests(verbose, url, user) - conn = Http.get_conn(verbose, url) + conn = Http.get_conn(verbose, supported_abs_url(url)) res = conn.get 'status/queue' if valid_json?(res.body) requests = JSON.parse(res.body) @@ -105,7 +105,7 @@ class ABS def self.delete(verbose, url, hosts, token, user) # In ABS terms, this is a "returned" host. - conn = Http.get_conn(verbose, url) + conn = Http.get_conn(verbose, supported_abs_url(url)) conn.headers['X-AUTH-TOKEN'] = token if token FloatyLogger.info "Trying to delete hosts #{hosts}" if verbose @@ -163,7 +163,7 @@ class ABS # List available VMs in ABS def self.list(verbose, url, os_filter = nil) - conn = Http.get_conn(verbose, url) + conn = Http.get_conn(verbose, supported_abs_url(url)) os_list = [] @@ -245,7 +245,7 @@ class ABS # } # } - conn = Http.get_conn(verbose, url) + conn = Http.get_conn(verbose, supported_abs_url(url)) conn.headers['X-AUTH-TOKEN'] = token if token saved_job_id = user + "-" + DateTime.now.strftime('%Q') @@ -348,7 +348,7 @@ class ABS end def self.status(verbose, url) - conn = Http.get_conn(verbose, url) + conn = Http.get_conn(verbose, supported_abs_url(url)) res = conn.get 'status' @@ -366,7 +366,7 @@ class ABS return @active_hostnames if @active_hostnames && !@active_hostnames.empty? # If using the cli query job_id - conn = Http.get_conn(verbose, url) + conn = Http.get_conn(verbose, supported_abs_url(url)) queue_info_res = conn.get "status/queue/info/#{job_id}" if valid_json?(queue_info_res.body) queue_info = JSON.parse(queue_info_res.body) @@ -411,4 +411,15 @@ class ABS rescue TypeError, JSON::ParserError => e return 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) + # add a slash if missing + expected_ending = "/#{expected_ending}" if url[-1] != "/" + url = "#{url}#{expected_ending}" + end + url + end end From ced6b46032dc9d0d9b1323cd038fc3f9e7884603 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 16 Oct 2020 13:15:15 -0500 Subject: [PATCH 160/265] (v1.1.1) Prepare for pushing the gem to rubygems --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 18711c4..c991fab 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.0.0' + VERSION = '1.1.1' end From 4aa78a1b66ae8af9ab1c118fa85552cef3391d67 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Fri, 16 Oct 2020 13:23:50 -0500 Subject: [PATCH 161/265] fix tests --- spec/vmfloaty/abs_spec.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index 40804cf..d6eabfc 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -11,11 +11,11 @@ describe ABS do describe '#list' do it 'skips empty platforms and lists aws' do - stub_request(:get, "http://foo/status/platforms/vmpooler"). + stub_request(:get, "http://foo/api/v2/status/platforms/vmpooler"). to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/status/platforms/ondemand_vmpooler"). + stub_request(:get, "http://foo/api/v2/status/platforms/ondemand_vmpooler"). to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/status/platforms/nspooler"). + stub_request(:get, "http://foo/api/v2/status/platforms/nspooler"). to_return(:status => 200, :body => "", :headers => {}) body = '{ "aws_platforms": [ @@ -26,7 +26,7 @@ describe ABS do "redhat-8-arm64" ] }' - stub_request(:get, "http://foo/status/platforms/aws"). + stub_request(:get, "http://foo/api/v2/status/platforms/aws"). to_return(:status => 200, :body => body, :headers => {}) @@ -35,16 +35,16 @@ describe ABS do 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/status/platforms/vmpooler"). + stub_request(:get, "http://foo/api/v2/status/platforms/vmpooler"). to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/status/platforms/ondemand_vmpooler"). + stub_request(:get, "http://foo/api/v2/status/platforms/ondemand_vmpooler"). to_return(:status => 200, :body => "", :headers => {}) - stub_request(:get, "http://foo/status/platforms/nspooler"). + 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/status/platforms/aws"). + stub_request(:get, "http://foo/api/v2/status/platforms/aws"). to_return(:status => 200, :body => body, :headers => {}) results = ABS.list(false, "http://foo") @@ -125,7 +125,7 @@ describe ABS do end it 'will skip a line with a null value returned from abs' do - stub_request(:get, 'https://abs.example.com/status/queue') + stub_request(:get, 'https://abs.example.com/api/v2/status/queue') .to_return(:status => 200, :body => @active_requests_response, :headers => {}) ret = ABS.get_active_requests(false, @abs_url, @test_user) @@ -156,9 +156,9 @@ describe ABS do end it 'will delete the whole job' do - stub_request(:get, 'https://abs.example.com/status/queue') + stub_request(:get, 'https://abs.example.com/api/v2/status/queue') .to_return(:status => 200, :body => @active_requests_response, :headers => {}) - stub_request(:post, 'https://abs.example.com/return') + stub_request(:post, 'https://abs.example.com/api/v2/return') .with(:body => @return_request) .to_return(:status => 200, :body => 'OK', :headers => {}) From c969e9c55215c0bfa28ca682ad33a23c14c7fcc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Nov 2020 13:03:24 +0000 Subject: [PATCH 162/265] Update rspec requirement from ~> 3.9.0 to ~> 3.10.0 Updates the requirements on [rspec](https://github.com/rspec/rspec) to permit the latest version. - [Release notes](https://github.com/rspec/rspec/releases) - [Commits](https://github.com/rspec/rspec/compare/v3.9.0...v3.10.0) Signed-off-by: dependabot[bot] --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b8bcc0f..31842ef 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,7 @@ group :test do gem 'coveralls', '~> 0.8.23' gem 'pry' gem 'rb-readline' - gem 'rspec', '~> 3.9.0' + gem 'rspec', '~> 3.10.0' gem 'rubocop', '~> 0.52' gem 'webmock', '1.21.0' end From d4c2795df0bb0ce2c07a1bdfd480de623df93125 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Dec 2020 13:04:56 +0000 Subject: [PATCH 163/265] Update rubocop requirement from ~> 0.52 to ~> 1.6 Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version. - [Release notes](https://github.com/rubocop-hq/rubocop/releases) - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.52.0...v1.6.0) Signed-off-by: dependabot[bot] --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b8bcc0f..229a437 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.9.0' - gem 'rubocop', '~> 0.52' + gem 'rubocop', '~> 1.6' gem 'webmock', '1.21.0' end From a3d848412484242fdd68a8ef571ba0184c04761a Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Tue, 9 Feb 2021 11:29:08 -0600 Subject: [PATCH 164/265] (DIO-908) Floaty can now report the status of ABS requests - If ABS queries returns a body for 200 or 202, floaty will print it this is useful in the new version of ABS, since it shows the progress for ondemand requests (AWS or vmpooler) - removed the queue_place and querying the queue for a 'get' request this queue_place number was misleading since it was just a redis index and did not represent well where the request was in the queue - Also added a flag option --continue to be used when the cli was interrupted for example with ctrl-c --- lib/vmfloaty.rb | 13 +++++----- lib/vmfloaty/abs.rb | 38 ++++++++++++++---------------- lib/vmfloaty/nonstandard_pooler.rb | 2 +- lib/vmfloaty/pooler.rb | 2 +- lib/vmfloaty/service.rb | 4 ++-- lib/vmfloaty/utils.rb | 2 +- 6 files changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 7d015f3..cd654f7 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -39,6 +39,7 @@ class Vmfloaty c.option '--force', 'Forces vmfloaty to get requested vms' c.option '--json', 'Prints retrieved vms in JSON format' c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID' + c.option '--continue STRING', String, 'resume polling ABS for job_id, for use when the cli was interrupted' c.action do |args, options| verbose = options.verbose || config['verbose'] service = Service.new(options, config) @@ -52,6 +53,11 @@ class Vmfloaty os_types = Utils.generate_os_hash(args) + if os_types.empty? + FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' + exit 1 + end + max_pool_request = 5 large_pool_requests = os_types.select { |_, v| v > max_pool_request } if !large_pool_requests.empty? && !force @@ -60,12 +66,7 @@ class Vmfloaty exit 1 end - if os_types.empty? - FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.' - exit 1 - end - - response = service.retrieve(verbose, os_types, use_token, options.ondemand) + response = service.retrieve(verbose, os_types, use_token, options.ondemand, options.continue) request_id = response['request_id'] if options.ondemand response = service.wait_for_request(verbose, request_id) if options.ondemand diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 873a0e0..08027b7 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -228,7 +228,7 @@ class ABS end # Retrieve an OS from ABS. - def self.retrieve(verbose, os_types, token, url, user, config, _ondemand = nil) + def self.retrieve(verbose, os_types, token, url, user, config, _ondemand = nil, continue = nil) # # Contents of post must be like: # @@ -248,7 +248,12 @@ class ABS conn = Http.get_conn(verbose, supported_abs_url(url)) conn.headers['X-AUTH-TOKEN'] = token if token - saved_job_id = user + "-" + DateTime.now.strftime('%Q') + if continue.nil? + saved_job_id = user + "-" + DateTime.now.strftime('%Q') + else + saved_job_id = continue + end + req_obj = { :resources => os_types, :job => { @@ -281,26 +286,28 @@ class ABS # os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+') # raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty? - FloatyLogger.info "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour." + FloatyLogger.info "Requesting VMs with job_id: #{saved_job_id} Will retry for up to an hour." res = conn.post 'request', req_obj.to_json retries = 360 - 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| - queue_place, res_body = check_queue(conn, saved_job_id, req_obj, verbose) - return translated(res_body, saved_job_id) if res_body + 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 sleep_seconds = 10 if i >= 10 sleep_seconds = i if i < 10 - FloatyLogger.info "Waiting #{sleep_seconds} seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})" + FloatyLogger.info "Waiting #{sleep_seconds}s (x#{i}) #{res_body.strip}" sleep(sleep_seconds) end rescue SystemExit, Interrupt - FloatyLogger.info "\n\nFloaty interrupted, you can query the state of your request via\n1) `floaty query #{saved_job_id}` or delete it via\n2) `floaty delete #{saved_job_id}`" + FloatyLogger.info "\n\nFloaty interrupted, you can resume polling with\n1) `floaty get [same arguments] and adding the flag --continue #{saved_job_id}` or query the state of the queue via\n2) `floaty query #{saved_job_id}` or delete it via\n3) `floaty delete #{saved_job_id}`" exit 1 end nil @@ -325,22 +332,13 @@ class ABS end def self.check_queue(conn, job_id, req_obj, verbose) - queue_info_res = conn.get "status/queue/info/#{job_id}" - if valid_json?(queue_info_res.body) - queue_info = JSON.parse(queue_info_res.body) - else - FloatyLogger.warn "Could not parse the status/queue/info/#{job_id}" - return [nil, nil] - end - res = conn.post 'request', req_obj.to_json - 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 queue_info['queue_place'], res_body + return res_body end - [queue_info['queue_place'], nil] + res.body end def self.snapshot(_verbose, _url, _hostname, _token) diff --git a/lib/vmfloaty/nonstandard_pooler.rb b/lib/vmfloaty/nonstandard_pooler.rb index 5d755a9..0746034 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) + 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 diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index fb811cf..5b5f65c 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -28,7 +28,7 @@ class Pooler vms end - def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil) + def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil, _continue = nil) # NOTE: # Developers can use `Utils.generate_os_hash` to # generate the os_type param. diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index ee41648..196ac4c 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -77,10 +77,10 @@ class Service @service_object.list_active verbose, url, token, user end - def retrieve(verbose, os_types, use_token = true, ondemand = nil) + def retrieve(verbose, os_types, use_token = true, ondemand = nil, continue = nil) FloatyLogger.info 'Requesting a vm without a token...' unless use_token token_value = use_token ? token : nil - @service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand + @service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand, continue end def wait_for_request(verbose, requestid) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index e3408f3..a356ec3 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -116,7 +116,7 @@ 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" && 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 From 4192631d70e681331886965a33e92b89e07bd829 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Tue, 9 Feb 2021 15:38:43 -0600 Subject: [PATCH 165/265] (DIO-908) Adding a way to set Logger level via --loglevel this is specially useful if you also use in combination --json to remove superfluous stdout --- lib/vmfloaty.rb | 17 +++++++++++++++++ lib/vmfloaty/logger.rb | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index cd654f7..0e1bad5 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -40,8 +40,12 @@ class Vmfloaty c.option '--json', 'Prints retrieved vms in JSON format' c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID' c.option '--continue STRING', String, 'resume polling ABS for job_id, for use when the cli was interrupted' + 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 service = Service.new(options, config) use_token = !options.notoken force = options.force @@ -93,8 +97,12 @@ class Vmfloaty c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' c.option '--user STRING', String, 'User to authenticate with' + 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 service = Service.new(options, config) filter = args[0] @@ -230,8 +238,13 @@ class Vmfloaty c.option '--token STRING', String, 'Token for pooler service' c.option '--url STRING', String, 'URL of pooler service' c.option '--user STRING', String, 'User to authenticate with' + 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 + service = Service.new(options, config) hostnames = args[0] delete_all = options.all @@ -375,8 +388,12 @@ class Vmfloaty c.option '--service STRING', String, 'Configured pooler service name' c.option '--url STRING', String, 'URL of pooler service' c.option '--json', 'Prints status in JSON format' + 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 service = Service.new(options, config) if options.json pp service.status(verbose) diff --git a/lib/vmfloaty/logger.rb b/lib/vmfloaty/logger.rb index d669d78..88bf5f1 100644 --- a/lib/vmfloaty/logger.rb +++ b/lib/vmfloaty/logger.rb @@ -17,6 +17,19 @@ class FloatyLogger < ::Logger FloatyLogger.logger.error msg end + 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 + else + error("set loglevel to debug, info or error") + end + end + def initialize super(STDERR) self.level = ::Logger::INFO From a9c8d17e9a053ec25d9b65f15fc515b9698721e1 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Thu, 11 Feb 2021 10:16:21 -0500 Subject: [PATCH 166/265] Release prep for 1.2.0 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index c991fab..d74edd1 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.1.1' + VERSION = '1.2.0' end From 8143641f831bb075286ca4debdfe4fa035774997 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Thu, 25 Feb 2021 10:04:30 -0600 Subject: [PATCH 167/265] (DIO-1522) Show the VM state (running, destroyed) and colorize in red when it has been deleted the ABS system does not have a real sense of the current state of the resources it has allocated. When running list --active it can list VMs that have been deleted or reaped after their lifetime expired. This change enables to show more information when a vmpooler_fallback service is provided to ABS, and will show the state (running, destroyed) and colorize in red when the VM is destroyed. --- lib/vmfloaty/utils.rb | 9 +++++++-- spec/vmfloaty/utils_spec.rb | 17 ++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index a356ec3..113a6da 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -130,8 +130,13 @@ class Utils tag_pairs = [] tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" - metadata = [host_data['template'], duration, *tag_pairs] - output_target.puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) + 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" + output_target.puts message.colorize(:red) + else + output_target.puts message + end when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index a90d3b1..ab5846e 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -283,7 +283,7 @@ describe Utils do } end - let(:default_output) { "- #{fqdn} (ubuntu-1604-x86_64, 9.66/12 hours)" } + 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) @@ -311,7 +311,7 @@ describe Utils do end it 'prints output with host fqdn, template, duration info, and tags' do - output = "- #{fqdn} (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" + output = "- #{fqdn} (running, redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" expect(STDOUT).to receive(:puts).with(output) @@ -458,13 +458,24 @@ describe Utils do it 'prints more information when vmpooler_fallback is set output with job id, host, template, lifetime, user and role' do fallback = {'vmpooler_fallback' => 'vmpooler'} service.config.merge! fallback - default_output_second_line=" - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" + 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'} + 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) + + subject + end + context 'when print_to_stderr option is true' do let(:print_to_stderr) { true } From eb99ba1dec39d1a76af3340725098a4d5bb5fe68 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Thu, 25 Feb 2021 13:38:11 -0600 Subject: [PATCH 168/265] Run the rubocop auto_correct fixed 27 files inspected, 975 offenses detected, 804 offenses corrected --- Gemfile | 2 +- Rakefile | 2 +- lib/vmfloaty.rb | 106 ++++--- lib/vmfloaty/abs.rb | 101 ++++--- lib/vmfloaty/http.rb | 8 +- lib/vmfloaty/logger.rb | 23 +- lib/vmfloaty/nonstandard_pooler.rb | 5 +- lib/vmfloaty/pooler.rb | 43 ++- lib/vmfloaty/service.rb | 6 +- lib/vmfloaty/utils.rb | 121 ++++---- lib/vmfloaty/version.rb | 1 - spec/spec_helper.rb | 6 +- spec/vmfloaty/abs/auth_spec.rb | 19 +- spec/vmfloaty/abs_spec.rb | 91 +++--- spec/vmfloaty/auth_spec.rb | 15 +- spec/vmfloaty/nonstandard_pooler_spec.rb | 59 ++-- spec/vmfloaty/pooler_spec.rb | 55 ++-- spec/vmfloaty/service_spec.rb | 20 +- spec/vmfloaty/ssh_spec.rb | 6 +- spec/vmfloaty/utils_spec.rb | 334 ++++++++++++----------- vmfloaty.gemspec | 4 +- 21 files changed, 516 insertions(+), 511 deletions(-) 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' From 38f24f4ad1514cd8ef03b80fa80d9c5ad66d3020 Mon Sep 17 00:00:00 2001 From: Samuel Date: Wed, 3 Mar 2021 12:25:08 -0600 Subject: [PATCH 169/265] Release prep for v1.3.0 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index d74edd1..f07179f 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.2.0' + VERSION = '1.3.0' end From f6febc9b8f50eec7fa34ac220f299f712dc62205 Mon Sep 17 00:00:00 2001 From: Nick Burgan-Illig Date: Mon, 12 Jul 2021 17:32:12 +0000 Subject: [PATCH 170/265] (maint) Use latest Faraday/webmock, update specs This unpins Faraday and webmock, and updates specs so that the Faraday changes (primarily including auth in the header rather than in the URL) is reflected. --- Gemfile | 2 +- spec/spec_helper.rb | 17 +++++++++++++ spec/vmfloaty/abs/auth_spec.rb | 32 +++++++++++++++--------- spec/vmfloaty/abs_spec.rb | 8 ++++-- spec/vmfloaty/auth_spec.rb | 23 +++++++++++------ spec/vmfloaty/nonstandard_pooler_spec.rb | 8 +++--- spec/vmfloaty/pooler_spec.rb | 4 +-- vmfloaty.gemspec | 2 +- 8 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Gemfile b/Gemfile index 042d6db..69ed407 100644 --- a/Gemfile +++ b/Gemfile @@ -12,5 +12,5 @@ group :test do gem 'rb-readline' gem 'rspec', '~> 3.10.0' gem 'rubocop', '~> 1.6' - gem 'webmock', '1.21.0' + gem 'webmock', '~> 3.13' end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6d17c36..750528d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,6 +2,7 @@ require 'simplecov' require 'coveralls' +require 'base64' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::HTMLFormatter, @@ -26,3 +27,19 @@ RSpec.configure do |config| config.tty = true config.formatter = :documentation end + +def get_headers(username: nil, password: nil, token: nil, content_type: nil, content_length: nil) + headers = { + 'Accept' => '*/*', + 'Accept-Encoding' => /gzip/, + 'User-Agent' => /Faraday/, + } + if username && password + auth = Base64.encode64("#{username}:#{password}").chomp + headers['Authorization'] = "Basic #{auth}" + end + headers['X-Auth-Token'] = token if token + headers['Content-Type'] = content_type if content_type + headers['Content-Length'] = content_length.to_s if content_length + headers +end \ No newline at end of file diff --git a/spec/vmfloaty/abs/auth_spec.rb b/spec/vmfloaty/abs/auth_spec.rb index fcf2392..ca1aec2 100644 --- a/spec/vmfloaty/abs/auth_spec.rb +++ b/spec/vmfloaty/abs/auth_spec.rb @@ -3,7 +3,11 @@ require 'spec_helper' require_relative '../../../lib/vmfloaty/auth' +user = 'first.last' +pass = 'password' + describe Pooler do + before :each do @abs_url = 'https://abs.example.com/api/v2' end @@ -15,18 +19,20 @@ describe Pooler do end it 'returns a token from abs' do - stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') + stub_request(:post, 'https://abs.example.com/api/v2/token') + .with(headers: get_headers(username: user, password: pass, content_length: 0)) .to_return(status: 200, body: @get_token_response, headers: {}) - token = Auth.get_token(false, @abs_url, 'first.last', 'password') + token = Auth.get_token(false, @abs_url, user, pass) expect(token).to eq @token end it 'raises a token error if something goes wrong' do - stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token') + stub_request(:post, 'https://abs.example.com/api/v2/token') + .with(headers: get_headers(username: user, password: pass, content_length: 0)) .to_return(status: 500, body: '{"ok":false}', headers: {}) - expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError) + expect { Auth.get_token(false, @abs_url, user, pass) }.to raise_error(TokenError) end end @@ -37,22 +43,24 @@ describe Pooler do end it 'deletes the specified token' do - stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + stub_request(:delete, 'https://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(headers: get_headers(username: user, password: pass)) .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, user, pass, + @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') + stub_request(:delete, 'https://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(headers: get_headers(username: user, password: pass)) .to_return(status: 500, body: '{"ok":false}', headers: {}) - expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError) + expect { Auth.delete_token(false, @abs_url, user, pass, @token) }.to raise_error(TokenError) end it 'raises a token error if no token provided' do - expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', nil) }.to raise_error(TokenError) + expect { Auth.delete_token(false, @abs_url, user, pass, nil) }.to raise_error(TokenError) end end @@ -64,7 +72,7 @@ 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' }) + .with(headers: get_headers) .to_return(status: 200, body: @token_status_response, headers: {}) expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response) @@ -72,7 +80,7 @@ describe Pooler do 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' }) + .with(headers: get_headers) .to_return(status: 500, body: '{"ok":false}', headers: {}) expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError) diff --git a/spec/vmfloaty/abs_spec.rb b/spec/vmfloaty/abs_spec.rb index 4199c53..4a66c5c 100644 --- a/spec/vmfloaty/abs_spec.rb +++ b/spec/vmfloaty/abs_spec.rb @@ -152,7 +152,11 @@ 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"}] + } # rubocop:enable Layout/LineLength @token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y' @test_user = 'test-user' @@ -164,7 +168,7 @@ describe ABS do stub_request(:get, 'https://abs.example.com/api/v2/status/queue') .to_return(status: 200, body: @active_requests_response, headers: {}) stub_request(:post, 'https://abs.example.com/api/v2/return') - .with(body: @return_request) + .with(headers: get_headers(content_type: 'application/x-www-form-urlencoded', token: @token), body: @return_request.to_json) .to_return(status: 200, body: 'OK', headers: {}) ret = ABS.delete(false, @abs_url, @hosts, @token, @test_user) diff --git a/spec/vmfloaty/auth_spec.rb b/spec/vmfloaty/auth_spec.rb index 80effe1..6ce4b77 100644 --- a/spec/vmfloaty/auth_spec.rb +++ b/spec/vmfloaty/auth_spec.rb @@ -3,6 +3,9 @@ require 'spec_helper' require_relative '../../lib/vmfloaty/auth' +user = 'first.last' +pass = 'password' + describe Pooler do before :each do @vmpooler_url = 'https://vmpooler.example.com' @@ -15,18 +18,20 @@ describe Pooler do end it 'returns a token from vmpooler' do - stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') + stub_request(:post, 'https://vmpooler.example.com/token') + .with(headers: get_headers(username: user, password: pass, content_length: 0)) .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, user, pass) expect(token).to eq @token end it 'raises a token error if something goes wrong' do - stub_request(:post, 'https://first.last:password@vmpooler.example.com/token') + stub_request(:post, 'https://vmpooler.example.com/token') + .with(headers: get_headers(username: user, password: pass, content_length: 0)) .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, user, pass) }.to raise_error(TokenError) end end @@ -37,15 +42,17 @@ describe Pooler do end it 'deletes the specified token' do - stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + stub_request(:delete, 'https://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(headers: get_headers(username: user, password: pass)) .to_return(status: 200, body: @delete_token_response, headers: {}) - expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', + expect(Auth.delete_token(false, @vmpooler_url, user, pass, @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') + stub_request(:delete, 'https://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y') + .with(headers: get_headers(username: user, password: pass)) .to_return(status: 500, body: '{"ok":false}', headers: {}) expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError) @@ -64,6 +71,7 @@ describe Pooler do it 'checks the status of a token' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") + .with(headers: get_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) @@ -71,6 +79,7 @@ describe Pooler do it 'raises a token error if something goes wrong' do stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y") + .with(headers: get_headers) .to_return(status: 500, body: '{"ok":false}', headers: {}) expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError) diff --git a/spec/vmfloaty/nonstandard_pooler_spec.rb b/spec/vmfloaty/nonstandard_pooler_spec.rb index 8b1ab7c..1f86dd2 100644 --- a/spec/vmfloaty/nonstandard_pooler_spec.rb +++ b/spec/vmfloaty/nonstandard_pooler_spec.rb @@ -8,9 +8,7 @@ require 'vmfloaty/nonstandard_pooler' describe NonstandardPooler do before :each do @nspooler_url = 'https://nspooler.example.com' - @auth_token_headers = { - 'X-Auth-Token' => 'token-value' - } + @auth_token_headers = get_headers(token: 'token-value') end describe '#list' do @@ -121,7 +119,7 @@ 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) + .with(headers: get_headers(token: 'token-value')) .to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {}) vm_hash = { 'solaris-11-sparc' => 1 } @@ -174,7 +172,7 @@ describe NonstandardPooler do end it 'modifies the reason of a vm' do - modify_request_body = { '{"reserved_for_reason":"testing"}' => true } + modify_request_body = { '{"reserved_for_reason":"testing"}' => nil } stub_request(:put, "#{@nspooler_url}/host/myfakehost") .with(body: modify_request_body, headers: @auth_token_headers) diff --git a/spec/vmfloaty/pooler_spec.rb b/spec/vmfloaty/pooler_spec.rb index 0604176..e9cebdd 100644 --- a/spec/vmfloaty/pooler_spec.rb +++ b/spec/vmfloaty/pooler_spec.rb @@ -119,8 +119,8 @@ describe Pooler do it 'modifies the TTL of a vm' do modify_hash = { lifetime: 12 } stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6") - .with(body: { '{"lifetime":12}' => true }, - headers: { 'Content-Type' => 'application/x-www-form-urlencoded', 'X-Auth-Token' => 'mytokenfile' }) + .with(body: { '{"lifetime":12}' => nil }, + headers: get_headers(content_type: 'application/x-www-form-urlencoded', token: 'mytokenfile')) .to_return(status: 200, body: @modify_response_body_success, headers: {}) modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 14e3db2..a8410ab 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -26,5 +26,5 @@ Gem::Specification.new do |s| s.add_dependency 'colorize', '~> 0.8.1' s.add_dependency 'commander', '>= 4.4.3', '< 4.6.0' - s.add_dependency 'faraday', '~> 0.17.0' + s.add_dependency 'faraday', '~> 1.5', '>= 1.5.1' end From bcd08fca15152f1fedaf3b7963b4d534e1958dd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jul 2021 17:02:52 +0000 Subject: [PATCH 171/265] Update commander requirement from >= 4.4.3, < 4.6.0 to >= 4.4.3, < 4.7.0 Updates the requirements on [commander](https://github.com/commander-rb/commander) to permit the latest version. - [Release notes](https://github.com/commander-rb/commander/releases) - [Changelog](https://github.com/commander-rb/commander/blob/master/History.rdoc) - [Commits](https://github.com/commander-rb/commander/compare/v4.4.3...v4.6.0) Signed-off-by: dependabot[bot] --- vmfloaty.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index a8410ab..c79a040 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -25,6 +25,6 @@ Gem::Specification.new do |s| s.require_path = 'lib' s.add_dependency 'colorize', '~> 0.8.1' - s.add_dependency 'commander', '>= 4.4.3', '< 4.6.0' + s.add_dependency 'commander', '>= 4.4.3', '< 4.7.0' s.add_dependency 'faraday', '~> 1.5', '>= 1.5.1' end From b89154648fe4b3dbf8f8cf1f480b84476c3cffe1 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Fri, 16 Jul 2021 16:24:32 -0400 Subject: [PATCH 172/265] v1.4.0 release prep --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index ffd73af..28841aa 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.3.0' + VERSION = '1.4.0' end From 38a465e862b2a46fa6b7455e23a59b1c5a8b74ac Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Fri, 16 Jul 2021 16:42:45 -0400 Subject: [PATCH 173/265] Migrate CI to GitHub Actions --- .coveralls.yml | 1 - .github/workflows/ci.yml | 53 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 7 ------ Gemfile | 4 ++- README.md | 4 +-- spec/spec_helper.rb | 18 ++++++++++---- 6 files changed, 71 insertions(+), 16 deletions(-) delete mode 100644 .coveralls.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index cf27a37..0000000 --- a/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -service_name: travis-pro diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..42edd97 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake +# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby + +name: CI + +on: + pull_request: + branches: + - main + +jobs: + test: + + runs-on: ubuntu-latest + strategy: + matrix: + ruby-version: + - '2.6' + - '2.7' + - '3.0' + + steps: + - uses: actions/checkout@v2 + - name: Set up Ruby + # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, + # change this to (see https://github.com/ruby/setup-ruby#versioning): + # uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: Run tests + run: bundle exec rake spec + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: run-${{ matrix.ruby-version }} + parallel: true + + finish: + needs: test + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 770839e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: ruby -dist: xenial -os: - - linux -rvm: - - 2.6.5 -script: bundle exec rake spec diff --git a/Gemfile b/Gemfile index 69ed407..6e26d2a 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,9 @@ gemspec gem 'rake', require: false group :test do - gem 'coveralls', '~> 0.8.23' + gem 'simplecov', '~> 0.21.2' + gem 'simplecov-html', '~> 0.12.3' + gem 'simplecov-lcov', '~> 0.8.0' gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.10.0' diff --git a/README.md b/README.md index 54e246e..f897005 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # vmfloaty [![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) -[![Build Status](https://travis-ci.com/puppetlabs/vmfloaty.svg?branch=master)](https://travis-ci.com/puppetlabs/vmfloaty) -[![Coverage Status](https://coveralls.io/repos/github/puppetlabs/vmfloaty/badge.svg?branch=master)](https://coveralls.io/github/puppetlabs/vmfloaty?branch=master) +[![Build Status](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml) +[![Coverage Status](https://github.com/puppetlabs/vmfloaty/badge.svg?branch=main)](https://coveralls.io/github/puppetlabs/vmfloaty?branch=main) [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=puppetlabs/vmfloaty)](https://dependabot.com) A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 750528d..1ed7ef7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,13 +1,21 @@ # frozen_string_literal: true require 'simplecov' -require 'coveralls' +require 'simplecov-lcov' require 'base64' -SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter - ]) +SimpleCov::Formatter::LcovFormatter.config do |c| + c.report_with_single_file = true + c.single_report_path = 'coverage/lcov.info' +end + +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new( + [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::LcovFormatter + ] +) + SimpleCov.start do add_filter %r{^/spec/} end From 33758081d1434a332bcc260b56e0a5cf61038e97 Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Wed, 11 Aug 2021 15:13:24 -0500 Subject: [PATCH 174/265] (DIO-2135) Update docker FROM image to ruby 3.0.2 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c564fa8..ceaa74e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.7 +FROM ruby:3.0.1-slim-buster COPY ./ ./ From bd5d1a36f019746bd3331d0e12bf14ba12da5b81 Mon Sep 17 00:00:00 2001 From: Tanisha Payne Date: Fri, 8 Oct 2021 11:44:45 -0400 Subject: [PATCH 175/265] priority flag added to ssh command --- lib/vmfloaty.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index d7e2196..4abba2d 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -469,6 +469,7 @@ class Vmfloaty c.option '--user STRING', String, 'User to authenticate with' c.option '--token STRING', String, 'Token for pooler service' c.option '--notoken', 'Makes a request without a token' + c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))' c.action do |args, options| verbose = options.verbose || config['verbose'] service = Service.new(options, config) From 3c3623689ada9eb46ef26425eb23b8a1d6e53aa1 Mon Sep 17 00:00:00 2001 From: Tanisha Payne Date: Tue, 12 Oct 2021 10:39:06 -0400 Subject: [PATCH 176/265] ondemand added to ssh command --- lib/vmfloaty.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 4abba2d..846bf4d 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -470,6 +470,7 @@ class Vmfloaty c.option '--token STRING', String, 'Token for pooler service' c.option '--notoken', 'Makes a request without a token' c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))' + c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID' c.action do |args, options| verbose = options.verbose || config['verbose'] service = Service.new(options, config) From 62f97319107ac1c261dbd6dc0919ab522e02bf37 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Tue, 12 Oct 2021 13:11:30 -0400 Subject: [PATCH 177/265] Release prep for 1.5.0 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 28841aa..fd1b9c7 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.4.0' + VERSION = '1.5.0' end From 61b87a5a589bbf27274f208d6fcf0ee9cd5e2241 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Tue, 12 Oct 2021 13:35:39 -0400 Subject: [PATCH 178/265] Minor cleanup to the readme --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f897005..4c60f87 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ # vmfloaty [![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) -[![Build Status](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml) -[![Coverage Status](https://github.com/puppetlabs/vmfloaty/badge.svg?branch=main)](https://coveralls.io/github/puppetlabs/vmfloaty?branch=main) -[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=puppetlabs/vmfloaty)](https://dependabot.com) +[![CI](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml/badge.svg)](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml) -A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. +A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. ![float image](float.jpg) @@ -18,7 +16,7 @@ A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler - [Using backends besides VMPooler](#using-backends-besides-vmpooler) - [Valid config keys](#valid-config-keys) - [Tab Completion](#tab-completion) -- [vmpooler API](#vmpooler-api) +- [VMPooler API](#vmpooler-api) - [Using the Pooler class](#using-the-pooler-class) - [Example Projects](#example-projects) - [Special thanks](#special-thanks) @@ -41,7 +39,7 @@ $ floaty --help DESCRIPTION: - A CLI helper tool for Puppet's vmpooler to help you stay afloat + A CLI helper tool for Puppet's VMPooler to help you stay afloat COMMANDS: @@ -151,13 +149,13 @@ There is also tab completion for zsh: source $(floaty completion --shell zsh) ``` -## vmpooler API +## VMPooler API -This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md). +This cli tool uses the [VMPooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md). ## Using the Pooler class -vmfloaty providers a `Pooler` class that gives users the ability to make requests to vmpooler without having to write their own requests. It also provides an `Auth` class for managing vmpooler tokens within your application. +vmfloaty providers a `Pooler` class that gives users the ability to make requests to VMPooler without having to write their own requests. It also provides an `Auth` class for managing VMPooler tokens within your application. ### Example Projects From 903e59afb88c78f8df4fe8c58a08e842aca79138 Mon Sep 17 00:00:00 2001 From: Gene Liverman Date: Tue, 12 Oct 2021 13:48:52 -0400 Subject: [PATCH 179/265] ignore .dccache --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5102fb1..1351382 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,8 @@ build/ /vendor/ /lib/bundler/man/ +.dccache + # for a library or gem, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: Gemfile.lock From 5793ea78b908c454a250af8fbbf037a887864c71 Mon Sep 17 00:00:00 2001 From: Christopher Thorn Date: Tue, 8 Feb 2022 11:53:55 -0800 Subject: [PATCH 180/265] (maint) Fix up nspooler list active bug If no reason is defined for checking out a nspooler VM we'd get a nil refrence error message when listing active nspooler VMs. This PR fixes that. --- lib/vmfloaty/utils.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index c1c4577..bfd4a4a 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -144,7 +144,7 @@ class Utils when 'NonstandardPooler' line = "- #{host_data['fqdn']} (#{host_data['os_triple']}" line += ", #{host_data['hours_left_on_reservation']}h remaining" - line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty? + line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].nil? || host_data['reserved_for_reason'].empty? line += ')' output_target.puts line else From 6b9b4ea6267b9aef2ec9f6fc290f2d5fd002a62c Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Wed, 16 Feb 2022 13:07:05 -0600 Subject: [PATCH 181/265] (DIO-2700) Vmfloaty should not use the Colorize gem removing cosmetic use of colorize --- lib/vmfloaty.rb | 1 - lib/vmfloaty/utils.rb | 4 ++-- lib/vmfloaty/version.rb | 2 +- spec/vmfloaty/utils_spec.rb | 6 +++--- vmfloaty.gemspec | 1 - 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 846bf4d..237632b 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -2,7 +2,6 @@ require 'rubygems' require 'commander' -require 'colorize' require 'json' require 'pp' require 'uri' diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index bfd4a4a..a24d7c5 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -137,7 +137,7 @@ class Utils 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' - output_target.puts message.colorize(:red) + output_target.puts "- DESTROYED #{hostname}.#{host_data['domain']}".gsub(/^/, ' ' * indent) else output_target.puts message end @@ -201,7 +201,7 @@ class Utils rescue StandardError => e FloatyLogger.error "#{name.ljust(width)} #{e.red}" end - puts message.colorize(status_response['status']['ok'] ? :default : :red) + puts message when 'NonstandardPooler' pools = status_response pools.delete 'ok' diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index fd1b9c7..119c4c5 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.5.0' + VERSION = '1.6.0' end diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index bade876..a567b0c 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -466,13 +466,13 @@ describe Utils do subject end - it 'prints in red when destroyed' do + it 'prints DESTROYED and hostname when destroyed' do 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 + default_output_second_line = " - DESTROYED #{fqdn}" expect($stdout).to receive(:puts).with(default_output_first_line) - expect($stdout).to receive(:puts).with(default_output_second_line_red) + expect($stdout).to receive(:puts).with(default_output_second_line) subject end diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index c79a040..5b15eff 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -24,7 +24,6 @@ Gem::Specification.new do |s| s.test_files = Dir['spec/**/*'] s.require_path = 'lib' - s.add_dependency 'colorize', '~> 0.8.1' s.add_dependency 'commander', '>= 4.4.3', '< 4.7.0' s.add_dependency 'faraday', '~> 1.5', '>= 1.5.1' end From 0463180a67914041ce112bf10c8f6d1de9e1bf86 Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Thu, 17 Mar 2022 08:53:31 -0700 Subject: [PATCH 182/265] (maint) removing previous maintainers Cleaning up our github org and repos. I checked in with each previous maintainer and they're cool with being off the hook here ;-) --- .github/PULL_REQUEST_TEMPLATE | 5 ----- CODEOWNERS | 2 +- vmfloaty.gemspec | 5 +---- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE index 0259cfe..5b0d10e 100644 --- a/.github/PULL_REQUEST_TEMPLATE +++ b/.github/PULL_REQUEST_TEMPLATE @@ -15,8 +15,3 @@ FIXME - [ ] Tests - [ ] Documentation -## Reviewers - -@puppetlabs/dio -@highb -@briancain diff --git a/CODEOWNERS b/CODEOWNERS index 321cebf..a478baf 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ # Set the default code owners -* @puppetlabs/dio @briancain @highb +* @puppetlabs/dio diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 5b15eff..b8abec1 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -10,10 +10,7 @@ Gem::Specification.new do |s| 'Brian Cain', 'Puppet' ] - s.email = [ - 'brianccain@gmail.com', - 'dio-gems@puppet.com' - ] + s.email = 'dio-gems@puppet.com' s.license = 'Apache-2.0' s.homepage = 'https://github.com/puppetlabs/vmfloaty' s.description = 'A helper tool for vmpooler to help you stay afloat' From 577579ffdd4fe31940a717f7d95b4bdeb5731bbd Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Fri, 1 Apr 2022 11:35:55 -0400 Subject: [PATCH 183/265] Add Ruby 3.1 to test matrix + dockerfile and drop EOL Ruby 2.6 --- .github/workflows/ci.yml | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42edd97..eadf380 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,9 +19,9 @@ jobs: strategy: matrix: ruby-version: - - '2.6' - '2.7' - '3.0' + - '3.1' steps: - uses: actions/checkout@v2 diff --git a/Dockerfile b/Dockerfile index ceaa74e..a38235d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.0.1-slim-buster +FROM ruby:3.1.1-slim-buster COPY ./ ./ From 6b67c216f5072f80aebda99d87c645abccd7b2fe Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 4 Apr 2022 11:25:56 -0400 Subject: [PATCH 184/265] Remove colorize usage from `floaty status` --- lib/vmfloaty/utils.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index a24d7c5..8470921 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -197,9 +197,9 @@ class Utils pending = pool['pending'] missing = max - ready - pending char = 'o' - puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}" + puts "#{name.ljust(width)} #{(char * ready)}#{(char * pending)}#{(char * missing)}" rescue StandardError => e - FloatyLogger.error "#{name.ljust(width)} #{e.red}" + FloatyLogger.error "#{name.ljust(width)} #{e}" end puts message when 'NonstandardPooler' @@ -214,13 +214,13 @@ class Utils 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}" + puts "#{name.ljust(width)} #{(char * ready)}#{(char * pending)}#{(char * missing)}" rescue StandardError => e - FloatyLogger.error "#{name.ljust(width)} #{e.red}" + FloatyLogger.error "#{name.ljust(width)} #{e}" end when 'ABS' FloatyLogger.error 'ABS Not OK' unless status_response - puts 'ABS is OK'.green if status_response + puts 'ABS is OK' if status_response else raise "Invalid service type #{service.type}" end From da48a4de0ae830704a5a478977849e2ff2c8b34d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Apr 2022 15:44:45 +0000 Subject: [PATCH 185/265] Update rspec requirement from ~> 3.10.0 to ~> 3.11.0 Updates the requirements on [rspec](https://github.com/rspec/rspec-metagem) to permit the latest version. - [Release notes](https://github.com/rspec/rspec-metagem/releases) - [Commits](https://github.com/rspec/rspec-metagem/compare/v3.10.0...v3.11.0) --- updated-dependencies: - dependency-name: rspec dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 6e26d2a..acc82eb 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'simplecov-lcov', '~> 0.8.0' gem 'pry' gem 'rb-readline' - gem 'rspec', '~> 3.10.0' + gem 'rspec', '~> 3.11.0' gem 'rubocop', '~> 1.6' gem 'webmock', '~> 3.13' end From 4103fdecccdde1a022fd0d6e4006bfbd8306fe14 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Fri, 1 Apr 2022 11:32:22 -0400 Subject: [PATCH 186/265] Add VMPooler api v2 support for `floaty get` --- lib/vmfloaty/utils.rb | 19 +++++++++++++++++-- spec/vmfloaty/utils_spec.rb | 22 +++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 8470921..39c97a3 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -9,7 +9,7 @@ class Utils # TODO: Takes the json response body from an HTTP GET # request and "pretty prints" it def self.standardize_hostnames(response_body) - # vmpooler response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`: + # vmpooler api v1 response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`: # { # "ok": true, # "domain": "delivery.mycompany.net", @@ -21,6 +21,17 @@ class Utils # } # } + # vmpooler api v2 response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`: + # { + # "ok": true, + # "ubuntu-1610-x86_64": { + # "hostname": ["gdoy8q3nckuob0i.pooler.example.com", "ctnktsd0u11p9tm.pooler.example.com"] + # }, + # "centos-7-x86_64": { + # "hostname": "dlgietfmgeegry2.pooler.example.com" + # } + # } + # nonstandard pooler response body example when `floaty get` arguments are `solaris-11-sparc=2 ubuntu-16.04-power8`: # { # "ok": true, @@ -98,7 +109,11 @@ class Utils puts abs_hostnames.join("\n") when 'Pooler' - puts "#{hostname}.#{host_data['domain']}" + if host_data['domain'].nil? + puts hostname + else + puts "#{hostname}.#{host_data['domain']}" + end when 'NonstandardPooler' puts host_data['fqdn'] else diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index a567b0c..0994107 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -13,7 +13,7 @@ end describe Utils do describe '#standardize_hostnames' do before :each do - @vmpooler_response_body = '{ + @vmpooler_api_v1_response_body = '{ "ok": true, "domain": "delivery.mycompany.net", "ubuntu-1610-x86_64": { @@ -23,6 +23,15 @@ describe Utils do "hostname": "dlgietfmgeegry2" } }' + @vmpooler_api_v2_response_body = '{ + "ok": true, + "ubuntu-1610-x86_64": { + "hostname": ["gdoy8q3nckuob0i.delivery.mycompany.net", "ctnktsd0u11p9tm.delivery.mycompany.net"] + }, + "centos-7-x86_64": { + "hostname": "dlgietfmgeegry2.delivery.mycompany.net" + } + }' @nonstandard_response_body = '{ "ok": true, "solaris-10-sparc": { @@ -34,8 +43,15 @@ describe Utils do }' end - it 'formats a result from vmpooler into a hash of os to hostnames' do - result = Utils.standardize_hostnames(JSON.parse(@vmpooler_response_body)) + it 'formats a result from vmpooler v1 api into a hash of os to hostnames' do + result = Utils.standardize_hostnames(JSON.parse(@vmpooler_api_v1_response_body)) + expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], + 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', + 'ctnktsd0u11p9tm.delivery.mycompany.net']) + end + + it 'formats a result from vmpooler v2 api into a hash of os to hostnames' do + result = Utils.standardize_hostnames(JSON.parse(@vmpooler_api_v2_response_body)) expect(result).to eq('centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'], 'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net']) From 3e8ddca1e30aa9247361304f24f5afa685cb43db Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Tue, 5 Apr 2022 11:36:35 -0400 Subject: [PATCH 187/265] Update release workflow to on dispatch and add notes about releasing --- .github/workflows/gempush.yml | 29 ------------------------ .github/workflows/release.yml | 42 +++++++++++++++++++++++++++++++++++ README.md | 18 +++++++++++++++ 3 files changed, 60 insertions(+), 29 deletions(-) delete mode 100644 .github/workflows/gempush.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/gempush.yml b/.github/workflows/gempush.yml deleted file mode 100644 index 0d8a445..0000000 --- a/.github/workflows/gempush.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Ruby Gem - -on: - push: - tags: - - 'v*.*.*' - -jobs: - build: - name: Build + Publish - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up Ruby 2.6 - uses: actions/setup-ruby@v1 - with: - version: 2.6.x - - - name: Publish to RubyGems - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - gem build *.gemspec - gem push *.gem - env: - GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..273a263 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Release + +on: workflow_dispatch + +jobs: + release: + name: Build + Publish + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Get Version + id: gv + run: | + echo "::set-output name=ver::$(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev)" + + - name: Tag Release + uses: ncipollo/release-action@v1 + with: + tag: ${{ steps.gv.outputs.ver }} + token: ${{ secrets.GITHUB_TOKEN }} + draft: false + prerelease: false + generateReleaseNotes: true + + - name: Set up Ruby 2.7 + uses: actions/setup-ruby@v1 + with: + version: 2.7.x + + - name: Build gem + run: gem build *.gemspec + + - name: Publish gem + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem push *.gem + env: + GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} diff --git a/README.md b/README.md index 4c60f87..15ec356 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler - [VMPooler API](#vmpooler-api) - [Using the Pooler class](#using-the-pooler-class) - [Example Projects](#example-projects) +- [Contributing](#contributing) + - [Code Reviews](#code-reviews) +- [Releasing](#releasing) - [Special thanks](#special-thanks) ## Install @@ -164,6 +167,21 @@ vmfloaty providers a `Pooler` class that gives users the ability to make request - [Brian Cain: vagrant-vmpooler](https://github.com/briancain/vagrant-vmpooler) - Use Vagrant to manage your vmpooler instances +## Contributing + +PR's are welcome! We always love to see how others think this tool can be made better. + +### Code Reviews + +Please wait for multiple code owners to sign off on any notable change. + +## Releasing + +Releasing is a two step process: + +1. Submit a release prep PR that updates `lib/vmfloaty/version.rb` to the desired new version and get that merged +2. Navigate to --> Run workflow --> select "main" branch --> Run workflow. This will publish a GitHub release, build, and push the gem to RubyGems. + ## Special thanks Special thanks to [Brian Cain](https://github.com/briancain) as he is the original author of vmfloaty! Vast amounts of this code exist thanks to his efforts. From 667dacbcea90d956e73ad2181b271ab5761db34c Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 4 Apr 2022 08:57:23 -0400 Subject: [PATCH 188/265] Add ondemand flag and api v2 support to `floaty ssh` --- lib/vmfloaty.rb | 2 +- lib/vmfloaty/service.rb | 4 +- lib/vmfloaty/ssh.rb | 36 +++++++++---- spec/vmfloaty/ssh_spec.rb | 107 ++++++++++++++++++++++++++++++-------- 4 files changed, 115 insertions(+), 34 deletions(-) diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 237632b..3c6bbec 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -484,7 +484,7 @@ class Vmfloaty FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1 - service.ssh(verbose, host_os, use_token) + service.ssh(verbose, host_os, use_token, options.ondemand) exit 0 end end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index 05904a1..a9e59ba 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -87,7 +87,7 @@ class Service @service_object.wait_for_request verbose, requestid, url end - def ssh(verbose, host_os, use_token = true) + def ssh(verbose, host_os, use_token = true, ondemand = nil) token_value = nil if use_token begin @@ -97,7 +97,7 @@ class Service FloatyLogger.info 'Could not get token... requesting vm without a token anyway...' end end - Ssh.ssh(verbose, self, host_os, token_value) + Ssh.ssh(verbose, self, host_os, token_value, ondemand) end def query(verbose, hostname) diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb index f100b8b..582adea 100644 --- a/lib/vmfloaty/ssh.rb +++ b/lib/vmfloaty/ssh.rb @@ -14,27 +14,45 @@ class Ssh nil end - def self.command_string(verbose, service, host_os, use_token) + def self.command_string(verbose, service, host_os, use_token, ondemand = nil) ssh_path = which('ssh') raise 'Could not determine path to ssh' unless ssh_path - - os_types = {} + os_types = Utils.generate_os_hash([host_os]) os_types[host_os] = 1 - response = service.retrieve(verbose, os_types, use_token) + response = service.retrieve(verbose, os_types, use_token, ondemand) raise "Could not get vm from #{service.type}:\n #{response}" unless response['ok'] user = /win/.match?(host_os) ? 'Administrator' : 'root' - hostname = response[host_os]['hostname'] - hostname = response[host_os]['hostname'][0] if response[host_os]['hostname'].is_a?(Array) - hostname = "#{hostname}.#{response['domain']}" unless hostname.end_with?('puppetlabs.net') + if ondemand + requestid = response['request_id'] + service.wait_for_request(verbose, requestid) + hosts = service.check_ondemandvm(verbose, requestid, service.url) + if hosts['domain'].nil? + hostname = hosts[host_os]['hostname'] + hostname = hosts[host_os]['hostname'][0] if hosts[host_os]['hostname'].is_a?(Array) + else + # Provides backwards compatibility with VMPooler API v1 + hostname = "#{hosts[host_os]['hostname']}.#{hosts['domain']}" + hostname = "#{hosts[host_os]['hostname'][0]}.#{hosts['domain']}" if hosts[host_os]['hostname'].is_a?(Array) + end + else + if response['domain'].nil? + hostname = response[host_os]['hostname'] + hostname = response[host_os]['hostname'][0] if response[host_os]['hostname'].is_a?(Array) + else + # Provides backwards compatibility with VMPooler API v1 + hostname = "#{response[host_os]['hostname']}.#{response['domain']}" + hostname = "#{response[host_os]['hostname'][0]}.#{response['domain']}" if response[host_os]['hostname'].is_a?(Array) + end + end "#{ssh_path} #{user}@#{hostname}" end - def self.ssh(verbose, service, host_os, use_token) - cmd = command_string(verbose, service, host_os, use_token) + def self.ssh(verbose, service, host_os, use_token, ondemand) + cmd = command_string(verbose, service, host_os, use_token, ondemand) # TODO: Should this respect more ssh settings? Can it be configured # by users ssh config and does this respect those settings? Kernel.exec(cmd) diff --git a/spec/vmfloaty/ssh_spec.rb b/spec/vmfloaty/ssh_spec.rb index c16bb30..ec5fd4e 100644 --- a/spec/vmfloaty/ssh_spec.rb +++ b/spec/vmfloaty/ssh_spec.rb @@ -4,24 +4,35 @@ require 'spec_helper' require 'vmfloaty/ssh' class ServiceStub - def retrieve(_verbose, os_types, _use_token) + def retrieve(_verbose, os_types, _use_token, ondemand) if os_types.keys[0] == 'abs_host_string' return { os_types.keys[0] => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net'] }, 'ok' => true } - end - { - os_types.keys[0] => { 'hostname' => 'vmpooler-hostname' }, - 'domain' => 'delivery.puppetlabs.net', - 'ok' => true - } + elsif os_types.keys[0] == 'vmpooler_api_v2_host_string' + return { + os_types.keys[0] => { 'hostname' => ['vmpooler-v2-hostname.delivery.puppetlabs.net'] }, + 'ok' => true + } + + else + return { + os_types.keys[0] => { 'hostname' => 'vmpooler-v1-hostname' }, + 'domain' => 'delivery.puppetlabs.net', + 'ok' => true + } + end end def type return 'abs' if os_types == 'abs_host_string' - return 'vmpooler' if os_types == 'vmpooler_host_string' + return 'vmpooler' if os_types == 'vmpooler_api_v1_host_string' || os_types == 'vmpooler_api_v2_host_string' + end + + def wait_for_request(verbose, requestid) + return true end end @@ -29,21 +40,73 @@ describe Ssh do before :each do end - it 'gets a hostname string for abs' do - verbose = false - service = ServiceStub.new - host_os = 'abs_host_string' - use_token = false - cmd = Ssh.command_string(verbose, service, host_os, use_token) - expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/) + context "for pooled requests" do + it 'gets a hostname string for abs' do + verbose = false + service = ServiceStub.new + host_os = 'abs_host_string' + use_token = false + cmd = Ssh.command_string(verbose, service, host_os, use_token) + expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/) + end + + it 'gets a hostname string for vmpooler api v1' do + verbose = true + service = ServiceStub.new + host_os = 'vmpooler_api_v1_host_string' + use_token = false + cmd = Ssh.command_string(verbose, service, host_os, use_token) + expect(cmd).to match(/ssh root@vmpooler-v1-hostname.delivery.puppetlabs.net/) + end + + it 'gets a hostname string for vmpooler api v2' do + verbose = false + service = ServiceStub.new + host_os = 'vmpooler_api_v2_host_string' + use_token = false + cmd = Ssh.command_string(verbose, service, host_os, use_token) + expect(cmd).to match(/ssh root@vmpooler-v2-hostname.delivery.puppetlabs.net/) + end end - it 'gets a hostname string for vmpooler' do - verbose = false - service = ServiceStub.new - host_os = 'vmpooler_host_string' - use_token = false - cmd = Ssh.command_string(verbose, service, host_os, use_token) - expect(cmd).to match(/ssh root@vmpooler-hostname.delivery.puppetlabs.net/) + context "for ondemand requests" do + let(:service) { ServiceStub.new } + let(:url) { 'http://pooler.example.com' } + + it 'gets a hostname string for abs' do + verbose = false + host_os = 'abs_host_string' + use_token = false + ondemand = true + response = {'abs_host_string' => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net']}} + allow(service).to receive(:url) + allow(service).to receive(:check_ondemandvm).and_return(response) + cmd = Ssh.command_string(verbose, service, host_os, use_token, ondemand) + expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/) + end + + it 'gets a hostname string for abs' do + verbose = false + host_os = 'vmpooler_api_v1_host_string' + use_token = false + ondemand = true + response = {'vmpooler_api_v1_host_string' => { 'hostname' => ['vmpooler_api_v1_host_string.delivery.puppetlabs.net']}} + allow(service).to receive(:url) + allow(service).to receive(:check_ondemandvm).and_return(response) + cmd = Ssh.command_string(verbose, service, host_os, use_token, ondemand) + expect(cmd).to match(/ssh root@vmpooler_api_v1_host_string.delivery.puppetlabs.net/) + end + + it 'gets a hostname string for abs' do + verbose = false + host_os = 'vmpooler_api_v2_host_string' + use_token = false + ondemand = true + response = {'vmpooler_api_v2_host_string' => { 'hostname' => ['vmpooler_api_v2_host_string.delivery.puppetlabs.net']}} + allow(service).to receive(:url) + allow(service).to receive(:check_ondemandvm).and_return(response) + cmd = Ssh.command_string(verbose, service, host_os, use_token, ondemand) + expect(cmd).to match(/ssh root@vmpooler_api_v2_host_string.delivery.puppetlabs.net/) + end end end From f74fe222451709735b161ecd02c37cfe5fd06b23 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Tue, 5 Apr 2022 11:51:23 -0400 Subject: [PATCH 189/265] v1.7.0 release prep Includes the following PRs since the last release: - https://github.com/puppetlabs/vmfloaty/pull/157 - https://github.com/puppetlabs/vmfloaty/pull/160 - https://github.com/puppetlabs/vmfloaty/pull/159 - https://github.com/puppetlabs/vmfloaty/pull/155 - https://github.com/puppetlabs/vmfloaty/pull/152 - https://github.com/puppetlabs/vmfloaty/pull/158 --- lib/vmfloaty/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 119c4c5..28c2a9f 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.6.0' + VERSION = '1.7.0' end From 14c160c2bce24783a3d2b3826d19f2deb2524f3a Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 8 Aug 2022 14:36:32 -0400 Subject: [PATCH 190/265] Add release-engineering to codeowners --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index a478baf..1fd1dac 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ # Set the default code owners -* @puppetlabs/dio +* @puppetlabs/dio @puppetlabs/release-engineering From a93bc246492d34bdd2af8a5d5384bd2ddee3b7b4 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 15 Aug 2022 17:04:57 -0400 Subject: [PATCH 191/265] Add Snyk action --- .github/workflows/snyk.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/snyk.yml diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml new file mode 100644 index 0000000..b9158e1 --- /dev/null +++ b/.github/workflows/snyk.yml @@ -0,0 +1,25 @@ +name: Snyk Scan + +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + security: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + - name: Bundle Install + run: bundle install + - name: Run Snyk to check for vulnerabilities + uses: snyk/actions/ruby@master + env: + SNYK_TOKEN: ${{ secrets.SNYK_RE_KEY }} + with: + command: monitor From 594544ea67ff8ff9c92ef6f0f74b0124aaed1ff3 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Fri, 26 Aug 2022 09:30:51 -0400 Subject: [PATCH 192/265] Move codeowners from DIO to RE --- CODEOWNERS | 2 +- vmfloaty.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 1fd1dac..e8dffe5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ # Set the default code owners -* @puppetlabs/dio @puppetlabs/release-engineering +* @puppetlabs/release-engineering diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index b8abec1..184247b 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |s| 'Brian Cain', 'Puppet' ] - s.email = 'dio-gems@puppet.com' + s.email = 'info@puppet.com' s.license = 'Apache-2.0' s.homepage = 'https://github.com/puppetlabs/vmfloaty' s.description = 'A helper tool for vmpooler to help you stay afloat' From cda848d2147248ddffb8eaffd84f12c1976d7f40 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Thu, 19 Jan 2023 19:23:14 -0500 Subject: [PATCH 193/265] Change dependabot to weekly --- .github/dependabot.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c8f8016..81e0069 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,6 +3,5 @@ updates: - package-ecosystem: bundler directory: "/" schedule: - interval: daily - time: "13:00" + interval: weekly open-pull-requests-limit: 10 From 6f35d0b16b1983d38326e3d2794a8593cf368900 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Thu, 19 Jan 2023 19:26:29 -0500 Subject: [PATCH 194/265] Migrate Snyk to Mend Scanning --- .github/workflows/security.yml | 39 ++++++++++++++++++++++++++++++++++ .github/workflows/snyk.yml | 25 ---------------------- 2 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/security.yml delete mode 100644 .github/workflows/snyk.yml diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..666c602 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,39 @@ +name: Security +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + scan: + name: Mend Scanning + runs-on: ubuntu-latest + steps: + - name: checkout repo content + uses: actions/checkout@v3 + with: + fetch-depth: 1 + - name: setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + # setup a package lock if one doesn't exist, otherwise do nothing + - name: check lock + run: '[ -f "Gemfile.lock" ] && echo "package lock file exists, skipping" || bundle lock' + # install java + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' # See 'Supported distributions' for available options + java-version: '17' + # download mend + - name: download_mend + run: curl -o wss-unified-agent.jar https://unified-agent.s3.amazonaws.com/wss-unified-agent.jar + - name: run mend + run: java -jar wss-unified-agent.jar + env: + WS_APIKEY: ${{ secrets.MEND_API_KEY }} + WS_WSS_URL: https://saas-eu.whitesourcesoftware.com/agent + WS_USERKEY: ${{ secrets.MEND_TOKEN }} + WS_PRODUCTNAME: RE + WS_PROJECTNAME: ${{ github.event.repository.name }} diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml deleted file mode 100644 index b9158e1..0000000 --- a/.github/workflows/snyk.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Snyk Scan - -on: - workflow_dispatch: - push: - branches: - - main - -jobs: - security: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Bundle Install - run: bundle install - - name: Run Snyk to check for vulnerabilities - uses: snyk/actions/ruby@master - env: - SNYK_TOKEN: ${{ secrets.SNYK_RE_KEY }} - with: - command: monitor From d5d87ed54ae59d75415c693bcdbd6a737eebc3ce Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:00:17 -0400 Subject: [PATCH 195/265] Fix `floaty list --active` for vmpooler api v2 --- lib/vmfloaty/utils.rb | 9 ++++- spec/vmfloaty/utils_spec.rb | 68 ++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index 39c97a3..b393acf 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -150,7 +150,14 @@ class Utils tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil? duration = "#{host_data['running']}/#{host_data['lifetime']} hours" metadata = [host_data['state'], host_data['template'], duration, *tag_pairs] - message = "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) + # For backwards compatibility with vmpooler api v1 + message = + if host_data['domain'] + "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) + else + "- #{host_data['fqdn']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent) + end + if host_data['state'] && host_data['state'] == 'destroyed' output_target.puts "- DESTROYED #{hostname}.#{host_data['domain']}".gsub(/^/, ' ' * indent) else diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 0994107..37d2537 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -280,7 +280,73 @@ describe Utils do subject { Utils.pretty_print_hosts(verbose, service, hostname, print_to_stderr) } - describe 'with vmpooler service' do + describe 'with vmpooler api v2 service' do + let(:service) { Service.new(MockOptions.new, 'url' => url) } + + let(:hostname) { 'mcpy42eqjxli9g2' } + let(:fqdn) { [hostname, 'delivery.puppetlabs.net'].join('.') } + + let(:response_body) do + { + hostname => { + 'template' => 'ubuntu-1604-x86_64', + 'lifetime' => 12, + 'running' => 9.66, + 'state' => 'running', + 'ip' => '127.0.0.1', + 'fqdn' => fqdn + } + } + end + + 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) + + subject + end + + context 'when tags are supplied' do + let(:hostname) { 'aiydvzpg23r415q' } + let(:response_body) do + { + hostname => { + 'template' => 'redhat-7-x86_64', + 'lifetime' => 48, + 'running' => 7.67, + 'state' => 'running', + 'tags' => { + 'user' => 'bob', + 'role' => 'agent' + }, + 'ip' => '127.0.0.1', + 'fqdn' => fqdn + } + } + end + + 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) + + subject + end + end + + context 'when print_to_stderr option is true' do + let(:print_to_stderr) { true } + + it 'outputs to stderr instead of stdout' do + expect($stderr).to receive(:puts).with(default_output) + + subject + end + end + end + + describe 'with vmpooler api v1 service' do let(:service) { Service.new(MockOptions.new, 'url' => url) } let(:hostname) { 'mcpy42eqjxli9g2' } From e65a1dad3b08e34d22f1219998a1b11f172994aa Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:11:04 -0400 Subject: [PATCH 196/265] Update test workflow names, action tags, and add ruby 3.2 --- .github/workflows/{ci.yml => test.yml} | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) rename .github/workflows/{ci.yml => test.yml} (85%) diff --git a/.github/workflows/ci.yml b/.github/workflows/test.yml similarity index 85% rename from .github/workflows/ci.yml rename to .github/workflows/test.yml index eadf380..4b9576f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby -name: CI +name: Test on: pull_request: @@ -13,8 +13,7 @@ on: - main jobs: - test: - + spec: runs-on: ubuntu-latest strategy: matrix: @@ -22,9 +21,10 @@ jobs: - '2.7' - '3.0' - '3.1' + - '3.2' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Ruby # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, # change this to (see https://github.com/ruby/setup-ruby#versioning): @@ -36,18 +36,19 @@ jobs: - name: Run tests run: bundle exec rake spec - name: Coveralls - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} flag-name: run-${{ matrix.ruby-version }} parallel: true finish: - needs: test + needs: spec + if: ${{ always() }} runs-on: ubuntu-latest steps: - name: Coveralls Finished - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.github_token }} - parallel-finished: true \ No newline at end of file + parallel-finished: true From d50e903167d94178824e798321d7d7c058c137de Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:15:39 -0400 Subject: [PATCH 197/265] Dependabot scan for actions updates --- .github/dependabot.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 81e0069..1afdd73 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,13 @@ version: 2 updates: -- package-ecosystem: bundler - directory: "/" - schedule: - interval: weekly - open-pull-requests-limit: 10 + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + + - package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 From dba1215db4cb8267607acd9a7b4da0ffcb6c48a6 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:33:15 -0400 Subject: [PATCH 198/265] Use Dockerfile for publishing an image --- .dockerignore | 3 --- Dockerfile | 25 +++++++++++++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.dockerignore b/.dockerignore index 6174523..eaf3712 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,10 +3,7 @@ **/*.md **/*example **/Dockerfile* -Gemfile.lock -Rakefile coverage -spec examples scripts vendor diff --git a/Dockerfile b/Dockerfile index a38235d..700e7bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,23 @@ -FROM ruby:3.1.1-slim-buster +FROM ruby:3.1.3-slim-bullseye -COPY ./ ./ +LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" +LABEL org.opencontainers.image.title="vmfloaty" +LABEL org.opencontainers.image.source=https://github.com/puppetlabs/vmfloaty +LABEL org.opencontainers.image.description="A CLI helper tool for VMPooler" -RUN apt-get update && apt-get install -y less -RUN gem install bundler && bundle install && gem build vmfloaty.gemspec && gem install vmfloaty*.gem +RUN apt-get update -qq && apt-get install -y build-essential less make openssh-client + +RUN groupadd --gid 1000 floatygroup \ + && useradd --uid 1000 --gid 1000 -m floatyuser + +USER floatyuser + +WORKDIR /home/floatyuser/app +COPY --chown=floatyuser:floatygroup . . + +RUN gem install bundler \ + && bundle install \ + && gem build vmfloaty.gemspec \ + && gem install vmfloaty*.gem + +ENTRYPOINT [ "floaty" ] From 9fdbb4acb9a8b94b1590f6db5d6d92c0488464e4 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:35:42 -0400 Subject: [PATCH 199/265] Update workflow to check changelog, add release notes and docker push --- .github/workflows/release.yml | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 273a263..39b43e3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,32 +1,108 @@ -name: Release +name: Tag Release & Push Gem & Docker on: workflow_dispatch +permissions: + contents: write + issues: read + pull-requests: read + packages: write + jobs: release: - name: Build + Publish + name: Validate Docs, Tag, and Docker Push runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Get Version - id: gv - run: | - echo "::set-output name=ver::$(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev)" + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + clean: true + fetch-depth: 0 + + - name: Get New Version + id: nv + run: | + version=$(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev) + echo "version=$version" >> $GITHUB_OUTPUT + echo "Found version $version from lib/vmfloaty/version.rb" + + - name: Get Current Version + uses: actions/github-script@v6 + id: cv + with: + script: | + const { data: response } = await github.rest.repos.getLatestRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + }) + console.log(`The latest release is ${response.tag_name}`) + return response.tag_name + result-encoding: string + + - name: Generate Changelog + uses: docker://githubchangeloggenerator/github-changelog-generator:1.16.2 + with: + args: >- + --future-release ${{ steps.nv.outputs.version }} + env: + CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Validate Changelog + run : | + set -e + if output=$(git status --porcelain) && [ ! -z "$output" ]; then + echo "Here is the current git status:" + git status + echo + echo "The following changes were detected:" + git --no-pager diff + echo "Uncommitted PRs found in the changelog. Please submit a release prep PR of changes after running './release-prep ${{ steps.nv.outputs.version }}'" + exit 1 + fi + + - name: Generate Release Notes + uses: docker://githubchangeloggenerator/github-changelog-generator:1.16.2 + with: + args: >- + --since-tag ${{ steps.cv.outputs.result }} + --future-release ${{ steps.nv.outputs.version }} + --output release-notes.md + env: + CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Tag Release uses: ncipollo/release-action@v1 with: - tag: ${{ steps.gv.outputs.ver }} + tag: ${{ steps.nv.outputs.version }} token: ${{ secrets.GITHUB_TOKEN }} + bodyfile: release-notes.md draft: false prerelease: false - generateReleaseNotes: true - - name: Set up Ruby 2.7 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + push: true + tags: | + ghcr.io/${{ github.repository }}:${{ steps.nv.outputs.version }} + ghcr.io/${{ github.repository }}:latest + + - name: Set up Ruby 3.2 uses: actions/setup-ruby@v1 with: - version: 2.7.x + version: 3.2.x - name: Build gem run: gem build *.gemspec From 68843c1ecf0acfa29a64e99ba187df96e36504fe Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:35:54 -0400 Subject: [PATCH 200/265] Add changelog --- .github_changelog_generator | 3 + CHANGELOG.md | 312 ++++++++++++++++++++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 .github_changelog_generator create mode 100644 CHANGELOG.md diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000..02a0c7c --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,3 @@ +project=vmfloaty +user=puppetlabs +exclude_labels=maintenance diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fa063ee --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,312 @@ +# Changelog + +## [Unreleased](https://github.com/puppetlabs/vmfloaty/tree/HEAD) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/1.7.0...HEAD) + +**Merged pull requests:** + +- \(RE-15111\) Migrate Synk to Mend [\#168](https://github.com/puppetlabs/vmfloaty/pull/168) ([yachub](https://github.com/yachub)) +- \(RE-14811\) Move codeowners from DIO to RE [\#165](https://github.com/puppetlabs/vmfloaty/pull/165) ([yachub](https://github.com/yachub)) +- Add Snyk action and Move to RE org [\#164](https://github.com/puppetlabs/vmfloaty/pull/164) ([yachub](https://github.com/yachub)) +- Add release-engineering to codeowners [\#163](https://github.com/puppetlabs/vmfloaty/pull/163) ([yachub](https://github.com/yachub)) + +## [1.7.0](https://github.com/puppetlabs/vmfloaty/tree/1.7.0) (2022-04-05) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.6.0...1.7.0) + +**Implemented enhancements:** + +- \(maint\) Add Ruby 3.1 to test matrix + dockerfile and drop EOL Ruby 2.6 [\#159](https://github.com/puppetlabs/vmfloaty/pull/159) ([yachub](https://github.com/yachub)) +- \(DIO-3101\) Add VMPooler API v2 Support [\#158](https://github.com/puppetlabs/vmfloaty/pull/158) ([yachub](https://github.com/yachub)) + +**Fixed bugs:** + +- \(maint\) Remove colorize usage from `floaty status` [\#160](https://github.com/puppetlabs/vmfloaty/pull/160) ([yachub](https://github.com/yachub)) + +**Merged pull requests:** + +- v1.7.0 release prep [\#162](https://github.com/puppetlabs/vmfloaty/pull/162) ([yachub](https://github.com/yachub)) +- \(maint\) removing previous maintainers [\#157](https://github.com/puppetlabs/vmfloaty/pull/157) ([binford2k](https://github.com/binford2k)) +- Update rspec requirement from ~\> 3.10.0 to ~\> 3.11.0 [\#155](https://github.com/puppetlabs/vmfloaty/pull/155) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Docs on contributing and releasing [\#152](https://github.com/puppetlabs/vmfloaty/pull/152) ([genebean](https://github.com/genebean)) + +## [v1.6.0](https://github.com/puppetlabs/vmfloaty/tree/v1.6.0) (2022-02-16) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.5.0...v1.6.0) + +**Merged pull requests:** + +- \(DIO-2700\) Vmfloaty should not use the Colorize gem [\#156](https://github.com/puppetlabs/vmfloaty/pull/156) ([sbeaulie](https://github.com/sbeaulie)) +- \(maint\) Fix up nspooler list active bug [\#154](https://github.com/puppetlabs/vmfloaty/pull/154) ([cthorn42](https://github.com/cthorn42)) +- Minor cleanup to the readme [\#151](https://github.com/puppetlabs/vmfloaty/pull/151) ([genebean](https://github.com/genebean)) +- Release prep for 1.5.0 [\#150](https://github.com/puppetlabs/vmfloaty/pull/150) ([genebean](https://github.com/genebean)) + +## [v1.5.0](https://github.com/puppetlabs/vmfloaty/tree/v1.5.0) (2021-10-12) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.4.0...v1.5.0) + +**Merged pull requests:** + +- DIO 2412- Ondemand and Priority flag added to SSH command [\#149](https://github.com/puppetlabs/vmfloaty/pull/149) ([tanisha-payne](https://github.com/tanisha-payne)) +- \(DIO-2135\) Update docker FROM image to ruby 3.0.2 [\#148](https://github.com/puppetlabs/vmfloaty/pull/148) ([sbeaulie](https://github.com/sbeaulie)) +- Migrate CI to GitHub Actions [\#147](https://github.com/puppetlabs/vmfloaty/pull/147) ([genebean](https://github.com/genebean)) +- v1.4.0 release prep [\#146](https://github.com/puppetlabs/vmfloaty/pull/146) ([genebean](https://github.com/genebean)) + +## [v1.4.0](https://github.com/puppetlabs/vmfloaty/tree/v1.4.0) (2021-07-16) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.3.0...v1.4.0) + +**Merged pull requests:** + +- \(maint\) Use latest Faraday/webmock, update specs [\#145](https://github.com/puppetlabs/vmfloaty/pull/145) ([nmburgan](https://github.com/nmburgan)) +- Update commander requirement from \>= 4.4.3, \< 4.6.0 to \>= 4.4.3, \< 4.7.0 [\#140](https://github.com/puppetlabs/vmfloaty/pull/140) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Release prep for v1.3.0 [\#137](https://github.com/puppetlabs/vmfloaty/pull/137) ([sbeaulie](https://github.com/sbeaulie)) +- Run the rubocop auto\_correct [\#135](https://github.com/puppetlabs/vmfloaty/pull/135) ([sbeaulie](https://github.com/sbeaulie)) + +## [v1.3.0](https://github.com/puppetlabs/vmfloaty/tree/v1.3.0) (2021-03-03) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.2.0...v1.3.0) + +**Merged pull requests:** + +- \(DIO-1522\) Show the VM state \(running, destroyed\) and colorize in red… [\#134](https://github.com/puppetlabs/vmfloaty/pull/134) ([sbeaulie](https://github.com/sbeaulie)) +- Release prep for 1.2.0 [\#132](https://github.com/puppetlabs/vmfloaty/pull/132) ([genebean](https://github.com/genebean)) +- Update rubocop requirement from ~\> 0.52 to ~\> 1.6 [\#124](https://github.com/puppetlabs/vmfloaty/pull/124) ([dependabot[bot]](https://github.com/apps/dependabot)) + +## [v1.2.0](https://github.com/puppetlabs/vmfloaty/tree/v1.2.0) (2021-02-11) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.1.1...v1.2.0) + +**Merged pull requests:** + +- \(DIO-908\) Floaty can now report the status of ABS requests [\#131](https://github.com/puppetlabs/vmfloaty/pull/131) ([sbeaulie](https://github.com/sbeaulie)) +- Update rspec requirement from ~\> 3.9.0 to ~\> 3.10.0 [\#116](https://github.com/puppetlabs/vmfloaty/pull/116) ([dependabot[bot]](https://github.com/apps/dependabot)) + +## [v1.1.1](https://github.com/puppetlabs/vmfloaty/tree/v1.1.1) (2020-10-16) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.1.0...v1.1.1) + +**Merged pull requests:** + +- V1.1.1 [\#112](https://github.com/puppetlabs/vmfloaty/pull/112) ([sbeaulie](https://github.com/sbeaulie)) + +## [v1.1.0](https://github.com/puppetlabs/vmfloaty/tree/v1.1.0) (2020-10-09) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v1.0.0...v1.1.0) + +**Merged pull requests:** + +- \(maint\) Add more uniqueness to jobid and useful termination message [\#107](https://github.com/puppetlabs/vmfloaty/pull/107) ([sbeaulie](https://github.com/sbeaulie)) +- \(maint\) Fix bug with detecting ABS service [\#106](https://github.com/puppetlabs/vmfloaty/pull/106) ([sbeaulie](https://github.com/sbeaulie)) +- \(maint\) Don't require config file for list --active [\#105](https://github.com/puppetlabs/vmfloaty/pull/105) ([sbeaulie](https://github.com/sbeaulie)) +- \(maint\) Don't require configuration file for get [\#104](https://github.com/puppetlabs/vmfloaty/pull/104) ([nwolfe](https://github.com/nwolfe)) +- \(maint\) Add vmpooler\_fallback to the get service check [\#103](https://github.com/puppetlabs/vmfloaty/pull/103) ([cthorn42](https://github.com/cthorn42)) +- Update completion scripts for `service` subcommands [\#102](https://github.com/puppetlabs/vmfloaty/pull/102) ([scotje](https://github.com/scotje)) +- Bump to version 1.0.0 [\#100](https://github.com/puppetlabs/vmfloaty/pull/100) ([genebean](https://github.com/genebean)) + +## [v1.0.0](https://github.com/puppetlabs/vmfloaty/tree/v1.0.0) (2020-09-22) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/0.11.1...v1.0.0) + +**Merged pull requests:** + +- \(maint\) Fix for ABS PR\#306 that includes json responses [\#99](https://github.com/puppetlabs/vmfloaty/pull/99) ([sbeaulie](https://github.com/sbeaulie)) +- \(maint\) Support any vmpooler for ABS via vmpooler\_fallback [\#98](https://github.com/puppetlabs/vmfloaty/pull/98) ([sbeaulie](https://github.com/sbeaulie)) +- \(DIO-991\) Add service command [\#97](https://github.com/puppetlabs/vmfloaty/pull/97) ([genebean](https://github.com/genebean)) +- \( DIO-911\) Include job\_id in ABS --json output [\#96](https://github.com/puppetlabs/vmfloaty/pull/96) ([sbeaulie](https://github.com/sbeaulie)) +- ABS enables fallback to vmpooler for some scenarios [\#94](https://github.com/puppetlabs/vmfloaty/pull/94) ([sbeaulie](https://github.com/sbeaulie)) +- WIP \(DIO-911\) Include job\_id in ABS --json output [\#92](https://github.com/puppetlabs/vmfloaty/pull/92) ([nwolfe](https://github.com/nwolfe)) +- \(maint\) Remove warning about missing configuration file [\#91](https://github.com/puppetlabs/vmfloaty/pull/91) ([nwolfe](https://github.com/nwolfe)) +- Add tab completion script for zsh and fix bash completion for ABS services [\#90](https://github.com/puppetlabs/vmfloaty/pull/90) ([scotje](https://github.com/scotje)) + +## [0.11.1](https://github.com/puppetlabs/vmfloaty/tree/0.11.1) (2020-08-20) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/0.10.0...0.11.1) + +**Merged pull requests:** + +- Update version for 0.11.1 release [\#89](https://github.com/puppetlabs/vmfloaty/pull/89) ([mattkirby](https://github.com/mattkirby)) +- \(maint\) Fix using ABS service without a .vmfloaty.yml file [\#88](https://github.com/puppetlabs/vmfloaty/pull/88) ([cthorn42](https://github.com/cthorn42)) +- Fix the argument list for nonstandardpooler [\#87](https://github.com/puppetlabs/vmfloaty/pull/87) ([jarretlavallee](https://github.com/jarretlavallee)) +- Json output for delete/list + better ABS error handling [\#86](https://github.com/puppetlabs/vmfloaty/pull/86) ([mcdonaldseanp](https://github.com/mcdonaldseanp)) +- Bump version for 0.11.0 release [\#85](https://github.com/puppetlabs/vmfloaty/pull/85) ([mattkirby](https://github.com/mattkirby)) +- Print all non-success output to STDERR [\#84](https://github.com/puppetlabs/vmfloaty/pull/84) ([austb](https://github.com/austb)) +- Update travis.yml [\#83](https://github.com/puppetlabs/vmfloaty/pull/83) ([rooneyshuman](https://github.com/rooneyshuman)) +- Bump version to 0.10.0 for release [\#82](https://github.com/puppetlabs/vmfloaty/pull/82) ([mattkirby](https://github.com/mattkirby)) + +## [0.10.0](https://github.com/puppetlabs/vmfloaty/tree/0.10.0) (2020-08-04) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.9.2-retag-for-gh-actions-for-real...0.10.0) + +**Merged pull requests:** + +- Update Dependabot config file [\#78](https://github.com/puppetlabs/vmfloaty/pull/78) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Update rspec requirement from ~\> 3.5.0 to ~\> 3.9.0 [\#75](https://github.com/puppetlabs/vmfloaty/pull/75) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Update commander requirement from ~\> 4.4.3 to \>= 4.4.3, \< 4.6.0 [\#73](https://github.com/puppetlabs/vmfloaty/pull/73) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Fix formatting of CODEOWNERS [\#71](https://github.com/puppetlabs/vmfloaty/pull/71) ([genebean](https://github.com/genebean)) +- Add Dependabot and Coveralls [\#70](https://github.com/puppetlabs/vmfloaty/pull/70) ([genebean](https://github.com/genebean)) +- Update docs [\#69](https://github.com/puppetlabs/vmfloaty/pull/69) ([genebean](https://github.com/genebean)) +- Remove old maintainer note [\#68](https://github.com/puppetlabs/vmfloaty/pull/68) ([briancain](https://github.com/briancain)) +- Add support for vmpooler on demand provisioning [\#67](https://github.com/puppetlabs/vmfloaty/pull/67) ([mattkirby](https://github.com/mattkirby)) + +## [v0.9.2-retag-for-gh-actions-for-real](https://github.com/puppetlabs/vmfloaty/tree/v0.9.2-retag-for-gh-actions-for-real) (2020-02-05) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.9.2...v0.9.2-retag-for-gh-actions-for-real) + +**Merged pull requests:** + +- Update gempush action to remove GPR publish [\#66](https://github.com/puppetlabs/vmfloaty/pull/66) ([highb](https://github.com/highb)) + +## [v0.9.2](https://github.com/puppetlabs/vmfloaty/tree/v0.9.2) (2020-02-05) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.9.2-retag-for-gh-actions...v0.9.2) + +## [v0.9.2-retag-for-gh-actions](https://github.com/puppetlabs/vmfloaty/tree/v0.9.2-retag-for-gh-actions) (2020-02-05) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.9.0...v0.9.2-retag-for-gh-actions) + +**Merged pull requests:** + +- Bump version.rb to 0.9.2 for release [\#65](https://github.com/puppetlabs/vmfloaty/pull/65) ([highb](https://github.com/highb)) +- Create gempush.yml Github Action [\#64](https://github.com/puppetlabs/vmfloaty/pull/64) ([highb](https://github.com/highb)) +- Bump faraday dependency for Ruby 2.7 compatibility [\#62](https://github.com/puppetlabs/vmfloaty/pull/62) ([nicklewis](https://github.com/nicklewis)) +- SSH Command respects ABS now and tests should fail if the API changes… [\#61](https://github.com/puppetlabs/vmfloaty/pull/61) ([mikkergimenez](https://github.com/mikkergimenez)) +- \(QENG-7604\) Add support for Job IDs to ABS delete [\#60](https://github.com/puppetlabs/vmfloaty/pull/60) ([highb](https://github.com/highb)) +- Bump version.rb to 0.9.1 [\#59](https://github.com/puppetlabs/vmfloaty/pull/59) ([highb](https://github.com/highb)) +- Fix error with delete command for vmpooler and nspooler [\#58](https://github.com/puppetlabs/vmfloaty/pull/58) ([mikkergimenez](https://github.com/mikkergimenez)) + +## [v0.9.0](https://github.com/puppetlabs/vmfloaty/tree/v0.9.0) (2019-12-17) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.8.2...v0.9.0) + +**Implemented enhancements:** + +- Add abs vm get [\#53](https://github.com/puppetlabs/vmfloaty/pull/53) ([mikkergimenez](https://github.com/mikkergimenez)) + +**Fixed bugs:** + +- vmfloaty reports an error on latest API version output [\#48](https://github.com/puppetlabs/vmfloaty/issues/48) + +**Merged pull requests:** + +- ABS will sometimes return null values in the /status/queue endpoint [\#57](https://github.com/puppetlabs/vmfloaty/pull/57) ([mikkergimenez](https://github.com/mikkergimenez)) +- Minor version bump to 0.9.0 [\#56](https://github.com/puppetlabs/vmfloaty/pull/56) ([highb](https://github.com/highb)) +- Update pooler provider to throw an exception if the API returns non-OK [\#55](https://github.com/puppetlabs/vmfloaty/pull/55) ([highb](https://github.com/highb)) +- Update Faraday to 0.15, remove unnecessary headers [\#54](https://github.com/puppetlabs/vmfloaty/pull/54) ([highb](https://github.com/highb)) +- change urls in docs to use example.net/.com [\#50](https://github.com/puppetlabs/vmfloaty/pull/50) ([steveax](https://github.com/steveax)) +- Rubocop cleanup [\#49](https://github.com/puppetlabs/vmfloaty/pull/49) ([rodjek](https://github.com/rodjek)) + +## [v0.8.2](https://github.com/puppetlabs/vmfloaty/tree/v0.8.2) (2018-01-05) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.8.1...v0.8.2) + +**Merged pull requests:** + +- 🎂🎂🎂 Add --json option for `floaty get` [\#47](https://github.com/puppetlabs/vmfloaty/pull/47) ([nicklewis](https://github.com/nicklewis)) + +## [v0.8.1](https://github.com/puppetlabs/vmfloaty/tree/v0.8.1) (2017-10-24) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.8.0...v0.8.1) + +**Merged pull requests:** + +- Bump commander version to clear up deprecation warnings [\#46](https://github.com/puppetlabs/vmfloaty/pull/46) ([highb](https://github.com/highb)) + +## [v0.8.0](https://github.com/puppetlabs/vmfloaty/tree/v0.8.0) (2017-10-13) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.7.9...v0.8.0) + +**Closed issues:** + +- don't automatically call system pager for help screens [\#20](https://github.com/puppetlabs/vmfloaty/issues/20) + +**Merged pull requests:** + +- Add configuration for multiple pooler services and integration with nspooler [\#45](https://github.com/puppetlabs/vmfloaty/pull/45) ([caseywilliams](https://github.com/caseywilliams)) + +## [v0.7.9](https://github.com/puppetlabs/vmfloaty/tree/v0.7.9) (2017-07-31) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.7.8...v0.7.9) + +**Closed issues:** + +- Handle when vmfloaty cannot reach vmpooler [\#39](https://github.com/puppetlabs/vmfloaty/issues/39) + +**Merged pull requests:** + +- Add basic bash completion script and framework for others [\#44](https://github.com/puppetlabs/vmfloaty/pull/44) ([scotje](https://github.com/scotje)) +- Developersdevelopersdevelopers [\#43](https://github.com/puppetlabs/vmfloaty/pull/43) ([mckern](https://github.com/mckern)) + +## [v0.7.8](https://github.com/puppetlabs/vmfloaty/tree/v0.7.8) (2016-12-20) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.7.7...v0.7.8) + +## [v0.7.7](https://github.com/puppetlabs/vmfloaty/tree/v0.7.7) (2016-12-14) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.7.6...v0.7.7) + +## [v0.7.6](https://github.com/puppetlabs/vmfloaty/tree/v0.7.6) (2016-12-09) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/v0.7.5...v0.7.6) + +**Closed issues:** + +- Improve the help text for floaty commands [\#41](https://github.com/puppetlabs/vmfloaty/issues/41) +- Require force flag for pool requests larger than 5? [\#40](https://github.com/puppetlabs/vmfloaty/issues/40) + +## [v0.7.5](https://github.com/puppetlabs/vmfloaty/tree/v0.7.5) (2016-12-06) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/1f86113243eb2e898b21c29892c05477e3487d2d...v0.7.5) + +**Implemented enhancements:** + +- Improve how to specify number of vms in get request [\#8](https://github.com/puppetlabs/vmfloaty/issues/8) +- Improve output from commands [\#3](https://github.com/puppetlabs/vmfloaty/issues/3) + +**Fixed bugs:** + +- floaty snapshot fails to authenticate [\#4](https://github.com/puppetlabs/vmfloaty/issues/4) + +**Closed issues:** + +- floaty snapshot should warn users about how long it takes to get snapshot [\#37](https://github.com/puppetlabs/vmfloaty/issues/37) +- floaty modify should allow to make changes on more than one machine [\#36](https://github.com/puppetlabs/vmfloaty/issues/36) +- Pooler.modify raises exception if Token is nil [\#34](https://github.com/puppetlabs/vmfloaty/issues/34) +- Improve error handling in Pooler and Auth classes [\#33](https://github.com/puppetlabs/vmfloaty/issues/33) +- Handle vmpooler responses when token is invalid in Pooler class [\#32](https://github.com/puppetlabs/vmfloaty/issues/32) +- Misuse of 'floaty revert ...' seems to create a new snapshot [\#31](https://github.com/puppetlabs/vmfloaty/issues/31) +- Test [\#30](https://github.com/puppetlabs/vmfloaty/issues/30) +- Don't system exit in Auth class [\#29](https://github.com/puppetlabs/vmfloaty/issues/29) +- Add flag to auto-ssh into a newly created \(single\) VM [\#28](https://github.com/puppetlabs/vmfloaty/issues/28) +- Handle vmpooler URL key that doesn't have 'https' [\#27](https://github.com/puppetlabs/vmfloaty/issues/27) +- Abstract vmfloaty cli related errors to command class rather than pooler class [\#26](https://github.com/puppetlabs/vmfloaty/issues/26) +- Don't puts results in `delete` method in Pooler library [\#25](https://github.com/puppetlabs/vmfloaty/issues/25) +- Improve `get` output [\#24](https://github.com/puppetlabs/vmfloaty/issues/24) +- specs don't work [\#22](https://github.com/puppetlabs/vmfloaty/issues/22) +- Add ability to get additional disk space for a running vm [\#19](https://github.com/puppetlabs/vmfloaty/issues/19) +- Have a force option for `delete --all` [\#17](https://github.com/puppetlabs/vmfloaty/issues/17) +- Stop printing json response in library methods [\#14](https://github.com/puppetlabs/vmfloaty/issues/14) +- Stop system exiting in library methods [\#13](https://github.com/puppetlabs/vmfloaty/issues/13) +- List active vms for a given token [\#12](https://github.com/puppetlabs/vmfloaty/issues/12) +- Provide a way to clean up vms obtained by a token [\#11](https://github.com/puppetlabs/vmfloaty/issues/11) +- Allow spaces when passing in vms for commands [\#10](https://github.com/puppetlabs/vmfloaty/issues/10) +- Write Tests for Pooler class [\#9](https://github.com/puppetlabs/vmfloaty/issues/9) +- Document all valid config file keys [\#7](https://github.com/puppetlabs/vmfloaty/issues/7) +- Write up simple "introduction" to using the tool [\#6](https://github.com/puppetlabs/vmfloaty/issues/6) +- Document how to use Pooler class for ruby scripts [\#5](https://github.com/puppetlabs/vmfloaty/issues/5) +- Convert vmfloaty to use latest pooler API [\#1](https://github.com/puppetlabs/vmfloaty/issues/1) + +**Merged pull requests:** + +- Show the status of pools with `floaty status` [\#38](https://github.com/puppetlabs/vmfloaty/pull/38) ([nicklewis](https://github.com/nicklewis)) +- Show tag values in `list --active` [\#23](https://github.com/puppetlabs/vmfloaty/pull/23) ([justinstoller](https://github.com/justinstoller)) +- \(\#19\) Update vmfloaty to expect /api/v1 in URL for disk endpoint [\#21](https://github.com/puppetlabs/vmfloaty/pull/21) ([briancain](https://github.com/briancain)) +- \(\#17\) Add a force option for delete --all [\#18](https://github.com/puppetlabs/vmfloaty/pull/18) ([briancain](https://github.com/briancain)) +- \(\#12\) List active vms for a given token [\#16](https://github.com/puppetlabs/vmfloaty/pull/16) ([briancain](https://github.com/briancain)) +- Cleanup vmfloaty library and command processor [\#15](https://github.com/puppetlabs/vmfloaty/pull/15) ([briancain](https://github.com/briancain)) +- \(\#1\) Update with commander [\#2](https://github.com/puppetlabs/vmfloaty/pull/2) ([briancain](https://github.com/briancain)) + + + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From 4ab4d511f70b38bb3bb6180855e1d00e99f3aaf9 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 14:58:31 -0400 Subject: [PATCH 201/265] Add release instructions and reference docker image --- README.md | 53 ++++++++++++++++++++++++++++++++-------------------- release-prep | 12 ++++++++++++ 2 files changed, 45 insertions(+), 20 deletions(-) create mode 100755 release-prep diff --git a/README.md b/README.md index 15ec356..2aa2d31 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,48 @@ # vmfloaty [![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) -[![CI](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml/badge.svg)](https://github.com/puppetlabs/vmfloaty/actions/workflows/ci.yml) +[![Test](https://github.com/puppetlabs/vmfloaty/actions/workflows/test.yml/badge.svg)](https://github.com/puppetlabs/vmfloaty/actions/workflows/test.yml) A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat. ![float image](float.jpg) -- [Install](#install) -- [Usage](#usage) - - [Example workflow](#example-workflow) - - [vmfloaty dotfile](#vmfloaty-dotfile) - - [Basic configuration](#basic-configuration) - - [Using multiple services](#using-multiple-services) - - [Using backends besides VMPooler](#using-backends-besides-vmpooler) - - [Valid config keys](#valid-config-keys) - - [Tab Completion](#tab-completion) -- [VMPooler API](#vmpooler-api) -- [Using the Pooler class](#using-the-pooler-class) - - [Example Projects](#example-projects) -- [Contributing](#contributing) - - [Code Reviews](#code-reviews) -- [Releasing](#releasing) -- [Special thanks](#special-thanks) +- [vmfloaty](#vmfloaty) + - [Install](#install) + - [Ruby](#ruby) + - [Docker](#docker) + - [Usage](#usage) + - [Example workflow](#example-workflow) + - [vmfloaty dotfile](#vmfloaty-dotfile) + - [Basic configuration](#basic-configuration) + - [Using multiple services](#using-multiple-services) + - [Using backends besides VMPooler](#using-backends-besides-vmpooler) + - [Valid config keys](#valid-config-keys) + - [Tab Completion](#tab-completion) + - [VMPooler API](#vmpooler-api) + - [Using the Pooler class](#using-the-pooler-class) + - [Example Projects](#example-projects) + - [Contributing](#contributing) + - [Code Reviews](#code-reviews) + - [Releasing](#releasing) + - [Special thanks](#special-thanks) ## Install +### Ruby + Grab the latest from ruby gems... ```bash gem install vmfloaty ``` +### Docker + +Run the docker image: + +`docker run -it --rm -v ~/.vmfloaty.yml:/home/floatyuser/.vmfloaty.yml ghcr.io/puppetlabs/vmfloaty --help` + ## Usage ```plain @@ -177,10 +188,12 @@ Please wait for multiple code owners to sign off on any notable change. ## Releasing -Releasing is a two step process: +Follow these steps to publish a new GitHub release, build and push the gem to , and build and push a Docker Image to GitHub Container Registry: -1. Submit a release prep PR that updates `lib/vmfloaty/version.rb` to the desired new version and get that merged -2. Navigate to --> Run workflow --> select "main" branch --> Run workflow. This will publish a GitHub release, build, and push the gem to RubyGems. +1. Bump the "VERSION" in `lib/vmpooler/version.rb` appropriately based on changes in `CHANGELOG.md` since the last release. +2. Run `./release-prep` to update `Gemfile.lock` if necessary and `CHANGELOG.md`. +3. Commit and push changes to a new branch, then open a pull request against `main` and be sure to add the "maintenance" label. +4. After the pull request is approved and merged, then navigate to --> Run workflow --> select "main" branch --> Run workflow. This will publish a GitHub release, build and push the gem to RubyGems, and build and push a Docker Image to GitHub Container Registry. ## Special thanks diff --git a/release-prep b/release-prep new file mode 100755 index 0000000..d5bbb83 --- /dev/null +++ b/release-prep @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# bundle install +docker run -it --rm \ + -v $(pwd):/app \ + $(grep ^FROM ./Dockerfile |cut -d ' ' -f2) \ + /bin/bash -c 'apt-get update -qq && apt-get install -y --no-install-recommends build-essential make openssh-client && cd /app && gem install bundler && bundle install --jobs 3; echo "LOCK_FILE_UPDATE_EXIT_CODE=$?"' + +# Update Changelog +docker run -it --rm -e CHANGELOG_GITHUB_TOKEN -v $(pwd):/usr/local/src/your-app \ + githubchangeloggenerator/github-changelog-generator:1.16.2 \ + github_changelog_generator --future-release $(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev) From 9b669f6acaf720b7c067a7f77a714b3b629d7ea0 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 20 Mar 2023 15:20:21 -0400 Subject: [PATCH 202/265] Add Gemfile.lock --- .gitignore | 1 - Gemfile.lock | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index 1351382..76a21bc 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,6 @@ build/ # for a library or gem, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: -Gemfile.lock .ruby-version .ruby-gemset diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..45dfa5b --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,118 @@ +PATH + remote: . + specs: + vmfloaty (1.7.0) + commander (>= 4.4.3, < 4.7.0) + faraday (~> 1.5, >= 1.5.1) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + ast (2.4.2) + coderay (1.1.3) + commander (4.6.0) + highline (~> 2.0.0) + crack (0.4.5) + rexml + diff-lcs (1.5.0) + docile (1.4.0) + faraday (1.10.3) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + hashdiff (1.0.1) + highline (2.0.3) + json (2.6.3) + method_source (1.0.0) + multipart-post (2.3.0) + parallel (1.22.1) + parser (3.2.1.1) + ast (~> 2.4.1) + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + public_suffix (5.0.1) + rainbow (3.1.1) + rake (13.0.6) + rb-readline (0.5.5) + regexp_parser (2.7.0) + rexml (3.2.5) + rspec (3.11.0) + rspec-core (~> 3.11.0) + rspec-expectations (~> 3.11.0) + rspec-mocks (~> 3.11.0) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.11.0) + rspec-support (3.11.1) + rubocop (1.48.1) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.2.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.26.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.27.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) + simplecov (0.21.2) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.12.3) + simplecov-lcov (0.8.0) + simplecov_json_formatter (0.1.4) + unicode-display_width (2.4.2) + webmock (3.18.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + +PLATFORMS + aarch64-linux + x86_64-linux + +DEPENDENCIES + pry + rake + rb-readline + rspec (~> 3.11.0) + rubocop (~> 1.6) + simplecov (~> 0.21.2) + simplecov-html (~> 0.12.3) + simplecov-lcov (~> 0.8.0) + vmfloaty! + webmock (~> 3.13) + +BUNDLED WITH + 2.4.8 From f327e5d5eefd24b2127c0c812c60c2b0a6b7d791 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Tue, 21 Mar 2023 08:27:51 -0400 Subject: [PATCH 203/265] 1.8.0 release prep --- CHANGELOG.md | 12 ++++++++++-- Gemfile.lock | 2 +- README.md | 4 ++-- lib/vmfloaty/version.rb | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa063ee..51d6c56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,16 @@ # Changelog -## [Unreleased](https://github.com/puppetlabs/vmfloaty/tree/HEAD) +## [1.8.0](https://github.com/puppetlabs/vmfloaty/tree/1.8.0) (2023-03-21) -[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/1.7.0...HEAD) +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/1.7.0...1.8.0) + +**Implemented enhancements:** + +- Docker, Actions, and Docs Updates [\#170](https://github.com/puppetlabs/vmfloaty/pull/170) ([yachub](https://github.com/yachub)) + +**Fixed bugs:** + +- Fix `floaty list --active` for vmpooler api v2 [\#169](https://github.com/puppetlabs/vmfloaty/pull/169) ([yachub](https://github.com/yachub)) **Merged pull requests:** diff --git a/Gemfile.lock b/Gemfile.lock index 45dfa5b..b68d4e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - vmfloaty (1.7.0) + vmfloaty (1.8.0) commander (>= 4.4.3, < 4.7.0) faraday (~> 1.5, >= 1.5.1) diff --git a/README.md b/README.md index 2aa2d31..dfc22f9 100644 --- a/README.md +++ b/README.md @@ -190,8 +190,8 @@ Please wait for multiple code owners to sign off on any notable change. Follow these steps to publish a new GitHub release, build and push the gem to , and build and push a Docker Image to GitHub Container Registry: -1. Bump the "VERSION" in `lib/vmpooler/version.rb` appropriately based on changes in `CHANGELOG.md` since the last release. -2. Run `./release-prep` to update `Gemfile.lock` if necessary and `CHANGELOG.md`. +1. Bump the "VERSION" in `lib/vmfloaty/version.rb` appropriately based on changes in `CHANGELOG.md` since the last release. +2. Run `./release-prep` to update `Gemfile.lock` and `CHANGELOG.md`. 3. Commit and push changes to a new branch, then open a pull request against `main` and be sure to add the "maintenance" label. 4. After the pull request is approved and merged, then navigate to --> Run workflow --> select "main" branch --> Run workflow. This will publish a GitHub release, build and push the gem to RubyGems, and build and push a Docker Image to GitHub Container Registry. diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 28c2a9f..941f623 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.7.0' + VERSION = '1.8.0' end From 56757d6cb4c634ed898e682da7efc372923694e8 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Tue, 21 Mar 2023 14:17:16 -0400 Subject: [PATCH 204/265] Fix release workflow indentation --- .github/workflows/release.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 39b43e3..5c10569 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,18 +15,18 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 - with: - ref: ${{ github.ref }} - clean: true - fetch-depth: 0 + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + clean: true + fetch-depth: 0 - name: Get New Version - id: nv - run: | - version=$(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev) - echo "version=$version" >> $GITHUB_OUTPUT - echo "Found version $version from lib/vmfloaty/version.rb" + id: nv + run: | + version=$(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev) + echo "version=$version" >> $GITHUB_OUTPUT + echo "Found version $version from lib/vmfloaty/version.rb" - name: Get Current Version uses: actions/github-script@v6 From 2adf27a7e0c35923d74334770eea73caf6baba79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 09:56:45 +0000 Subject: [PATCH 205/265] Bump rubocop from 1.48.1 to 1.49.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.48.1 to 1.49.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.48.1...v1.49.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index acc82eb..90161b9 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.11.0' - gem 'rubocop', '~> 1.6' + gem 'rubocop', '~> 1.49' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index b68d4e0..3edc041 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,7 +47,7 @@ GEM method_source (1.0.0) multipart-post (2.3.0) parallel (1.22.1) - parser (3.2.1.1) + parser (3.2.2.0) ast (~> 2.4.1) pry (0.14.2) coderay (~> 1.1) @@ -71,17 +71,17 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-support (3.11.1) - rubocop (1.48.1) + rubocop (1.49.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.26.0, < 2.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.27.0) + rubocop-ast (1.28.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -107,7 +107,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.11.0) - rubocop (~> 1.6) + rubocop (~> 1.49) simplecov (~> 0.21.2) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 9de7ef163581f7b721d03714650fb2d4e12ac0c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 12:38:12 +0000 Subject: [PATCH 206/265] Update simplecov requirement from ~> 0.21.2 to ~> 0.22.0 Updates the requirements on [simplecov](https://github.com/simplecov-ruby/simplecov) to permit the latest version. - [Release notes](https://github.com/simplecov-ruby/simplecov/releases) - [Changelog](https://github.com/simplecov-ruby/simplecov/blob/main/CHANGELOG.md) - [Commits](https://github.com/simplecov-ruby/simplecov/compare/v0.21.2...v0.22.0) --- updated-dependencies: - dependency-name: simplecov dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 90161b9..3a6dae6 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gemspec gem 'rake', require: false group :test do - gem 'simplecov', '~> 0.21.2' + gem 'simplecov', '~> 0.22.0' gem 'simplecov-html', '~> 0.12.3' gem 'simplecov-lcov', '~> 0.8.0' gem 'pry' diff --git a/Gemfile.lock b/Gemfile.lock index 3edc041..ac84115 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -85,7 +85,7 @@ GEM parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) - simplecov (0.21.2) + simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) @@ -108,7 +108,7 @@ DEPENDENCIES rb-readline rspec (~> 3.11.0) rubocop (~> 1.49) - simplecov (~> 0.21.2) + simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) vmfloaty! From 5b7b3e69f3e7e6cb80a9c3294d7a9d522d58ceaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 13:08:53 +0000 Subject: [PATCH 207/265] Update rspec requirement from ~> 3.11.0 to ~> 3.12.0 Updates the requirements on [rspec](https://github.com/rspec/rspec-metagem) to permit the latest version. - [Release notes](https://github.com/rspec/rspec-metagem/releases) - [Commits](https://github.com/rspec/rspec-metagem/compare/v3.11.0...v3.12.0) --- updated-dependencies: - dependency-name: rspec dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 3a6dae6..6c042d1 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'simplecov-lcov', '~> 0.8.0' gem 'pry' gem 'rb-readline' - gem 'rspec', '~> 3.11.0' + gem 'rspec', '~> 3.12.0' gem 'rubocop', '~> 1.49' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index ac84115..71f8f50 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,19 +58,19 @@ GEM rb-readline (0.5.5) regexp_parser (2.7.0) rexml (3.2.5) - rspec (3.11.0) - rspec-core (~> 3.11.0) - rspec-expectations (~> 3.11.0) - rspec-mocks (~> 3.11.0) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.1) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.1) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-mocks (3.11.2) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-support (3.11.1) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) rubocop (1.49.0) json (~> 2.3) parallel (~> 1.10) @@ -106,7 +106,7 @@ DEPENDENCIES pry rake rb-readline - rspec (~> 3.11.0) + rspec (~> 3.12.0) rubocop (~> 1.49) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) From 6b6bf539ccf5f25458ccbed61c274312d4d0e1d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 09:56:44 +0000 Subject: [PATCH 208/265] Bump rubocop from 1.49.0 to 1.50.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.49.0 to 1.50.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.49.0...v1.50.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 6c042d1..c473eb6 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.49' + gem 'rubocop', '~> 1.50' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index 71f8f50..f5c23ce 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,7 +71,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.49.0) + rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) @@ -107,7 +107,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.49) + rubocop (~> 1.50) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 6fa018d0b1470636b575f084b6db4d514960b181 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Thu, 20 Apr 2023 08:52:58 -0400 Subject: [PATCH 209/265] Migrate issue management to Jira --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index dfc22f9..92ff0b9 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler - [Example Projects](#example-projects) - [Contributing](#contributing) - [Code Reviews](#code-reviews) + - [Submitting Issues](#submitting-issues) - [Releasing](#releasing) - [Special thanks](#special-thanks) @@ -186,6 +187,10 @@ PR's are welcome! We always love to see how others think this tool can be made b Please wait for multiple code owners to sign off on any notable change. +## Submitting Issues + +Please file any issues or requests in Jira at where project development is tracked across all VMPooler related components. + ## Releasing Follow these steps to publish a new GitHub release, build and push the gem to , and build and push a Docker Image to GitHub Container Registry: From ff6ee2ddd8646646aaaa10fb3365126aed574dd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 09:56:34 +0000 Subject: [PATCH 210/265] Bump rubocop from 1.50.2 to 1.51.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.50.2 to 1.51.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.50.2...v1.51.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index c473eb6..062a05f 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.50' + gem 'rubocop', '~> 1.51' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index f5c23ce..c5d7065 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -46,8 +46,8 @@ GEM json (2.6.3) method_source (1.0.0) multipart-post (2.3.0) - parallel (1.22.1) - parser (3.2.2.0) + parallel (1.23.0) + parser (3.2.2.1) ast (~> 2.4.1) pry (0.14.2) coderay (~> 1.1) @@ -56,7 +56,7 @@ GEM rainbow (3.1.1) rake (13.0.6) rb-readline (0.5.5) - regexp_parser (2.7.0) + regexp_parser (2.8.0) rexml (3.2.5) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -71,7 +71,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.50.2) + rubocop (1.51.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) @@ -81,7 +81,7 @@ GEM rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.28.0) + rubocop-ast (1.28.1) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -107,7 +107,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.50) + rubocop (~> 1.51) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 0d7119bb8a0d5648ef35779a581e2d9534c5bed2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 09:56:37 +0000 Subject: [PATCH 211/265] Bump rubocop from 1.51.0 to 1.52.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.51.0 to 1.52.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.51.0...v1.52.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 062a05f..0c2b45f 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.51' + gem 'rubocop', '~> 1.52' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index c5d7065..a466597 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,7 +71,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.51.0) + rubocop (1.52.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) @@ -81,7 +81,7 @@ GEM rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.28.1) + rubocop-ast (1.29.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -107,7 +107,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.51) + rubocop (~> 1.52) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 3702cc8c98af9a745be8082d423aa8b7771975de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 09:56:10 +0000 Subject: [PATCH 212/265] Bump rubocop from 1.52.0 to 1.54.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.52.0 to 1.54.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.52.0...v1.54.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 0c2b45f..2d288e2 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.52' + gem 'rubocop', '~> 1.54' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index a466597..4704632 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -44,19 +44,22 @@ GEM hashdiff (1.0.1) highline (2.0.3) json (2.6.3) + language_server-protocol (3.17.0.3) method_source (1.0.0) multipart-post (2.3.0) parallel (1.23.0) - parser (3.2.2.1) + parser (3.2.2.3) ast (~> 2.4.1) + racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) public_suffix (5.0.1) + racc (1.7.1) rainbow (3.1.1) rake (13.0.6) rb-readline (0.5.5) - regexp_parser (2.8.0) + regexp_parser (2.8.1) rexml (3.2.5) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -71,10 +74,11 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.52.0) + rubocop (1.54.2) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.2.2.3) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) @@ -107,7 +111,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.52) + rubocop (~> 1.54) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From a4e006615ee09c877201ed5ac155177fa37ce4d3 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Thu, 20 Apr 2023 08:52:58 -0400 Subject: [PATCH 213/265] Revert "Migrate issue management to Jira" This reverts commit 6fa018d0b1470636b575f084b6db4d514960b181. --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 92ff0b9..dfc22f9 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler - [Example Projects](#example-projects) - [Contributing](#contributing) - [Code Reviews](#code-reviews) - - [Submitting Issues](#submitting-issues) - [Releasing](#releasing) - [Special thanks](#special-thanks) @@ -187,10 +186,6 @@ PR's are welcome! We always love to see how others think this tool can be made b Please wait for multiple code owners to sign off on any notable change. -## Submitting Issues - -Please file any issues or requests in Jira at where project development is tracked across all VMPooler related components. - ## Releasing Follow these steps to publish a new GitHub release, build and push the gem to , and build and push a Docker Image to GitHub Container Registry: From 6b041f5c48d1f8809e68d763749b3fee421417fc Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 7 Aug 2023 11:31:37 -0400 Subject: [PATCH 214/265] Use relative path for pooler status and summary --- lib/vmfloaty/pooler.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vmfloaty/pooler.rb b/lib/vmfloaty/pooler.rb index 855e604..9d47407 100644 --- a/lib/vmfloaty/pooler.rb +++ b/lib/vmfloaty/pooler.rb @@ -146,14 +146,14 @@ class Pooler def self.status(verbose, url) conn = Http.get_conn(verbose, url) - response = conn.get '/status' + response = conn.get 'status' JSON.parse(response.body) end def self.summary(verbose, url) conn = Http.get_conn(verbose, url) - response = conn.get '/summary' + response = conn.get 'summary' JSON.parse(response.body) end From 7b24c8136003d1792d647842db719c4f87560f26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:59:07 +0000 Subject: [PATCH 215/265] Bump rubocop from 1.54.2 to 1.55.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.54.2 to 1.55.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.54.2...v1.55.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 2d288e2..856b39c 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.54' + gem 'rubocop', '~> 1.55' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index 4704632..31cedf0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -60,7 +60,7 @@ GEM rake (13.0.6) rb-readline (0.5.5) regexp_parser (2.8.1) - rexml (3.2.5) + rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) rspec-expectations (~> 3.12.0) @@ -74,7 +74,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.54.2) + rubocop (1.55.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -82,7 +82,7 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) + rubocop-ast (>= 1.28.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.29.0) @@ -111,7 +111,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.54) + rubocop (~> 1.55) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 8daf63665dc3bf730d56be5c790ca48139509b85 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 7 Aug 2023 16:11:06 -0400 Subject: [PATCH 216/265] Bump docker tag to latest used in test matrix --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 700e7bf..5c3a5e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.1.3-slim-bullseye +FROM ruby:3.2.2-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty" From 06127d7e67da78f17852b81c5edbde2d2923b4db Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 7 Aug 2023 16:13:19 -0400 Subject: [PATCH 217/265] 1.8.1 release prep --- CHANGELOG.md | 20 ++++++++++++++++++++ Gemfile.lock | 2 +- lib/vmfloaty/version.rb | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51d6c56..ff7c73f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [1.8.1](https://github.com/puppetlabs/vmfloaty/tree/1.8.1) (2023-08-07) + +[Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/1.8.0...1.8.1) + +**Fixed bugs:** + +- status and summary broken for pooler service after v3 [\#185](https://github.com/puppetlabs/vmfloaty/issues/185) +- \(RE-15687\) Use relative path for pooler status and summary [\#186](https://github.com/puppetlabs/vmfloaty/pull/186) ([yachub](https://github.com/yachub)) + +**Merged pull requests:** + +- Bump rubocop from 1.54.2 to 1.55.1 [\#183](https://github.com/puppetlabs/vmfloaty/pull/183) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rubocop from 1.52.0 to 1.54.2 [\#182](https://github.com/puppetlabs/vmfloaty/pull/182) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rubocop from 1.51.0 to 1.52.0 [\#177](https://github.com/puppetlabs/vmfloaty/pull/177) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rubocop from 1.50.2 to 1.51.0 [\#176](https://github.com/puppetlabs/vmfloaty/pull/176) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rubocop from 1.49.0 to 1.50.2 [\#174](https://github.com/puppetlabs/vmfloaty/pull/174) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rubocop from 1.48.1 to 1.49.0 [\#173](https://github.com/puppetlabs/vmfloaty/pull/173) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Update simplecov requirement from ~\> 0.21.2 to ~\> 0.22.0 [\#167](https://github.com/puppetlabs/vmfloaty/pull/167) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Update rspec requirement from ~\> 3.11.0 to ~\> 3.12.0 [\#166](https://github.com/puppetlabs/vmfloaty/pull/166) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [1.8.0](https://github.com/puppetlabs/vmfloaty/tree/1.8.0) (2023-03-21) [Full Changelog](https://github.com/puppetlabs/vmfloaty/compare/1.7.0...1.8.0) diff --git a/Gemfile.lock b/Gemfile.lock index 31cedf0..11f156f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - vmfloaty (1.8.0) + vmfloaty (1.8.1) commander (>= 4.4.3, < 4.7.0) faraday (~> 1.5, >= 1.5.1) diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb index 941f623..aab63a3 100644 --- a/lib/vmfloaty/version.rb +++ b/lib/vmfloaty/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Vmfloaty - VERSION = '1.8.0' + VERSION = '1.8.1' end From ebede7799d8227d400b68b1501e021ebdd05756d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 09:43:18 +0000 Subject: [PATCH 218/265] Bump rubocop from 1.55.1 to 1.56.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.55.1 to 1.56.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.55.1...v1.56.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 856b39c..f2b60cd 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.55' + gem 'rubocop', '~> 1.56' gem 'webmock', '~> 3.13' end diff --git a/Gemfile.lock b/Gemfile.lock index 11f156f..ad6b40a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,6 +11,7 @@ GEM addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) + base64 (0.1.1) coderay (1.1.3) commander (4.6.0) highline (~> 2.0.0) @@ -74,7 +75,8 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.55.1) + rubocop (1.56.0) + base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -111,7 +113,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.55) + rubocop (~> 1.56) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 7f06fbd0bc31a6d9d4a88a207cba806475a6596f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 09:31:07 +0000 Subject: [PATCH 219/265] Bump rubocop from 1.56.0 to 1.56.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.0 to 1.56.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.0...v1.56.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ad6b40a..2ed9f1c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.56.0) + rubocop (1.56.1) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) From 6afb47c6094c551bd3f29c87823eb585383795ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:41:09 +0000 Subject: [PATCH 220/265] Bump webmock from 3.18.1 to 3.19.0 Bumps [webmock](https://github.com/bblimke/webmock) from 3.18.1 to 3.19.0. - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.18.1...v3.19.0) --- updated-dependencies: - dependency-name: webmock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index f2b60cd..1193321 100644 --- a/Gemfile +++ b/Gemfile @@ -14,5 +14,5 @@ group :test do gem 'rb-readline' gem 'rspec', '~> 3.12.0' gem 'rubocop', '~> 1.56' - gem 'webmock', '~> 3.13' + gem 'webmock', '~> 3.19' end diff --git a/Gemfile.lock b/Gemfile.lock index 2ed9f1c..baf4d2e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ PATH GEM remote: https://rubygems.org/ specs: - addressable (2.8.1) + addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) base64 (0.1.1) @@ -55,7 +55,7 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.1) + public_suffix (5.0.3) racc (1.7.1) rainbow (3.1.1) rake (13.0.6) @@ -99,7 +99,7 @@ GEM simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) unicode-display_width (2.4.2) - webmock (3.18.1) + webmock (3.19.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -118,7 +118,7 @@ DEPENDENCIES simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) vmfloaty! - webmock (~> 3.13) + webmock (~> 3.19) BUNDLED WITH 2.4.8 From ae42ba08ae6da815a2ab202960981669c90dd623 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 09:18:54 +0000 Subject: [PATCH 221/265] Bump webmock from 3.19.0 to 3.19.1 Bumps [webmock](https://github.com/bblimke/webmock) from 3.19.0 to 3.19.1. - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.19.0...v3.19.1) --- updated-dependencies: - dependency-name: webmock dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index baf4d2e..c3f748d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,7 +99,7 @@ GEM simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) unicode-display_width (2.4.2) - webmock (3.19.0) + webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) From 75cd758aad35ba9021bacbf845581084efa8bb20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 09:19:02 +0000 Subject: [PATCH 222/265] Bump rubocop from 1.56.1 to 1.56.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.1 to 1.56.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.1...v1.56.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index baf4d2e..89c6de0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.56.1) + rubocop (1.56.2) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) From a2bf9ead58a00abf43d17630e48e59be2161fdb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:11:43 +0000 Subject: [PATCH 223/265] Bump rubocop from 1.56.2 to 1.56.3 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.2 to 1.56.3. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.2...v1.56.3) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b30e646..5a2491d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.56.2) + rubocop (1.56.3) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) From 9f72be51269f00d07478a95b6dfa78a01f190f67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:36:32 +0000 Subject: [PATCH 224/265] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- .github/workflows/security.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5c10569..d2c6575 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ github.ref }} clean: true diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 666c602..30e3388 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout repo content - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 - name: setup ruby diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b9576f..8562713 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,7 +24,7 @@ jobs: - '3.2' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Ruby # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, # change this to (see https://github.com/ruby/setup-ruby#versioning): From ded2cd69dd61d4888416da25b5048b22680f6185 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:50:18 +0000 Subject: [PATCH 225/265] Bump docker/build-push-action from 4 to 5 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2c6575..1b6c55d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,7 +92,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: push: true tags: | From f77bb2b29a88d29975df3db5d900d629f2fc68e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:50:21 +0000 Subject: [PATCH 226/265] Bump docker/setup-buildx-action from 2 to 3 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2c6575..bedcb6d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,7 +82,7 @@ jobs: prerelease: false - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v2 From df45ec0180fb71f7a0defae4cd3ad03e2f379c25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:50:25 +0000 Subject: [PATCH 227/265] Bump docker/login-action from 2 to 3 Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2c6575..ec0d252 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,7 +85,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} From c5ea73a3ad06d042eec6db2934dee7f9eb465f15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:05:59 +0000 Subject: [PATCH 228/265] Bump rubocop from 1.56.3 to 1.56.4 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.3 to 1.56.4. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.3...v1.56.4) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5a2491d..1927fcd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.56.3) + rubocop (1.56.4) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) @@ -98,7 +98,7 @@ GEM simplecov-html (0.12.3) simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) - unicode-display_width (2.4.2) + unicode-display_width (2.5.0) webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) From 5953ad89a4dad817616003bace2e2e45611f7548 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Tue, 5 Dec 2023 17:16:18 -0500 Subject: [PATCH 229/265] syncing files from release-engineering-repo-standards --- .github/dependabot.yml | 26 +++++++++++++++---------- .github/workflows/auto_release_prep.yml | 11 +++++++++++ .github/workflows/dependabot_merge.yml | 8 ++++++++ .github/workflows/ensure_label.yml | 8 ++++++++ 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/auto_release_prep.yml create mode 100644 .github/workflows/dependabot_merge.yml create mode 100644 .github/workflows/ensure_label.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1afdd73..90d6dfd 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,13 +1,19 @@ version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - open-pull-requests-limit: 10 +- package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 - - package-ecosystem: bundler - directory: "/" - schedule: - interval: weekly - open-pull-requests-limit: 10 +- package-ecosystem: docker + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 + +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 diff --git a/.github/workflows/auto_release_prep.yml b/.github/workflows/auto_release_prep.yml new file mode 100644 index 0000000..00f6964 --- /dev/null +++ b/.github/workflows/auto_release_prep.yml @@ -0,0 +1,11 @@ +name: Automated release prep + +on: + workflow_dispatch: + +jobs: + auto_release_prep: + uses: puppetlabs/release-engineering-repo-standards/.github/workflows/auto_release_prep.yml@v1 + secrets: inherit + with: + version-file-path: lib/vmfloaty/version.rb diff --git a/.github/workflows/dependabot_merge.yml b/.github/workflows/dependabot_merge.yml new file mode 100644 index 0000000..75b9cea --- /dev/null +++ b/.github/workflows/dependabot_merge.yml @@ -0,0 +1,8 @@ +name: Dependabot auto-merge + +on: pull_request + +jobs: + dependabot_merge: + uses: puppetlabs/release-engineering-repo-standards/.github/workflows/dependabot_merge.yml@v1 + secrets: inherit diff --git a/.github/workflows/ensure_label.yml b/.github/workflows/ensure_label.yml new file mode 100644 index 0000000..50a5fa8 --- /dev/null +++ b/.github/workflows/ensure_label.yml @@ -0,0 +1,8 @@ +name: Ensure label + +on: pull_request + +jobs: + ensure_label: + uses: puppetlabs/release-engineering-repo-standards/.github/workflows/ensure_label.yml@v1 + secrets: inherit From 03ebf1d79a3d460611c49415a1bab0ca94439df6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:45:52 +0000 Subject: [PATCH 230/265] Bump rake from 13.0.6 to 13.1.0 Bumps [rake](https://github.com/ruby/rake) from 13.0.6 to 13.1.0. - [Release notes](https://github.com/ruby/rake/releases) - [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc) - [Commits](https://github.com/ruby/rake/compare/v13.0.6...v13.1.0) --- updated-dependencies: - dependency-name: rake dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1927fcd..6dbe520 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GEM public_suffix (5.0.3) racc (1.7.1) rainbow (3.1.1) - rake (13.0.6) + rake (13.1.0) rb-readline (0.5.5) regexp_parser (2.8.1) rexml (3.2.6) From 494bd3412cccba537ff17b7914d53ea62d3201b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:50:01 +0000 Subject: [PATCH 231/265] Bump actions/github-script from 6 to 7 Bumps [actions/github-script](https://github.com/actions/github-script) from 6 to 7. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b75f39b..d79ed5f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: echo "Found version $version from lib/vmfloaty/version.rb" - name: Get Current Version - uses: actions/github-script@v6 + uses: actions/github-script@v7 id: cv with: script: | From 05ae2e55daec2936dfef930b29df7c9c4821eef4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:14:46 +0000 Subject: [PATCH 232/265] Bump rubocop from 1.56.4 to 1.58.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.4 to 1.58.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.4...v1.58.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index 1193321..932cd12 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.56' + gem 'rubocop', '~> 1.58' gem 'webmock', '~> 3.19' end diff --git a/Gemfile.lock b/Gemfile.lock index 6dbe520..31f19ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,6 @@ GEM addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) - base64 (0.1.1) coderay (1.1.3) commander (4.6.0) highline (~> 2.0.0) @@ -44,23 +43,23 @@ GEM faraday-retry (1.0.3) hashdiff (1.0.1) highline (2.0.3) - json (2.6.3) + json (2.7.1) language_server-protocol (3.17.0.3) method_source (1.0.0) multipart-post (2.3.0) parallel (1.23.0) - parser (3.2.2.3) + parser (3.2.2.4) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) public_suffix (5.0.3) - racc (1.7.1) + racc (1.7.3) rainbow (3.1.1) rake (13.1.0) rb-readline (0.5.5) - regexp_parser (2.8.1) + regexp_parser (2.8.3) rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -75,19 +74,18 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.56.4) - base64 (~> 0.1.1) + rubocop (1.58.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -113,7 +111,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.56) + rubocop (~> 1.58) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 93ecadf49ac4513110bcc527385264c8b603814d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:14:53 +0000 Subject: [PATCH 233/265] Bump actions/setup-java from 3 to 4 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/security.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 30e3388..ba273f5 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -22,7 +22,7 @@ jobs: - name: check lock run: '[ -f "Gemfile.lock" ] && echo "package lock file exists, skipping" || bundle lock' # install java - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '17' From 85ae0c9914ae8539364c8d04bf06d15a4986a35b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 09:05:38 +0000 Subject: [PATCH 234/265] Bump rubocop from 1.58.0 to 1.59.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.58.0 to 1.59.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.58.0...v1.59.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 932cd12..700a03f 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.58' + gem 'rubocop', '~> 1.59' gem 'webmock', '~> 3.19' end diff --git a/Gemfile.lock b/Gemfile.lock index 31f19ec..a556047 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,7 +47,7 @@ GEM language_server-protocol (3.17.0.3) method_source (1.0.0) multipart-post (2.3.0) - parallel (1.23.0) + parallel (1.24.0) parser (3.2.2.4) ast (~> 2.4.1) racc @@ -74,7 +74,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.58.0) + rubocop (1.59.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -111,7 +111,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.58) + rubocop (~> 1.59) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 375eb6b9fded28d3c61eb74a5ab210da0fc77a8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 09:15:12 +0000 Subject: [PATCH 235/265] Bump ruby from 3.2.2-slim-bullseye to 3.3.0-slim-bullseye Bumps ruby from 3.2.2-slim-bullseye to 3.3.0-slim-bullseye. --- updated-dependencies: - dependency-name: ruby dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5c3a5e1..87f4db5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.2.2-slim-bullseye +FROM ruby:3.3.0-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty" From 50d3088ad8c0577b99c7349995514052c3706c79 Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Mon, 15 Jan 2024 09:24:30 -0500 Subject: [PATCH 236/265] Fix missing param in auto_release_prep --- .github/workflows/auto_release_prep.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/auto_release_prep.yml b/.github/workflows/auto_release_prep.yml index 00f6964..19380e9 100644 --- a/.github/workflows/auto_release_prep.yml +++ b/.github/workflows/auto_release_prep.yml @@ -8,4 +8,5 @@ jobs: uses: puppetlabs/release-engineering-repo-standards/.github/workflows/auto_release_prep.yml@v1 secrets: inherit with: + project-type: ruby version-file-path: lib/vmfloaty/version.rb From 4c9c82a7c235164e9d1ff64c89e6948f3a1dd2db Mon Sep 17 00:00:00 2001 From: Jake Spain Date: Fri, 19 Jan 2024 14:28:21 -0500 Subject: [PATCH 237/265] Remove interactive option from release prep script --- release-prep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release-prep b/release-prep index d5bbb83..82ee104 100755 --- a/release-prep +++ b/release-prep @@ -1,12 +1,12 @@ #!/usr/bin/env bash # bundle install -docker run -it --rm \ +docker run -t --rm \ -v $(pwd):/app \ $(grep ^FROM ./Dockerfile |cut -d ' ' -f2) \ /bin/bash -c 'apt-get update -qq && apt-get install -y --no-install-recommends build-essential make openssh-client && cd /app && gem install bundler && bundle install --jobs 3; echo "LOCK_FILE_UPDATE_EXIT_CODE=$?"' # Update Changelog -docker run -it --rm -e CHANGELOG_GITHUB_TOKEN -v $(pwd):/usr/local/src/your-app \ +docker run -t --rm -e CHANGELOG_GITHUB_TOKEN -v $(pwd):/usr/local/src/your-app \ githubchangeloggenerator/github-changelog-generator:1.16.2 \ github_changelog_generator --future-release $(grep VERSION lib/vmfloaty/version.rb |rev |cut -d "'" -f2 |rev) From 0352a687c6c9ec3a5d0e86bf08e852fda9312818 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 09:22:11 +0000 Subject: [PATCH 238/265] Bump rubocop from 1.59.0 to 1.60.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.59.0 to 1.60.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.59.0...v1.60.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 700a03f..eb22dd9 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.12.0' - gem 'rubocop', '~> 1.59' + gem 'rubocop', '~> 1.60' gem 'webmock', '~> 3.19' end diff --git a/Gemfile.lock b/Gemfile.lock index a556047..b315196 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -48,7 +48,7 @@ GEM method_source (1.0.0) multipart-post (2.3.0) parallel (1.24.0) - parser (3.2.2.4) + parser (3.3.0.5) ast (~> 2.4.1) racc pry (0.14.2) @@ -59,7 +59,7 @@ GEM rainbow (3.1.1) rake (13.1.0) rb-readline (0.5.5) - regexp_parser (2.8.3) + regexp_parser (2.9.0) rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -74,11 +74,11 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.59.0) + rubocop (1.60.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) @@ -111,7 +111,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.12.0) - rubocop (~> 1.59) + rubocop (~> 1.60) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From cd412f8a078b4dd44e4f7f3cac47bc2d8142c2a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 09:02:48 +0000 Subject: [PATCH 239/265] Bump rubocop from 1.60.1 to 1.60.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.60.1 to 1.60.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.60.1...v1.60.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b315196..43ccd3d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,7 +74,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.0) - rubocop (1.60.1) + rubocop (1.60.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From cc018b0599f487da5714adeef788f109166a099a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:32:57 +0000 Subject: [PATCH 240/265] Bump rspec from 3.12.0 to 3.13.0 Bumps [rspec](https://github.com/rspec/rspec-metagem) from 3.12.0 to 3.13.0. - [Commits](https://github.com/rspec/rspec-metagem/compare/v3.12.0...v3.13.0) --- updated-dependencies: - dependency-name: rspec dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Gemfile b/Gemfile index eb22dd9..5bed03d 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'simplecov-lcov', '~> 0.8.0' gem 'pry' gem 'rb-readline' - gem 'rspec', '~> 3.12.0' + gem 'rspec', '~> 3.13.0' gem 'rubocop', '~> 1.60' gem 'webmock', '~> 3.19' end diff --git a/Gemfile.lock b/Gemfile.lock index 43ccd3d..46ebed2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,7 +16,7 @@ GEM highline (~> 2.0.0) crack (0.4.5) rexml - diff-lcs (1.5.0) + diff-lcs (1.5.1) docile (1.4.0) faraday (1.10.3) faraday-em_http (~> 1.0) @@ -61,19 +61,19 @@ GEM rb-readline (0.5.5) regexp_parser (2.9.0) rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.1) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.2) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.5) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.0) rubocop (1.60.2) json (~> 2.3) language_server-protocol (>= 3.17.0) @@ -110,7 +110,7 @@ DEPENDENCIES pry rake rb-readline - rspec (~> 3.12.0) + rspec (~> 3.13.0) rubocop (~> 1.60) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) From a5d5cdc53f45ec5d2c8613f2825f5d823807659b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 09:50:28 +0000 Subject: [PATCH 241/265] Bump webmock from 3.19.1 to 3.20.0 Bumps [webmock](https://github.com/bblimke/webmock) from 3.19.1 to 3.20.0. - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.19.1...v3.20.0) --- updated-dependencies: - dependency-name: webmock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 5bed03d..c9ae6ed 100644 --- a/Gemfile +++ b/Gemfile @@ -14,5 +14,5 @@ group :test do gem 'rb-readline' gem 'rspec', '~> 3.13.0' gem 'rubocop', '~> 1.60' - gem 'webmock', '~> 3.19' + gem 'webmock', '~> 3.20' end diff --git a/Gemfile.lock b/Gemfile.lock index 46ebed2..520908c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,13 +8,15 @@ PATH GEM remote: https://rubygems.org/ specs: - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) + bigdecimal (3.1.6) coderay (1.1.3) commander (4.6.0) highline (~> 2.0.0) - crack (0.4.5) + crack (1.0.0) + bigdecimal rexml diff-lcs (1.5.1) docile (1.4.0) @@ -41,7 +43,7 @@ GEM faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - hashdiff (1.0.1) + hashdiff (1.1.0) highline (2.0.3) json (2.7.1) language_server-protocol (3.17.0.3) @@ -54,7 +56,7 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.3) + public_suffix (5.0.4) racc (1.7.3) rainbow (3.1.1) rake (13.1.0) @@ -97,7 +99,7 @@ GEM simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) unicode-display_width (2.5.0) - webmock (3.19.1) + webmock (3.20.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -116,7 +118,7 @@ DEPENDENCIES simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) vmfloaty! - webmock (~> 3.19) + webmock (~> 3.20) BUNDLED WITH 2.4.8 From df08f383fe5a0d6d261b48653175724eeb2fa838 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:37:08 +0000 Subject: [PATCH 242/265] Bump webmock from 3.20.0 to 3.23.0 Bumps [webmock](https://github.com/bblimke/webmock) from 3.20.0 to 3.23.0. - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.20.0...v3.23.0) --- updated-dependencies: - dependency-name: webmock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index c9ae6ed..a6308e5 100644 --- a/Gemfile +++ b/Gemfile @@ -14,5 +14,5 @@ group :test do gem 'rb-readline' gem 'rspec', '~> 3.13.0' gem 'rubocop', '~> 1.60' - gem 'webmock', '~> 3.20' + gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index 520908c..1ed5116 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,7 +99,7 @@ GEM simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) unicode-display_width (2.5.0) - webmock (3.20.0) + webmock (3.23.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -118,7 +118,7 @@ DEPENDENCIES simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) vmfloaty! - webmock (~> 3.20) + webmock (~> 3.23) BUNDLED WITH 2.4.8 From 961e3d9b3d33ca7bc53a96f3a9feba15586eaf59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:54:41 +0000 Subject: [PATCH 243/265] Bump rubocop from 1.60.2 to 1.61.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.60.2 to 1.61.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.60.2...v1.61.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index a6308e5..d8b7277 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.13.0' - gem 'rubocop', '~> 1.60' + gem 'rubocop', '~> 1.61' gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index 1ed5116..cfe20d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.60.2) + rubocop (1.61.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -87,8 +87,8 @@ GEM rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) + rubocop-ast (1.31.1) + parser (>= 3.3.0.4) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) simplecov (0.22.0) @@ -113,7 +113,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.13.0) - rubocop (~> 1.60) + rubocop (~> 1.61) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From c0609d87b7c3a7a5149a2b1723bc679e1ca39113 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 09:05:24 +0000 Subject: [PATCH 244/265] Bump rubocop from 1.61.0 to 1.62.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.61.0 to 1.62.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.61.0...v1.62.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index d8b7277..fbffd69 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.13.0' - gem 'rubocop', '~> 1.61' + gem 'rubocop', '~> 1.62' gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index cfe20d8..a1e2417 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.61.0) + rubocop (1.62.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -84,10 +84,10 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.1) + rubocop-ast (1.31.2) parser (>= 3.3.0.4) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -113,7 +113,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.13.0) - rubocop (~> 1.61) + rubocop (~> 1.62) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From e58a1eb68e3fb8bcb5042fddfdba6eacf5c25ac6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:15:14 +0000 Subject: [PATCH 245/265] Bump rubocop from 1.62.0 to 1.62.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.62.0 to 1.62.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.62.0...v1.62.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a1e2417..a061878 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.62.0) + rubocop (1.62.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From c1f93e40f7bca69d4295540d6bc43f0d8d83be55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:13:47 +0000 Subject: [PATCH 246/265] Bump rake from 13.1.0 to 13.2.1 Bumps [rake](https://github.com/ruby/rake) from 13.1.0 to 13.2.1. - [Release notes](https://github.com/ruby/rake/releases) - [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc) - [Commits](https://github.com/ruby/rake/compare/v13.1.0...v13.2.1) --- updated-dependencies: - dependency-name: rake dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a061878..08e4efa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,7 +59,7 @@ GEM public_suffix (5.0.4) racc (1.7.3) rainbow (3.1.1) - rake (13.1.0) + rake (13.2.1) rb-readline (0.5.5) regexp_parser (2.9.0) rexml (3.2.6) From 03d7bb7963c1201139e51b74c981ed2cd6783bd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:13:58 +0000 Subject: [PATCH 247/265] Bump rubocop from 1.62.1 to 1.63.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.62.1 to 1.63.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.62.1...v1.63.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index fbffd69..c363bce 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.13.0' - gem 'rubocop', '~> 1.62' + gem 'rubocop', '~> 1.63' gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index a061878..1f53f6c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,7 +45,7 @@ GEM faraday-retry (1.0.3) hashdiff (1.1.0) highline (2.0.3) - json (2.7.1) + json (2.7.2) language_server-protocol (3.17.0.3) method_source (1.0.0) multipart-post (2.3.0) @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.62.1) + rubocop (1.63.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -113,7 +113,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.13.0) - rubocop (~> 1.62) + rubocop (~> 1.63) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 30938db02e8b36883bafa5e052180b0ffa2b3cf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:46:40 +0000 Subject: [PATCH 248/265] Bump rubocop from 1.63.0 to 1.63.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.0 to 1.63.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.63.0...v1.63.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2a76b96..a95b551 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.63.0) + rubocop (1.63.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 00484568c0337d8a2b6c090910528cbe9de556fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:58:43 +0000 Subject: [PATCH 249/265] Bump rubocop from 1.63.1 to 1.63.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.1 to 1.63.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.63.1...v1.63.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a95b551..f1dcb6b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.63.1) + rubocop (1.63.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 7f32c1aeb2b243674e5b62702fdbbd856a608f31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 09:40:13 +0000 Subject: [PATCH 250/265] Bump rubocop from 1.63.2 to 1.63.4 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.2 to 1.63.4. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.63.2...v1.63.4) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f1dcb6b..60a3ddb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GEM method_source (1.0.0) multipart-post (2.3.0) parallel (1.24.0) - parser (3.3.0.5) + parser (3.3.1.0) ast (~> 2.4.1) racc pry (0.14.2) @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.63.2) + rubocop (1.63.4) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 473f584a90f93d45da2d6548489f9dfcf6adf417 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 09:47:27 +0000 Subject: [PATCH 251/265] Bump ruby from 3.3.0-slim-bullseye to 3.3.1-slim-bullseye Bumps ruby from 3.3.0-slim-bullseye to 3.3.1-slim-bullseye. --- updated-dependencies: - dependency-name: ruby dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 87f4db5..fa652b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.0-slim-bullseye +FROM ruby:3.3.1-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty" From 3213b33b984aa51e0470905127c2cabde20fddb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 09:08:29 +0000 Subject: [PATCH 252/265] Bump rubocop from 1.63.4 to 1.63.5 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.4 to 1.63.5. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.63.4...v1.63.5) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 60a3ddb..d6fb930 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,7 +61,7 @@ GEM rainbow (3.1.1) rake (13.2.1) rb-readline (0.5.5) - regexp_parser (2.9.0) + regexp_parser (2.9.1) rexml (3.2.6) rspec (3.13.0) rspec-core (~> 3.13.0) @@ -76,7 +76,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.63.4) + rubocop (1.63.5) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -87,8 +87,8 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.2) - parser (>= 3.3.0.4) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) simplecov (0.22.0) From ddc35eb1184803d03969150e7ff18991ccaa514c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 21:28:17 +0000 Subject: [PATCH 253/265] Bump rexml from 3.2.6 to 3.2.8 Bumps [rexml](https://github.com/ruby/rexml) from 3.2.6 to 3.2.8. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.2.8) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d6fb930..6944083 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -62,7 +62,8 @@ GEM rake (13.2.1) rb-readline (0.5.5) regexp_parser (2.9.1) - rexml (3.2.6) + rexml (3.2.8) + strscan (>= 3.0.9) rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -98,6 +99,7 @@ GEM simplecov-html (0.12.3) simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) + strscan (3.1.0) unicode-display_width (2.5.0) webmock (3.23.0) addressable (>= 2.8.0) From 5b09d149263b980967f77e37b8fbd59c8f52a688 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 09:44:03 +0000 Subject: [PATCH 254/265] Bump rubocop from 1.63.5 to 1.64.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.5 to 1.64.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.63.5...v1.64.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index c363bce..244ab06 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.13.0' - gem 'rubocop', '~> 1.63' + gem 'rubocop', '~> 1.64' gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index 6944083..54aeb99 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -57,11 +57,11 @@ GEM coderay (~> 1.1) method_source (~> 1.0) public_suffix (5.0.4) - racc (1.7.3) + racc (1.8.0) rainbow (3.1.1) rake (13.2.1) rb-readline (0.5.5) - regexp_parser (2.9.1) + regexp_parser (2.9.2) rexml (3.2.8) strscan (>= 3.0.9) rspec (3.13.0) @@ -77,7 +77,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.63.5) + rubocop (1.64.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -115,7 +115,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.13.0) - rubocop (~> 1.63) + rubocop (~> 1.64) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 06a9b95edff8beacd2ec655af493fa1e55e4a15a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 09:45:18 +0000 Subject: [PATCH 255/265] Bump webmock from 3.23.0 to 3.23.1 Bumps [webmock](https://github.com/bblimke/webmock) from 3.23.0 to 3.23.1. - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.23.0...v3.23.1) --- updated-dependencies: - dependency-name: webmock dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 54aeb99..7e8b021 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GEM addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) - bigdecimal (3.1.6) + bigdecimal (3.1.8) coderay (1.1.3) commander (4.6.0) highline (~> 2.0.0) @@ -56,7 +56,7 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) + public_suffix (5.0.5) racc (1.8.0) rainbow (3.1.1) rake (13.2.1) @@ -101,7 +101,7 @@ GEM simplecov_json_formatter (0.1.4) strscan (3.1.0) unicode-display_width (2.5.0) - webmock (3.23.0) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) From dc0e440c868fb2b65597411890cbf79ed2c2247e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:24:25 +0000 Subject: [PATCH 256/265] Bump ruby from 3.3.1-slim-bullseye to 3.3.2-slim-bullseye Bumps ruby from 3.3.1-slim-bullseye to 3.3.2-slim-bullseye. --- updated-dependencies: - dependency-name: ruby dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fa652b7..a419cc8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.1-slim-bullseye +FROM ruby:3.3.2-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty" From d1806b23eb4272e9c245003945ddba091aa6bb1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:28:26 +0000 Subject: [PATCH 257/265] Bump rubocop from 1.64.0 to 1.64.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.64.0 to 1.64.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.64.0...v1.64.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7e8b021..f6232ca 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GEM method_source (1.0.0) multipart-post (2.3.0) parallel (1.24.0) - parser (3.3.1.0) + parser (3.3.2.0) ast (~> 2.4.1) racc pry (0.14.2) @@ -77,7 +77,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.64.0) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 58ddd50618e295ec71203c502f25454caa401137 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:58:43 +0000 Subject: [PATCH 258/265] Bump ruby from 3.3.2-slim-bullseye to 3.3.3-slim-bullseye Bumps ruby from 3.3.2-slim-bullseye to 3.3.3-slim-bullseye. --- updated-dependencies: - dependency-name: ruby dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a419cc8..878e012 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.2-slim-bullseye +FROM ruby:3.3.3-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty" From e4151a00cebe1f130b6c1b56d21fba68c8fef6a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 09:39:58 +0000 Subject: [PATCH 259/265] Bump ruby from 3.3.3-slim-bullseye to 3.3.4-slim-bullseye Bumps ruby from 3.3.3-slim-bullseye to 3.3.4-slim-bullseye. --- updated-dependencies: - dependency-name: ruby dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 878e012..edc0711 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.3-slim-bullseye +FROM ruby:3.3.4-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty" From 82f522e9110e5d7ef53250ece05992fb68e40278 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 01:57:30 +0000 Subject: [PATCH 260/265] Bump rexml from 3.2.8 to 3.3.3 Bumps [rexml](https://github.com/ruby/rexml) from 3.2.8 to 3.3.3. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.8...v3.3.3) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f6232ca..4301eee 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -62,8 +62,8 @@ GEM rake (13.2.1) rb-readline (0.5.5) regexp_parser (2.9.2) - rexml (3.2.8) - strscan (>= 3.0.9) + rexml (3.3.3) + strscan rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) From d26bac7409f6aafe13b4170c522a41d9488dc322 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 01:59:32 +0000 Subject: [PATCH 261/265] Bump rubocop from 1.64.1 to 1.65.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.64.1 to 1.65.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.64.1...v1.65.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 244ab06..89c6b5c 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.13.0' - gem 'rubocop', '~> 1.64' + gem 'rubocop', '~> 1.65' gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index 4301eee..458fcae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,20 +49,20 @@ GEM language_server-protocol (3.17.0.3) method_source (1.0.0) multipart-post (2.3.0) - parallel (1.24.0) - parser (3.3.2.0) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) public_suffix (5.0.5) - racc (1.8.0) + racc (1.8.1) rainbow (3.1.1) rake (13.2.1) rb-readline (0.5.5) regexp_parser (2.9.2) - rexml (3.3.3) + rexml (3.3.4) strscan rspec (3.13.0) rspec-core (~> 3.13.0) @@ -77,13 +77,13 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.64.1) + rubocop (1.65.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) + regexp_parser (>= 2.4, < 3.0) rexml (>= 3.2.5, < 4.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) @@ -115,7 +115,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.13.0) - rubocop (~> 1.64) + rubocop (~> 1.65) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 721881395c86822b065502a88d7ac681e59551aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:24:28 +0000 Subject: [PATCH 262/265] Bump rubocop from 1.65.1 to 1.66.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.65.1 to 1.66.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.65.1...v1.66.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index 89c6b5c..16af5ec 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,6 @@ group :test do gem 'pry' gem 'rb-readline' gem 'rspec', '~> 3.13.0' - gem 'rubocop', '~> 1.65' + gem 'rubocop', '~> 1.66' gem 'webmock', '~> 3.23' end diff --git a/Gemfile.lock b/Gemfile.lock index 458fcae..3ab29f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,8 +49,8 @@ GEM language_server-protocol (3.17.0.3) method_source (1.0.0) multipart-post (2.3.0) - parallel (1.25.1) - parser (3.3.4.0) + parallel (1.26.3) + parser (3.3.4.2) ast (~> 2.4.1) racc pry (0.14.2) @@ -62,7 +62,7 @@ GEM rake (13.2.1) rb-readline (0.5.5) regexp_parser (2.9.2) - rexml (3.3.4) + rexml (3.3.6) strscan rspec (3.13.0) rspec-core (~> 3.13.0) @@ -77,18 +77,17 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.65.1) + rubocop (1.66.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.4, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.31.1, < 2.0) + rubocop-ast (>= 1.32.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.3) + rubocop-ast (1.32.1) parser (>= 3.3.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -115,7 +114,7 @@ DEPENDENCIES rake rb-readline rspec (~> 3.13.0) - rubocop (~> 1.65) + rubocop (~> 1.66) simplecov (~> 0.22.0) simplecov-html (~> 0.12.3) simplecov-lcov (~> 0.8.0) From 197c6e2e609b790d4ba00ff18bcd1d30562e56bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:52:46 +0000 Subject: [PATCH 263/265] Bump rubocop from 1.66.0 to 1.66.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.66.0 to 1.66.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.66.0...v1.66.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3ab29f8..9de558c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GEM method_source (1.0.0) multipart-post (2.3.0) parallel (1.26.3) - parser (3.3.4.2) + parser (3.3.5.0) ast (~> 2.4.1) racc pry (0.14.2) @@ -77,17 +77,17 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.0) - rubocop (1.66.0) + rubocop (1.66.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.1, < 2.0) + rubocop-ast (>= 1.32.2, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.1) + rubocop-ast (1.32.3) parser (>= 3.3.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) From 8df6ceb6768d3bab2d58d7bc2e121d7d09fa6d44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:52:53 +0000 Subject: [PATCH 264/265] Bump simplecov-html from 0.12.3 to 0.13.1 Bumps [simplecov-html](https://github.com/simplecov-ruby/simplecov-html) from 0.12.3 to 0.13.1. - [Release notes](https://github.com/simplecov-ruby/simplecov-html/releases) - [Changelog](https://github.com/simplecov-ruby/simplecov-html/blob/main/CHANGELOG.md) - [Commits](https://github.com/simplecov-ruby/simplecov-html/compare/v0.12.3...v0.13.1) --- updated-dependencies: - dependency-name: simplecov-html dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 16af5ec..7f70b2e 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem 'rake', require: false group :test do gem 'simplecov', '~> 0.22.0' - gem 'simplecov-html', '~> 0.12.3' + gem 'simplecov-html', '~> 0.13.1' gem 'simplecov-lcov', '~> 0.8.0' gem 'pry' gem 'rb-readline' diff --git a/Gemfile.lock b/Gemfile.lock index 3ab29f8..3c48e71 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -95,7 +95,7 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-html (0.12.3) + simplecov-html (0.13.1) simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) strscan (3.1.0) @@ -116,7 +116,7 @@ DEPENDENCIES rspec (~> 3.13.0) rubocop (~> 1.66) simplecov (~> 0.22.0) - simplecov-html (~> 0.12.3) + simplecov-html (~> 0.13.1) simplecov-lcov (~> 0.8.0) vmfloaty! webmock (~> 3.23) From b2fd9313f886848373b0551869cf24a38e8f7825 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:56:48 +0000 Subject: [PATCH 265/265] Bump ruby from 3.3.4-slim-bullseye to 3.3.5-slim-bullseye Bumps ruby from 3.3.4-slim-bullseye to 3.3.5-slim-bullseye. --- updated-dependencies: - dependency-name: ruby dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index edc0711..5c8fd0e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.4-slim-bullseye +FROM ruby:3.3.5-slim-bullseye LABEL org.opencontainers.image.authors="@puppetlabs/release-engineering" LABEL org.opencontainers.image.title="vmfloaty"