diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index eaf3712..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,9 +0,0 @@
-**/*.yml
-**/*.yaml
-**/*.md
-**/*example
-**/Dockerfile*
-coverage
-examples
-scripts
-vendor
diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE
index 5b0d10e..b1d9431 100644
--- a/.github/PULL_REQUEST_TEMPLATE
+++ b/.github/PULL_REQUEST_TEMPLATE
@@ -15,3 +15,7 @@ FIXME
- [ ] Tests
- [ ] Documentation
+## Reviewers
+
+@highb
+@briancain
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 90d6dfd..0000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-version: 2
-updates:
-- 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
deleted file mode 100644
index 19380e9..0000000
--- a/.github/workflows/auto_release_prep.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-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:
- project-type: ruby
- version-file-path: lib/vmfloaty/version.rb
diff --git a/.github/workflows/dependabot_merge.yml b/.github/workflows/dependabot_merge.yml
deleted file mode 100644
index 75b9cea..0000000
--- a/.github/workflows/dependabot_merge.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 50a5fa8..0000000
--- a/.github/workflows/ensure_label.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: Ensure label
-
-on: pull_request
-
-jobs:
- ensure_label:
- uses: puppetlabs/release-engineering-repo-standards/.github/workflows/ensure_label.yml@v1
- secrets: inherit
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}}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index d79ed5f..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,118 +0,0 @@
-name: Tag Release & Push Gem & Docker
-
-on: workflow_dispatch
-
-permissions:
- contents: write
- issues: read
- pull-requests: read
- packages: write
-
-jobs:
- release:
- name: Validate Docs, Tag, and Docker Push
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
- 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@v7
- 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.nv.outputs.version }}
- token: ${{ secrets.GITHUB_TOKEN }}
- bodyfile: release-notes.md
- draft: false
- prerelease: false
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Login to GitHub Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Build and push
- uses: docker/build-push-action@v5
- 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: 3.2.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/.github/workflows/security.yml b/.github/workflows/security.yml
deleted file mode 100644
index ba273f5..0000000
--- a/.github/workflows/security.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-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@v4
- 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@v4
- 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/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index 8562713..0000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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: Test
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- spec:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- ruby-version:
- - '2.7'
- - '3.0'
- - '3.1'
- - '3.2'
-
- steps:
- - 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):
- # 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@v2
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- flag-name: run-${{ matrix.ruby-version }}
- parallel: true
-
- finish:
- needs: spec
- if: ${{ always() }}
- runs-on: ubuntu-latest
- steps:
- - name: Coveralls Finished
- uses: coverallsapp/github-action@v2
- with:
- github-token: ${{ secrets.github_token }}
- parallel-finished: true
diff --git a/.github_changelog_generator b/.github_changelog_generator
deleted file mode 100644
index 02a0c7c..0000000
--- a/.github_changelog_generator
+++ /dev/null
@@ -1,3 +0,0 @@
-project=vmfloaty
-user=puppetlabs
-exclude_labels=maintenance
diff --git a/.gitignore b/.gitignore
index 76a21bc..f211644 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,13 +22,11 @@ build/
## Environment normalisation:
/.bundle/
-/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
.ruby-version
.ruby-gemset
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000..1bbc983
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,27 @@
+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/HashAlignment:
+ EnforcedHashRocketStyle: table
+Layout/FirstHashElementIndentation:
+ EnforcedStyle: consistent
+Metrics/ParameterLists:
+ Enabled: False
+
+Style/StderrPuts:
+ Enabled: false
+Style/WordArray:
+ Enabled: false
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
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..041e835
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+sudo: false
+language: ruby
+rvm:
+ - 2.6.5
+script: bundle exec rake rubocop spec
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index ff7c73f..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,340 +0,0 @@
-# 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)
-
-**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:**
-
-- \(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)*
diff --git a/CODEOWNERS b/CODEOWNERS
deleted file mode 100644
index e8dffe5..0000000
--- a/CODEOWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Set the default code owners
-* @puppetlabs/release-engineering
-
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 5c8fd0e..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM ruby:3.3.5-slim-bullseye
-
-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 -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" ]
diff --git a/Gemfile b/Gemfile
index 7f70b2e..2d04715 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,15 +4,12 @@ source 'https://rubygems.org'
gemspec
-gem 'rake', require: false
+gem 'rake', :require => false
group :test do
- gem 'simplecov', '~> 0.22.0'
- gem 'simplecov-html', '~> 0.13.1'
- gem 'simplecov-lcov', '~> 0.8.0'
gem 'pry'
gem 'rb-readline'
- gem 'rspec', '~> 3.13.0'
- gem 'rubocop', '~> 1.66'
- gem 'webmock', '~> 3.23'
+ gem 'rspec', '~> 3.5.0'
+ gem 'rubocop', '~> 0.52'
+ gem 'webmock', '1.21.0'
end
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index 7d27ddd..0000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,125 +0,0 @@
-PATH
- remote: .
- specs:
- vmfloaty (1.8.1)
- commander (>= 4.4.3, < 4.7.0)
- faraday (~> 1.5, >= 1.5.1)
-
-GEM
- remote: https://rubygems.org/
- specs:
- addressable (2.8.6)
- public_suffix (>= 2.0.2, < 6.0)
- ast (2.4.2)
- bigdecimal (3.1.8)
- coderay (1.1.3)
- commander (4.6.0)
- highline (~> 2.0.0)
- crack (1.0.0)
- bigdecimal
- rexml
- diff-lcs (1.5.1)
- 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.1.0)
- highline (2.0.3)
- json (2.7.2)
- language_server-protocol (3.17.0.3)
- method_source (1.0.0)
- multipart-post (2.3.0)
- parallel (1.26.3)
- parser (3.3.5.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.1)
- rainbow (3.1.1)
- rake (13.2.1)
- rb-readline (0.5.5)
- regexp_parser (2.9.2)
- rexml (3.3.6)
- strscan
- 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.13.0)
- rspec-mocks (3.13.0)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.13.0)
- rspec-support (3.13.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.2, < 2.0)
- ruby-progressbar (~> 1.7)
- unicode-display_width (>= 2.4.0, < 3.0)
- rubocop-ast (1.32.3)
- parser (>= 3.3.1.0)
- ruby-progressbar (1.13.0)
- ruby2_keywords (0.0.5)
- simplecov (0.22.0)
- docile (~> 1.1)
- simplecov-html (~> 0.11)
- simplecov_json_formatter (~> 0.1)
- simplecov-html (0.13.1)
- simplecov-lcov (0.8.0)
- simplecov_json_formatter (0.1.4)
- strscan (3.1.0)
- unicode-display_width (2.5.0)
- webmock (3.23.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.13.0)
- rubocop (~> 1.66)
- simplecov (~> 0.22.0)
- simplecov-html (~> 0.13.1)
- simplecov-lcov (~> 0.8.0)
- vmfloaty!
- webmock (~> 3.23)
-
-BUNDLED WITH
- 2.4.8
diff --git a/README.md b/README.md
index dfc22f9..9e278fc 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,40 @@
-# vmfloaty
+vmfloaty
+========
-[](https://badge.fury.io/rb/vmfloaty)
-[](https://github.com/puppetlabs/vmfloaty/actions/workflows/test.yml)
+[](https://badge.fury.io/rb/vmfloaty) [](https://travis-ci.org/briancain/vmfloaty)
-A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat.
+A CLI helper tool for [Puppet Labs vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat.
-
+
-- [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)
+This project is still supported by @briancain and @demophoon. Ping either of us if you'd like something merged and released.
## 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`
+$ gem install vmfloaty
+...
+...
+$ floaty --help
+```
## Usage
-```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
- 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
- summary Prints a summary of a pooler service
- token Retrieves or deletes a token or checks token status
+```
+ 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
GLOBAL OPTIONS:
@@ -88,7 +52,7 @@ $ floaty --help
Grabbing a token for authenticated pooler requests:
-```bash
+```
floaty token get --user username --url https://vmpooler.example.net/api/v1
```
@@ -96,54 +60,108 @@ 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
```
### vmfloaty dotfile
-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.
+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
-This is the simplest type of configuration where you only need a single service:
-
```yaml
-# file at ~/.vmfloaty.yml
+# file at /Users/me/.vmfloaty.yml
url: 'https://vmpooler.example.net/api/v1'
user: 'brian'
token: 'tokenstring'
```
-Run `floaty service examples` to see additional configuration options
+Now vmfloaty will use those config files if no flag was specified.
-#### Using multiple services
+#### Configuring multiple services
-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.
+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'
+```
- 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.
- This makes it so you can specify things like `user` once at the top of your `~/.vmfloaty.yml`.
+ With the config file above, 'brian' will be used as the username for both configured services, since neither specifies a username.
-#### Using backends besides VMPooler
+Examples using the above configuration:
-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.
+List available vm types from our main vmpooler instance:
+```sh
+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
+```
+
+#### 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:
+
+```sh
+floaty list --service ns
+```
#### Valid config keys
Here are the keys that vmfloaty currently supports:
-- verbose (Boolean)
-- token (String)
-- user (String)
-- url (String)
-- services (String)
-- type (String)
-- vmpooler_fallback (String)
+- verbose
+ + Boolean
+- token
+ + String
+- user
+ + String
+- url
+ + String
+- services
+ + Map
### 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/puppetlabs/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/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:
@@ -157,44 +175,17 @@ 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:
+## vmpooler API
-```zsh
-source $(floaty completion --shell zsh)
-```
-
-## 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
- [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
-
-## 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
-
-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/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.
-
-## 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.
+ + Use Vagrant to manage your vmpooler instances
diff --git a/Rakefile b/Rakefile
index cdd6c8f..bde93cf 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/extras/completions/floaty.bash b/extras/completions/floaty.bash
index 17a5b24..1d1e69d 100644
--- a/extras/completions/floaty.bash
+++ b/extras/completions/floaty.bash
@@ -2,37 +2,29 @@
_vmfloaty()
{
- local cur prev commands template_arg_commands hostname_arg_commands service_subcommands
-
+ local cur prev subcommands template_subcommands hostname_subcommands
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
- 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"
+ 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_arg_commands =~ (^| )$prev($| ) ]] ; then
+ elif [[ $template_subcommands =~ (^| )$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_arg_commands =~ (^| )$prev($| ) ]] ; then
- _vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null)
+ 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}") )
- 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}") )
+ else
+ COMPREPLY=( $(compgen -W "${subcommands}" -- "${cur}") )
fi
}
complete -F _vmfloaty floaty
diff --git a/extras/completions/floaty.zsh b/extras/completions/floaty.zsh
deleted file mode 100644
index 1dbc292..0000000
--- a/extras/completions/floaty.zsh
+++ /dev/null
@@ -1,43 +0,0 @@
-_floaty()
-{
- local line commands template_arg_commands hostname_arg_commands service_subcommands
-
- 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")
-
- _arguments -C \
- "1: :(${commands})" \
- "*::arg:->args"
-
- if ((template_arg_commands[(Ie)$line[1]])); then
- _floaty_template_sub
- 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
-
- _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
diff --git a/float.jpg b/float.jpg
deleted file mode 100644
index 87b06f4..0000000
Binary files a/float.jpg and /dev/null differ
diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb
index 3c6bbec..9165423 100644
--- a/lib/vmfloaty.rb
+++ b/lib/vmfloaty.rb
@@ -2,6 +2,7 @@
require 'rubygems'
require 'commander'
+require 'colorize'
require 'json'
require 'pp'
require 'uri'
@@ -12,15 +13,13 @@ require 'vmfloaty/conf'
require 'vmfloaty/utils'
require 'vmfloaty/service'
require 'vmfloaty/ssh'
-require 'vmfloaty/logger'
class Vmfloaty
include Commander::Methods
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 Labs VM poolers to help you stay afloat'
config = Conf.read_config
@@ -38,43 +37,35 @@ 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.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']
- FloatyLogger.setlevel = options.loglevel if options.loglevel
service = Service.new(options, config)
use_token = !options.notoken
force = options.force
if args.empty?
- FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
+ STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
exit 1
end
os_types = Utils.generate_os_hash(args)
- 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
- FloatyLogger.error "Requesting vms over #{max_pool_request} requires a --force flag."
- FloatyLogger.error 'Try again with `floaty get --force`'
+ STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag."
+ STDERR.puts 'Try again with `floaty get --force`'
exit 1
end
- 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
+ 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)
hosts = Utils.standardize_hostnames(response)
-
- if options.json || options.ondemand
+ if options.json
puts JSON.pretty_generate(hosts)
else
puts Utils.format_host_output(hosts)
@@ -90,40 +81,20 @@ 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 '--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'
- c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
c.action do |args, options|
verbose = options.verbose || config['verbose']
- FloatyLogger.setlevel = options.loglevel if options.loglevel
service = Service.new(options, config)
filter = args[0]
if options.active
# list active vms
- 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
+ running_vms = service.list_active(verbose)
host = URI.parse(service.url).host
if running_vms.empty?
- if options.json
- puts {}.to_json
- else
- FloatyLogger.info "You have no running VMs on #{host}"
- end
- 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
+ puts "You have no running VMs on #{host}"
else
puts "Your VMs on #{host}:"
Utils.pretty_print_hosts(verbose, service, running_vms)
@@ -139,7 +110,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. If using ABS, you can query a job_id'
+ 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 '--service STRING', String, 'Configured pooler service name'
@@ -158,8 +129,7 @@ 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'
@@ -176,22 +146,17 @@ class Vmfloaty
modify_all = options.all
if hostname.nil? && !modify_all
- FloatyLogger.error 'ERROR: Provide a hostname or specify --all.'
+ STDERR.puts 'ERROR: Provide a hostname or specify --all.'
exit 1
end
- running_vms =
- if modify_all
- service.list_active(verbose)
- else
- hostname.split(',')
- end
+ running_vms = modify_all ? service.list_active(verbose) : hostname.split(',')
tags = options.tags ? JSON.parse(options.tags) : nil
modify_hash = {
- lifetime: options.lifetime,
- disk: options.disk,
- tags: tags,
- reason: options.reason
+ :lifetime => options.lifetime,
+ :disk => options.disk,
+ :tags => tags,
+ :reason => options.reason,
}
modify_hash.delete_if { |_, value| value.nil? }
@@ -199,14 +164,16 @@ class Vmfloaty
ok = true
modified_hash = {}
running_vms.each do |vm|
- modified_hash[vm] = service.modify(verbose, vm, modify_hash)
- rescue ModifyError => e
- FloatyLogger.error e
- ok = false
+ begin
+ modified_hash[vm] = service.modify(verbose, vm, modify_hash)
+ rescue ModifyError => e
+ STDERR.puts e
+ ok = false
+ end
end
if ok
if modify_all
- puts "Successfully modified all #{running_vms.count} VMs."
+ puts 'Successfully modified all VMs.'
else
puts "Successfully modified VM #{hostname}."
end
@@ -227,15 +194,10 @@ 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.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']
- FloatyLogger.setlevel = options.loglevel if options.loglevel
-
service = Service.new(options, config)
hostnames = args[0]
delete_all = options.all
@@ -245,25 +207,15 @@ class Vmfloaty
successes = []
if delete_all
- 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
+ running_vms = service.list_active(verbose)
if running_vms.empty?
- if options.json
- puts {}.to_json
- else
- FloatyLogger.info 'You have no running VMs.'
- end
+ STDERR.puts 'You have no running VMs.'
else
+ Utils.pretty_print_hosts(verbose, service, running_vms)
+ # Confirm deletion
+ puts
confirmed = true
- unless force
- Utils.pretty_print_hosts(verbose, service, running_vms, true)
- # Confirm deletion
- 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|
@@ -286,28 +238,23 @@ class Vmfloaty
end
end
else
- FloatyLogger.info 'You did not provide any hosts to delete'
+ STDERR.puts 'You did not provide any hosts to delete'
exit 1
end
unless failures.empty?
- FloatyLogger.info 'Unable to delete the following VMs:'
+ STDERR.puts 'Unable to delete the following VMs:'
failures.each do |hostname|
- FloatyLogger.info "- #{hostname}"
+ STDERR.puts "- #{hostname}"
end
- FloatyLogger.info 'Check `floaty list --active`; Do you need to specify a different service?'
+ STDERR.puts 'Check `floaty list --active`; Do you need to specify a different service?'
end
unless successes.empty?
- 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
+ puts unless failures.empty?
+ puts 'Scheduled the following VMs for deletion:'
+ successes.each do |hostname|
+ puts "- #{hostname}"
end
end
@@ -319,8 +266,7 @@ 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'
@@ -333,7 +279,7 @@ class Vmfloaty
begin
snapshot_req = service.snapshot(verbose, hostname)
rescue TokenError, ModifyError => e
- FloatyLogger.error e
+ STDERR.puts e
exit 1
end
@@ -346,8 +292,7 @@ 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'
@@ -359,14 +304,12 @@ class Vmfloaty
hostname = args[0]
snapshot_sha = args[1] || options.snapshot
- if args[1] && options.snapshot
- FloatyLogger.info "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)
rescue TokenError, ModifyError => e
- FloatyLogger.error e
+ STDERR.puts e
exit 1
end
@@ -383,10 +326,8 @@ 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']
- FloatyLogger.setlevel = options.loglevel if options.loglevel
service = Service.new(options, config)
if options.json
pp service.status(verbose)
@@ -443,14 +384,14 @@ class Vmfloaty
status = service.token_status(verbose, token_value)
puts status
when nil
- FloatyLogger.error 'No action provided'
+ STDERR.puts 'No action provided'
exit 1
else
- FloatyLogger.error "Unknown action: #{action}"
+ STDERR.puts "Unknown action: #{action}"
exit 1
end
rescue TokenError => e
- FloatyLogger.error e
+ STDERR.puts e
exit 1
end
exit 0
@@ -468,23 +409,21 @@ 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.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)
use_token = !options.notoken
if args.empty?
- FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
+ STDERR.puts 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
exit 1
end
host_os = args.first
- FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
+ STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
- service.ssh(verbose, host_os, use_token, options.ondemand)
+ service.ssh(verbose, host_os, use_token)
exit 0
end
end
@@ -509,71 +448,7 @@ class Vmfloaty
puts completion_file
exit 0
else
- FloatyLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}"
- exit 1
- end
- 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}"
+ STDERR.puts "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 e6769e0..259f411 100644
--- a/lib/vmfloaty/abs.rb
+++ b/lib/vmfloaty/abs.rb
@@ -2,7 +2,6 @@
require 'vmfloaty/errors'
require 'vmfloaty/http'
-require 'vmfloaty/utils'
require 'faraday'
require 'json'
@@ -37,61 +36,39 @@ class ABS
# }
# }
#
+
@active_hostnames = {}
- def self.list_active_job_ids(verbose, url, user)
- all_job_ids = []
- @active_hostnames = {}
- get_active_requests(verbose, url, user).each do |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_job_ids
- end
-
def self.list_active(verbose, url, _token, user)
- hosts = []
- get_active_requests(verbose, url, user).each do |req_hash|
- next unless req_hash.key?('allocated_resources')
+ all_jobs = []
+ @active_hostnames = {}
- req_hash['allocated_resources'].each do |onehost|
- hosts.push(onehost['hostname'])
- end
+ 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
- hosts
+ all_jobs
end
def self.get_active_requests(verbose, url, user)
- conn = Http.get_conn(verbose, supported_abs_url(url))
+ conn = Http.get_conn(verbose, url)
res = conn.get 'status/queue'
- if valid_json?(res.body)
- requests = JSON.parse(res.body)
- else
- FloatyLogger.warn "Warning: couldn't parse body returned from abs/status/queue"
- end
+ requests = JSON.parse(res.body)
ret_val = []
requests.each do |req|
next if req == 'null'
- 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
- end
+ req_hash = JSON.parse(req)
begin
next unless user == req_hash['request']['job']['user']
ret_val.push(req_hash)
rescue NoMethodError
- FloatyLogger.warn "Warning: couldn't parse user returned from abs/status/queue: "
+ puts "Warning: couldn't parse line returned from abs/status/queue: ".yellow
end
end
@@ -105,10 +82,10 @@ class ABS
def self.delete(verbose, url, hosts, token, user)
# In ABS terms, this is a "returned" host.
- conn = Http.get_conn(verbose, supported_abs_url(url))
+ conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
- FloatyLogger.info "Trying to delete hosts #{hosts}" if verbose
+ puts "Trying to delete hosts #{hosts}" if verbose
requests = get_active_requests(verbose, url, user)
jobs_to_delete = []
@@ -116,7 +93,7 @@ class ABS
ret_status = {}
hosts.each do |host|
ret_status[host] = {
- 'ok' => false
+ 'ok' => false,
}
end
@@ -132,11 +109,11 @@ 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
- 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']}"
+ 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
@@ -147,10 +124,10 @@ 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
+ puts "Deleting #{req_obj}" if verbose
return_result = conn.post 'return', req_obj.to_json
req_obj['hosts'].each do |host|
@@ -163,64 +140,27 @@ class ABS
# List available VMs in ABS
def self.list(verbose, url, os_filter = nil)
- conn = Http.get_conn(verbose, supported_abs_url(url))
+ conn = Http.get_conn(verbose, url)
os_list = []
res = conn.get 'status/platforms/vmpooler'
- if valid_json?(res.body)
- res_body = JSON.parse(res.body)
- if res_body.key?('vmpooler_platforms')
- os_list << '*** VMPOOLER Pools ***'
- 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
- res = conn.get 'status/platforms/ondemand_vmpooler'
- 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 ***'
- 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
+ res_body = JSON.parse(res.body)
+ os_list << '*** VMPOOLER Pools ***'
+ os_list += JSON.parse(res_body['vmpooler_platforms'])
res = conn.get 'status/platforms/nspooler'
- 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 += 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
+ 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'
- 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 += 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
+ res_body = JSON.parse(res.body)
+ os_list << ''
+ os_list << '*** AWS Pools ***'
+ os_list += JSON.parse(res_body['aws_platforms'])
os_list.delete 'ok'
@@ -228,7 +168,7 @@ class ABS
end
# Retrieve an OS from ABS.
- def self.retrieve(verbose, os_types, token, url, user, config, _ondemand = nil, continue = nil)
+ def self.retrieve(verbose, os_types, token, url, user, options)
#
# Contents of post must be like:
#
@@ -245,69 +185,53 @@ class ABS
# }
# }
- conn = Http.get_conn(verbose, supported_abs_url(url))
+ conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
- saved_job_id = if continue.nil?
- "#{user}-#{DateTime.now.strftime('%Q')}"
- else
- continue
- end
+ saved_job_id = DateTime.now.strftime('%Q')
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
- 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] = case config['priority']
- when 'high'
+ if options['priority']
+ req_obj[:priority] = if options['priority'] == 'high'
1
- when 'medium'
+ elsif options['priority'] == 'medium'
2
- when 'low'
+ elsif options['priority'] == 'low'
3
else
- config['priority'].to_i
+ options['priority'].to_i
end
end
- FloatyLogger.info "Posting to ABS #{req_obj.to_json}" if verbose
+ 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?
- FloatyLogger.info "Requesting VMs with job_id: #{saved_job_id} Will retry for up to an hour."
+ 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
- status = validate_queue_status_response(res.status, res.body, 'Initial request', verbose)
+ raise AuthError, "HTTP #{res.status}: The token provided could not authenticate to the pooler.\n#{res_body}" if res.status == 401
- begin
- (1..retries).each do |i|
- res_body = check_queue(conn, saved_job_id, req_obj, verbose)
- return translated(res_body, saved_job_id) if res_body.is_a?(Array) # when we get a response with hostnames
+ (1..retries).each do |i|
+ queue_place, res_body = check_queue(conn, saved_job_id, req_obj)
+ return translated(res_body) if res_body
- sleep_seconds = 10 if i >= 10
- sleep_seconds = i if i < 10
- FloatyLogger.info "Waiting #{sleep_seconds}s (x#{i}) #{res_body.strip}"
+ 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(sleep_seconds)
- end
- rescue SystemExit, Interrupt
- 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
+ sleep(sleep_seconds)
end
nil
end
@@ -315,11 +239,11 @@ 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 }
+ def self.translated(res_body)
+ vmpooler_formatted_body = {}
res_body.each do |host|
- if vmpooler_formatted_body[host['type']] && vmpooler_formatted_body[host['type']]['hostname'].instance_of?(Array)
+ 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']] }
@@ -330,47 +254,46 @@ 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)
+ 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
- status = validate_queue_status_response(res.status, res.body, 'Check queue request', verbose)
- unless res.body.empty? || !valid_json?(res.body)
+
+ unless res.body.empty?
res_body = JSON.parse(res.body)
- return res_body
+ return queue_info['queue_place'], res_body
end
- res.body
+ [queue_info['queue_place'], nil]
end
def self.snapshot(_verbose, _url, _hostname, _token)
- raise NoMethodError, "Can't snapshot with ABS, use '--service vmpooler' (even for vms checked out with ABS)"
+ 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, supported_abs_url(url))
+ conn = Http.get_conn(verbose, url)
res = conn.get 'status'
res.body == 'OK'
end
- def self.summary(_verbose, _url)
- raise NoMethodError, 'summary is not defined for ABS'
+ def self.summary(verbose, url)
+ conn = Http.get_conn(verbose, url)
+
+ res = conn.get 'summary'
+ JSON.parse(res.body)
end
- 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?
+ def self.query(verbose, url, hostname)
+ return @active_hostnames if @active_hostnames
- # If using the cli query job_id
- 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)
- else
- FloatyLogger.warn "Could not parse the status/queue/info/#{job_id}"
- end
- queue_info
+ 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}"
+ JSON.parse(res.body)
end
def self.modify(_verbose, _url, _hostname, _token, _modify_hash)
@@ -384,39 +307,4 @@ 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
-
- def self.valid_json?(json)
- JSON.parse(json)
- true
- rescue TypeError, JSON::ParserError => e
- false
- end
-
- # when missing, adds the required api/v2 in the url
- def self.supported_abs_url(url)
- expected_ending = 'api/v2'
- unless url.include?(expected_ending)
- # add a slash if missing
- expected_ending = "/#{expected_ending}" if url[-1] != '/'
- url = "#{url}#{expected_ending}"
- end
- url
- end
end
diff --git a/lib/vmfloaty/conf.rb b/lib/vmfloaty/conf.rb
index 904020d..5e572fa 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
- # ignore
+ STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml"
end
conf
end
diff --git a/lib/vmfloaty/http.rb b/lib/vmfloaty/http.rb
index c1f03f6..b1984b8 100644
--- a/lib/vmfloaty/http.rb
+++ b/lib/vmfloaty/http.rb
@@ -21,11 +21,13 @@ class Http
url = "https://#{url}" unless url?(url)
- Faraday.new(url: url, ssl: { verify: false }) do |faraday|
+ conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday|
faraday.request :url_encoded
faraday.response :logger if verbose
faraday.adapter Faraday.default_adapter
end
+
+ conn
end
def self.get_conn_with_auth(verbose, url, user, password)
@@ -35,11 +37,13 @@ class Http
url = "https://#{url}" unless url?(url)
- Faraday.new(url: url, ssl: { verify: false }) do |faraday|
+ conn = Faraday.new(:url => url, :ssl => { :verify => false }) do |faraday|
faraday.request :url_encoded
faraday.request :basic_auth, user, password
faraday.response :logger if verbose
faraday.adapter Faraday.default_adapter
end
+
+ conn
end
end
diff --git a/lib/vmfloaty/logger.rb b/lib/vmfloaty/logger.rb
deleted file mode 100644
index bdc2bb4..0000000
--- a/lib/vmfloaty/logger.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-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 self.setlevel=(level)
- level = level.downcase
- 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')
- end
- end
-
- def initialize
- super($stderr)
- self.level = ::Logger::INFO
- 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 eb6c6a7..90722c0 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)
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
@@ -46,8 +46,7 @@ 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 9d47407..c85daf3 100644
--- a/lib/vmfloaty/pooler.rb
+++ b/lib/vmfloaty/pooler.rb
@@ -12,11 +12,13 @@ class Pooler
response = conn.get 'vm'
response_body = JSON.parse(response.body)
- 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
+
+ hosts
end
def self.list_active(verbose, url, token, _user)
@@ -26,7 +28,7 @@ class Pooler
vms
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)
# NOTE:
# Developers can use `Utils.generate_os_hash` to
# generate the os_type param.
@@ -36,8 +38,7 @@ 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}" unless ondemand
- response ||= conn.post "ondemandvm/#{os_string}"
+ response = conn.post "vm/#{os_string}"
res_body = JSON.parse(response.body)
@@ -45,49 +46,16 @@ 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
- 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}"
+ raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/vm/#{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
-
- FloatyLogger.info "waiting for request #{request_id} to be fulfilled"
- sleep 5
- end
- FloatyLogger.info '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?
- modify_hash.each_key do |key|
- raise ModifyError, "Configured service type does not support modification of #{key}." unless %i[tags lifetime
- disk].include? key
+ modify_hash.keys.each 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)
@@ -122,7 +90,8 @@ class Pooler
response = conn.post "vm/#{hostname}/disk/#{disk}"
- JSON.parse(response.body)
+ res_body = JSON.parse(response.body)
+ res_body
end
def self.delete(verbose, url, hosts, token, _user)
@@ -146,22 +115,26 @@ class Pooler
def self.status(verbose, url)
conn = Http.get_conn(verbose, url)
- response = conn.get 'status'
- JSON.parse(response.body)
+ response = conn.get '/status'
+ res_body = JSON.parse(response.body)
+ res_body
end
def self.summary(verbose, url)
conn = Http.get_conn(verbose, url)
- response = conn.get 'summary'
- JSON.parse(response.body)
+ response = conn.get '/summary'
+ res_body = JSON.parse(response.body)
+ res_body
end
def self.query(verbose, url, hostname)
conn = Http.get_conn(verbose, url)
response = conn.get "vm/#{hostname}"
- JSON.parse(response.body)
+ res_body = JSON.parse(response.body)
+
+ res_body
end
def self.snapshot(verbose, url, hostname, token)
@@ -171,7 +144,8 @@ class Pooler
conn.headers['X-AUTH-TOKEN'] = token
response = conn.post "vm/#{hostname}/snapshot"
- JSON.parse(response.body)
+ res_body = JSON.parse(response.body)
+ res_body
end
def self.revert(verbose, url, hostname, token, snapshot_sha)
@@ -183,6 +157,7 @@ class Pooler
raise "Snapshot SHA provided was nil, could not revert #{hostname}" if snapshot_sha.nil?
response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}"
- JSON.parse(response.body)
+ res_body = JSON.parse(response.body)
+ res_body
end
end
diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb
index a9e59ba..6a89b3d 100644
--- a/lib/vmfloaty/service.rb
+++ b/lib/vmfloaty/service.rb
@@ -7,13 +7,11 @@ 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)
@@ -38,15 +36,15 @@ class Service
def user
unless @config['user']
- FloatyLogger.info "Enter your #{@config['url']} service username:"
- @config['user'] = $stdin.gets.chomp
+ puts "Enter your #{@config['url']} service username:"
+ @config['user'] = STDIN.gets.chomp
end
@config['user']
end
def token
unless @config['token']
- FloatyLogger.info 'No token found. Retrieving a token...'
+ puts 'No token found. Retrieving a token...'
@config['token'] = get_new_token(nil)
end
@config['token']
@@ -77,27 +75,32 @@ class Service
@service_object.list_active verbose, url, token, user
end
- def retrieve(verbose, os_types, use_token = true, ondemand = nil, continue = nil)
- FloatyLogger.info 'Requesting a vm without a token...' unless use_token
+ 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, @config, ondemand, continue
+ @service_object.retrieve verbose, os_types, token_value, url, user, @config
end
- def wait_for_request(verbose, requestid)
- @service_object.wait_for_request verbose, requestid, url
- end
-
- def ssh(verbose, host_os, use_token = true, ondemand = nil)
+ 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
- FloatyLogger.error e
- FloatyLogger.info 'Could not get token... requesting vm without a token anyway...'
+ STDERR.puts e
+ STDERR.puts 'Could not get token... requesting vm without a token anyway...'
end
end
- Ssh.ssh(verbose, self, host_os, token_value, ondemand)
+ 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)
@@ -105,7 +108,6 @@ class Service
end
def modify(verbose, hostname, modify_hash)
- maybe_use_vmpooler
@service_object.modify verbose, url, hostname, token, modify_hash
end
@@ -118,35 +120,18 @@ 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 == ABS # this is not an instance
- 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
-
- @config = Utils.get_vmpooler_service_config(@config['vmpooler_fallback'])
- @service_object = Pooler
- end
- end
end
diff --git a/lib/vmfloaty/ssh.rb b/lib/vmfloaty/ssh.rb
index 582adea..f100b8b 100644
--- a/lib/vmfloaty/ssh.rb
+++ b/lib/vmfloaty/ssh.rb
@@ -14,45 +14,27 @@ class Ssh
nil
end
- def self.command_string(verbose, service, host_os, use_token, ondemand = nil)
+ 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 = Utils.generate_os_hash([host_os])
+
+ os_types = {}
os_types[host_os] = 1
- response = service.retrieve(verbose, os_types, use_token, ondemand)
+ 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'
- 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
+ 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, ondemand)
- cmd = command_string(verbose, service, host_os, use_token, ondemand)
+ 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/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb
index b393acf..1e2e678 100644
--- a/lib/vmfloaty/utils.rb
+++ b/lib/vmfloaty/utils.rb
@@ -3,13 +3,12 @@
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
# request and "pretty prints" it
def self.standardize_hostnames(response_body)
- # vmpooler api v1 response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`:
+ # vmpooler response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`:
# {
# "ok": true,
# "domain": "delivery.mycompany.net",
@@ -21,17 +20,6 @@ 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,
@@ -50,22 +38,14 @@ class Utils
# "engine"=>"vmpooler"
# }
- 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')
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, _| %w[request_id ready].include?(key) }
- filtered_response_body.each do |os, value|
+ response_body.each do |os, value|
hostnames = Array(value['hostname'])
hostnames.map! { |host| "#{host}.#{domain}" } if domain
result[os] = hostnames
@@ -76,8 +56,7 @@ class Utils
def self.format_host_output(hosts)
hosts.flat_map do |os, names|
- # Assume hosts are stored in Arrays and ignore everything else
- names.map { |name| "- #{name} (#{os})" } if names.is_a? Array
+ names.map { |name| "- #{name} (#{os})" }
end.join("\n")
end
@@ -98,109 +77,41 @@ class Utils
os_types
end
- 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|
- abs_hostnames << vm_name['hostname']
- end
-
- puts abs_hostnames.join("\n")
- when 'Pooler'
- if host_data['domain'].nil?
- puts hostname
- else
- puts "#{hostname}.#{host_data['domain']}"
- end
- 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
-
- fetched_data = 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
- #
- # Create a vmpooler service to query each hostname there so as to get the metadata too
-
- 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']
- vmpooler_service = service.clone
- vmpooler_service.silent = true
- vmpooler_service.maybe_use_vmpooler
- 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 = []
- 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]
- # 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
- output_target.puts message
- end
- 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'].nil? || host_data['reserved_for_reason'].empty?
- line += ')'
- output_target.puts line
- else
- raise "Invalid service type #{service.type}"
- end
- end
- end
-
- def self.get_host_data(verbose, service, hostnames = [])
- result = {}
+ def self.pretty_print_hosts(verbose, service, hostnames = [])
hostnames = [hostnames] unless hostnames.is_a? Array
hostnames.each do |hostname|
- response = service.query(verbose, hostname)
- host_data = response[hostname]
- if block_given?
- yield host_data result
- else
+ begin
+ response = service.query(verbose, hostname)
+ host_data = response[hostname]
+
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'
+ 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'
- result[hostname] = host_data
+ 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'
- result[hostname] = host_data
+ line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
+ line += ", #{host_data['hours_left_on_reservation']}h remaining"
+ line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty?
+ line += ')'
+ puts line
else
raise "Invalid service type #{service.type}"
end
+ rescue StandardError => e
+ STDERR.puts("Something went wrong while trying to gather information on #{hostname}:")
+ STDERR.puts(e)
end
- rescue StandardError => e
- FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:")
- FloatyLogger.error(e)
end
- result
end
def self.pretty_print_status(verbose, service)
@@ -214,16 +125,18 @@ class Utils
width = pools.keys.map(&:length).max
pools.each do |name, pool|
- max = pool['max']
- ready = pool['ready']
- pending = pool['pending']
- missing = max - ready - pending
- char = 'o'
- puts "#{name.ljust(width)} #{(char * ready)}#{(char * pending)}#{(char * missing)}"
- rescue StandardError => e
- FloatyLogger.error "#{name.ljust(width)} #{e}"
+ 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
end
- puts message
+ puts message.colorize(status_response['status']['ok'] ? :default : :red)
when 'NonstandardPooler'
pools = status_response
pools.delete 'ok'
@@ -231,18 +144,20 @@ class Utils
width = pools.keys.map(&:length).max
pools.each do |name, pool|
- 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)}#{(char * pending)}#{(char * missing)}"
- rescue StandardError => e
- FloatyLogger.error "#{name.ljust(width)} #{e}"
+ 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
end
when 'ABS'
- FloatyLogger.error 'ABS Not OK' unless status_response
- puts 'ABS is OK' 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
@@ -257,15 +172,12 @@ class Utils
end
def self.get_service_object(type = '')
- abs_strings = %w[abs alwaysbescheduling always_be_scheduling]
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
+ abs_strings = %w[abs alwaysbescheduling always_be_scheduling]
+ if nspooler_strings.include? type.downcase
NonstandardPooler
- elsif vmpooler_strings.include? type.downcase
- Pooler
+ elsif abs_strings.include? type.downcase
+ ABS
else
Pooler
end
@@ -274,11 +186,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'],
+ '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']
@@ -289,17 +200,11 @@ 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]
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
@@ -310,30 +215,4 @@ class Utils
service_config
end
-
- # This method gets the vmpooler service configured in ~/.vmfloaty
- 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 = {
- '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
- 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
- end
end
diff --git a/lib/vmfloaty/version.rb b/lib/vmfloaty/version.rb
index aab63a3..145a681 100644
--- a/lib/vmfloaty/version.rb
+++ b/lib/vmfloaty/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class Vmfloaty
- VERSION = '1.8.1'
+ VERSION = '0.9.2'
end
diff --git a/release-prep b/release-prep
deleted file mode 100755
index 82ee104..0000000
--- a/release-prep
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-
-# bundle install
-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 -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)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 1ed7ef7..558a0ad 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,25 +1,5 @@
# frozen_string_literal: true
-require 'simplecov'
-require 'simplecov-lcov'
-require 'base64'
-
-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
-
require 'vmfloaty'
require 'webmock/rspec'
@@ -35,19 +15,3 @@ 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 ca1aec2..555d6c5 100644
--- a/spec/vmfloaty/abs/auth_spec.rb
+++ b/spec/vmfloaty/abs/auth_spec.rb
@@ -3,11 +3,7 @@
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
@@ -19,20 +15,18 @@ describe Pooler do
end
it 'returns a token from abs' do
- 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: {})
+ stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token')
+ .to_return(:status => 200, :body => @get_token_response, :headers => {})
- token = Auth.get_token(false, @abs_url, user, pass)
+ 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://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: {})
+ stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token')
+ .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
- expect { Auth.get_token(false, @abs_url, user, pass) }.to raise_error(TokenError)
+ expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError)
end
end
@@ -43,24 +37,21 @@ describe Pooler do
end
it 'deletes the specified token' do
- 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: {})
+ stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
+ .to_return(:status => 200, :body => @delete_token_response, :headers => {})
- expect(Auth.delete_token(false, @abs_url, user, pass,
- @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://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
- .with(headers: get_headers(username: user, password: pass))
- .to_return(status: 500, body: '{"ok":false}', headers: {})
+ stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
+ .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
- expect { Auth.delete_token(false, @abs_url, user, pass, @token) }.to raise_error(TokenError)
+ 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, user, pass, nil) }.to raise_error(TokenError)
+ expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', nil) }.to raise_error(TokenError)
end
end
@@ -72,16 +63,16 @@ describe Pooler do
it 'checks the status of a token' do
stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
- .with(headers: get_headers)
- .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: get_headers)
- .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 4a66c5c..b59380a 100644
--- a/spec/vmfloaty/abs_spec.rb
+++ b/spec/vmfloaty/abs_spec.rb
@@ -9,78 +9,26 @@ describe ABS do
before :each do
end
- 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: {})
- 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: {})
-
- 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/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: {})
-
- 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'
+ 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' }
+ { '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_response = ABS.translated(abs_formatted_response)
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
- 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')
@@ -91,22 +39,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 = %w[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
@@ -120,9 +68,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'
@@ -130,17 +78,17 @@ describe ABS do
end
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: {})
+ 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'
- }]
+ 'type' => 'win-2012r2-x86_64',
+ 'engine' => 'vmpooler',
+ }],
)
end
end
@@ -150,13 +98,9 @@ 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"}]
- }
+ @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'
@@ -165,16 +109,16 @@ describe ABS do
end
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: {})
- stub_request(:post, 'https://abs.example.com/api/v2/return')
- .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: {})
+ 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 }
+ '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 6ce4b77..65cadc4 100644
--- a/spec/vmfloaty/auth_spec.rb
+++ b/spec/vmfloaty/auth_spec.rb
@@ -3,9 +3,6 @@
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'
@@ -18,20 +15,18 @@ describe Pooler do
end
it 'returns a token from vmpooler' do
- 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: {})
+ stub_request(:post, 'https://first.last:password@vmpooler.example.com/token')
+ .to_return(:status => 200, :body => @get_token_response, :headers => {})
- token = Auth.get_token(false, @vmpooler_url, user, pass)
+ 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://vmpooler.example.com/token')
- .with(headers: get_headers(username: user, password: pass, content_length: 0))
- .to_return(status: 500, body: '{"ok":false}', headers: {})
+ stub_request(:post, 'https://first.last:password@vmpooler.example.com/token')
+ .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
- expect { Auth.get_token(false, @vmpooler_url, user, pass) }.to raise_error(TokenError)
+ expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError)
end
end
@@ -42,18 +37,15 @@ describe Pooler do
end
it 'deletes the specified token' do
- 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: {})
+ stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
+ .to_return(:status => 200, :body => @delete_token_response, :headers => {})
- expect(Auth.delete_token(false, @vmpooler_url, user, pass,
- @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://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
- .with(headers: get_headers(username: user, password: pass))
- .to_return(status: 500, body: '{"ok":false}', headers: {})
+ stub_request(:delete, 'https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
+ .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
end
@@ -71,16 +63,14 @@ 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: {})
+ .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: get_headers)
- .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 1f86dd2..8bcfe3c 100644
--- a/spec/vmfloaty/nonstandard_pooler_spec.rb
+++ b/spec/vmfloaty/nonstandard_pooler_spec.rb
@@ -8,7 +8,9 @@ require 'vmfloaty/nonstandard_pooler'
describe NonstandardPooler do
before :each do
@nspooler_url = 'https://nspooler.example.com'
- @auth_token_headers = get_headers(token: 'token-value')
+ @auth_token_headers = {
+ 'X-Auth-Token' => 'token-value',
+ }
end
describe '#list' do
@@ -34,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
@@ -42,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
@@ -51,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
@@ -87,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 %w[sol10-9 sol10-11]
+ expect(list).to eql ['sol10-9', 'sol10-11']
end
end
@@ -119,19 +121,17 @@ describe NonstandardPooler do
it 'raises an AuthError if the token is invalid' do
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
- .with(headers: get_headers(token: 'token-value'))
- .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 do
- NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {})
- end.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
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,16 +142,15 @@ 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
@@ -163,22 +162,22 @@ 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
it 'modifies the reason of a vm' do
- modify_request_body = { '{"reserved_for_reason":"testing"}' => nil }
+ 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
@@ -209,7 +208,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
@@ -232,7 +231,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
@@ -257,7 +256,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
@@ -272,8 +271,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
@@ -281,8 +280,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 e9cebdd..6d7def0 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
@@ -84,26 +84,6 @@ 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
@@ -117,11 +97,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}' => nil },
- headers: get_headers(content_type: 'application/x-www-form-urlencoded', 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 +116,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 +135,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 +158,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 +172,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,18 +187,15 @@ 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 do
- Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile',
- nil)
- end.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
@@ -234,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: { '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 70c7199..13426b3 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 ec5fd4e..c780a88 100644
--- a/spec/vmfloaty/ssh_spec.rb
+++ b/spec/vmfloaty/ssh_spec.rb
@@ -4,35 +4,24 @@ require 'spec_helper'
require 'vmfloaty/ssh'
class ServiceStub
- def retrieve(_verbose, os_types, _use_token, ondemand)
+ 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
- }
-
- 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
+ '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_api_v1_host_string' || os_types == 'vmpooler_api_v2_host_string'
- end
-
- def wait_for_request(verbose, requestid)
- return true
+ return 'vmpooler' if os_types == 'vmpooler_host_string'
end
end
@@ -40,73 +29,21 @@ describe Ssh do
before :each do
end
- 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
+ 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
- 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
+ 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
diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb
index 37d2537..7fd795b 100644
--- a/spec/vmfloaty/utils_spec.rb
+++ b/spec/vmfloaty/utils_spec.rb
@@ -5,15 +5,10 @@ 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
- @vmpooler_api_v1_response_body = '{
+ @vmpooler_response_body = '{
"ok": true,
"domain": "delivery.mycompany.net",
"ubuntu-1610-x86_64": {
@@ -23,15 +18,6 @@ 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": {
@@ -43,23 +29,15 @@ describe Utils do
}'
end
- 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'])
+ 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'],
+ 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
@@ -67,12 +45,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)
@@ -99,39 +77,31 @@ 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
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
@@ -143,26 +113,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
@@ -184,544 +154,97 @@ 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' }
- let(:verbose) { nil }
- let(:print_to_stderr) { false }
- before(:each) 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',
+ } }
+ 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(anything, hostname)
+ .with(nil, hostname)
.and_return(response_body)
+
+ Utils.pretty_print_hosts(nil, service, hostname)
end
- subject { Utils.pretty_print_hosts(verbose, service, hostname, print_to_stderr) }
+ 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)'
- describe 'with vmpooler api v2 service' do
- let(:service) { Service.new(MockOptions.new, 'url' => url) }
+ expect(Utils).to receive(:puts).with(output)
- let(:hostname) { 'mcpy42eqjxli9g2' }
- let(:fqdn) { [hostname, 'delivery.puppetlabs.net'].join('.') }
+ service = Service.new(MockOptions.new, 'url' => url)
+ allow(service).to receive(:query)
+ .with(nil, hostname)
+ .and_return(response_body)
- 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
+ Utils.pretty_print_hosts(nil, service, hostname)
end
- describe 'with vmpooler api v1 service' do
- let(:service) { Service.new(MockOptions.new, 'url' => url) }
+ 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)'
- let(:hostname) { 'mcpy42eqjxli9g2' }
- let(:domain) { 'delivery.mycompany.net' }
- let(:fqdn) { [hostname, domain].join('.') }
+ expect(Utils).to receive(:puts).with(output)
- 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
+ service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
+ allow(service).to receive(:query)
+ .with(nil, hostname)
+ .and_return(response_body)
- 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',
- 'domain' => domain
- }
- }
- 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
+ Utils.pretty_print_hosts(nil, service, hostname)
end
- describe 'with nonstandard pooler service' do
- let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') }
+ 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)'
- 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
+ expect(Utils).to receive(:puts).with(output)
- let(:default_output) { "- #{hostname} (solaris-11-sparc, 35.89h remaining)" }
+ service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
+ allow(service).to receive(:query)
+ .with(nil, hostname)
+ .and_return(response_body)
- 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
-
- describe 'with ABS service' do
- let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
-
- let(:hostname) { '1597952189390' }
- let(:fqdn) { 'example-noun.delivery.mycompany.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
- let(:response_body) do
- {
- hostname => {
- 'state' => 'allocated',
- 'allocated_resources' => [
- {
- 'hostname' => fqdn,
- 'type' => template,
- 'engine' => 'vmpooler'
- }
- ],
- '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})" }
-
- 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)
-
- 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} (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 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 = " - DESTROYED #{fqdn}"
- 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 }
-
- 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)
-
- subject
- 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})" }
- 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
- 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 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'
- }
- }
- }
- allow(Conf).to receive(:read_config).and_return(config)
- 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'
- },
- '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'
- })
+ Utils.pretty_print_hosts(nil, service, hostname)
end
end
end
diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec
index 184247b..27f335c 100644
--- a/vmfloaty.gemspec
+++ b/vmfloaty.gemspec
@@ -6,13 +6,10 @@ require 'vmfloaty/version'
Gem::Specification.new do |s|
s.name = 'vmfloaty'
s.version = Vmfloaty::VERSION
- s.authors = [
- 'Brian Cain',
- 'Puppet'
- ]
- s.email = 'info@puppet.com'
+ s.authors = ['Brian Cain']
+ s.email = ['brianccain@gmail.com']
s.license = 'Apache-2.0'
- s.homepage = 'https://github.com/puppetlabs/vmfloaty'
+ 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'
@@ -21,6 +18,7 @@ Gem::Specification.new do |s|
s.test_files = Dir['spec/**/*']
s.require_path = 'lib'
- s.add_dependency 'commander', '>= 4.4.3', '< 4.7.0'
- s.add_dependency 'faraday', '~> 1.5', '>= 1.5.1'
+ s.add_dependency 'colorize', '~> 0.8.1'
+ s.add_dependency 'commander', '~> 4.4.3'
+ s.add_dependency 'faraday', '~> 0.17.0'
end