Compare commits

...

417 commits
v0.7.5 ... main

Author SHA1 Message Date
puppet-release-bot
6b6d6f73cd
Merge pull request #242 from puppetlabs/dependabot/docker/ruby-3.3.5-slim-bullseye
Bump ruby from 3.3.4-slim-bullseye to 3.3.5-slim-bullseye
2024-09-09 05:57:47 -04:00
dependabot[bot]
b2fd9313f8
Bump ruby from 3.3.4-slim-bullseye to 3.3.5-slim-bullseye
Bumps ruby from 3.3.4-slim-bullseye to 3.3.5-slim-bullseye.

---
updated-dependencies:
- dependency-name: ruby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 09:56:48 +00:00
puppet-release-bot
41d55e44b8
Merge pull request #241 from puppetlabs/dependabot/bundler/simplecov-html-0.13.1
Bump simplecov-html from 0.12.3 to 0.13.1
2024-09-09 05:53:50 -04:00
puppet-release-bot
fa92cad278
Merge pull request #240 from puppetlabs/dependabot/bundler/rubocop-1.66.1
Bump rubocop from 1.66.0 to 1.66.1
2024-09-09 05:53:32 -04:00
dependabot[bot]
8df6ceb676
Bump simplecov-html from 0.12.3 to 0.13.1
Bumps [simplecov-html](https://github.com/simplecov-ruby/simplecov-html) from 0.12.3 to 0.13.1.
- [Release notes](https://github.com/simplecov-ruby/simplecov-html/releases)
- [Changelog](https://github.com/simplecov-ruby/simplecov-html/blob/main/CHANGELOG.md)
- [Commits](https://github.com/simplecov-ruby/simplecov-html/compare/v0.12.3...v0.13.1)

---
updated-dependencies:
- dependency-name: simplecov-html
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 09:52:53 +00:00
dependabot[bot]
197c6e2e60
Bump rubocop from 1.66.0 to 1.66.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.66.0 to 1.66.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.66.0...v1.66.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 09:52:46 +00:00
puppet-release-bot
d6f1eeddc6
Merge pull request #239 from puppetlabs/dependabot/bundler/rubocop-1.66.0
Bump rubocop from 1.65.1 to 1.66.0
2024-09-02 05:25:16 -04:00
dependabot[bot]
721881395c
Bump rubocop from 1.65.1 to 1.66.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.65.1 to 1.66.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.65.1...v1.66.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-02 09:24:28 +00:00
puppet-release-bot
6a46261844
Merge pull request #237 from puppetlabs/dependabot/bundler/rubocop-1.65.1
Bump rubocop from 1.64.1 to 1.65.1
2024-08-01 22:00:17 -04:00
dependabot[bot]
d26bac7409
Bump rubocop from 1.64.1 to 1.65.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.64.1 to 1.65.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.64.1...v1.65.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-02 01:59:32 +00:00
puppet-release-bot
f0195ee4db
Merge pull request #236 from puppetlabs/dependabot/bundler/rexml-3.3.3
Bump rexml from 3.2.8 to 3.3.3
2024-08-01 21:58:17 -04:00
dependabot[bot]
82f522e911
Bump rexml from 3.2.8 to 3.3.3
Bumps [rexml](https://github.com/ruby/rexml) from 3.2.8 to 3.3.3.
- [Release notes](https://github.com/ruby/rexml/releases)
- [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md)
- [Commits](https://github.com/ruby/rexml/compare/v3.2.8...v3.3.3)

---
updated-dependencies:
- dependency-name: rexml
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-02 01:57:30 +00:00
puppet-release-bot
d46b7f10ef
Merge pull request #235 from puppetlabs/dependabot/docker/ruby-3.3.4-slim-bullseye
Bump ruby from 3.3.3-slim-bullseye to 3.3.4-slim-bullseye
2024-07-15 05:40:42 -04:00
dependabot[bot]
e4151a00ce
Bump ruby from 3.3.3-slim-bullseye to 3.3.4-slim-bullseye
Bumps ruby from 3.3.3-slim-bullseye to 3.3.4-slim-bullseye.

---
updated-dependencies:
- dependency-name: ruby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 09:39:58 +00:00
puppet-release-bot
bea7434436
Merge pull request #232 from puppetlabs/dependabot/docker/ruby-3.3.3-slim-bullseye
Bump ruby from 3.3.2-slim-bullseye to 3.3.3-slim-bullseye
2024-06-17 05:59:27 -04:00
dependabot[bot]
58ddd50618
Bump ruby from 3.3.2-slim-bullseye to 3.3.3-slim-bullseye
Bumps ruby from 3.3.2-slim-bullseye to 3.3.3-slim-bullseye.

---
updated-dependencies:
- dependency-name: ruby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-17 09:58:43 +00:00
puppet-release-bot
6285e2c854
Merge pull request #231 from puppetlabs/dependabot/bundler/rubocop-1.64.1
Bump rubocop from 1.64.0 to 1.64.1
2024-06-03 05:29:10 -04:00
dependabot[bot]
d1806b23eb
Bump rubocop from 1.64.0 to 1.64.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.64.0 to 1.64.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.64.0...v1.64.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 09:28:26 +00:00
puppet-release-bot
43b1977721
Merge pull request #230 from puppetlabs/dependabot/docker/ruby-3.3.2-slim-bullseye
Bump ruby from 3.3.1-slim-bullseye to 3.3.2-slim-bullseye
2024-06-03 05:25:11 -04:00
dependabot[bot]
dc0e440c86
Bump ruby from 3.3.1-slim-bullseye to 3.3.2-slim-bullseye
Bumps ruby from 3.3.1-slim-bullseye to 3.3.2-slim-bullseye.

---
updated-dependencies:
- dependency-name: ruby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 09:24:25 +00:00
puppet-release-bot
98c45a5ed3
Merge pull request #229 from puppetlabs/dependabot/bundler/webmock-3.23.1
Bump webmock from 3.23.0 to 3.23.1
2024-05-27 05:45:55 -04:00
dependabot[bot]
06a9b95edf
Bump webmock from 3.23.0 to 3.23.1
Bumps [webmock](https://github.com/bblimke/webmock) from 3.23.0 to 3.23.1.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.23.0...v3.23.1)

---
updated-dependencies:
- dependency-name: webmock
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 09:45:18 +00:00
puppet-release-bot
83d23be8d7
Merge pull request #228 from puppetlabs/dependabot/bundler/rubocop-1.64.0
Bump rubocop from 1.63.5 to 1.64.0
2024-05-27 05:44:50 -04:00
dependabot[bot]
5b09d14926
Bump rubocop from 1.63.5 to 1.64.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.5 to 1.64.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.63.5...v1.64.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 09:44:03 +00:00
puppet-release-bot
e575ee1ba8
Merge pull request #227 from puppetlabs/dependabot/bundler/rexml-3.2.8
Bump rexml from 3.2.6 to 3.2.8
2024-05-16 17:29:07 -04:00
dependabot[bot]
ddc35eb118
Bump rexml from 3.2.6 to 3.2.8
Bumps [rexml](https://github.com/ruby/rexml) from 3.2.6 to 3.2.8.
- [Release notes](https://github.com/ruby/rexml/releases)
- [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md)
- [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.2.8)

---
updated-dependencies:
- dependency-name: rexml
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-16 21:28:17 +00:00
puppet-release-bot
2acf63c8ba
Merge pull request #226 from puppetlabs/dependabot/bundler/rubocop-1.63.5
Bump rubocop from 1.63.4 to 1.63.5
2024-05-13 05:09:18 -04:00
dependabot[bot]
3213b33b98
Bump rubocop from 1.63.4 to 1.63.5
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.4 to 1.63.5.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.63.4...v1.63.5)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-13 09:08:29 +00:00
puppet-release-bot
813e76befc
Merge pull request #225 from puppetlabs/dependabot/docker/ruby-3.3.1-slim-bullseye
Bump ruby from 3.3.0-slim-bullseye to 3.3.1-slim-bullseye
2024-04-29 05:48:10 -04:00
dependabot[bot]
473f584a90
Bump ruby from 3.3.0-slim-bullseye to 3.3.1-slim-bullseye
Bumps ruby from 3.3.0-slim-bullseye to 3.3.1-slim-bullseye.

---
updated-dependencies:
- dependency-name: ruby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 09:47:27 +00:00
puppet-release-bot
83bf0877b6
Merge pull request #224 from puppetlabs/dependabot/bundler/rubocop-1.63.4
Bump rubocop from 1.63.2 to 1.63.4
2024-04-29 05:41:03 -04:00
dependabot[bot]
7f32c1aeb2
Bump rubocop from 1.63.2 to 1.63.4
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.2 to 1.63.4.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.63.2...v1.63.4)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 09:40:13 +00:00
puppet-release-bot
40a0b2e2c6
Merge pull request #223 from puppetlabs/dependabot/bundler/rubocop-1.63.2
Bump rubocop from 1.63.1 to 1.63.2
2024-04-22 05:59:28 -04:00
dependabot[bot]
00484568c0
Bump rubocop from 1.63.1 to 1.63.2
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.1 to 1.63.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.63.1...v1.63.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-22 09:58:43 +00:00
puppet-release-bot
6e7c609d10
Merge pull request #222 from puppetlabs/dependabot/bundler/rubocop-1.63.1
Bump rubocop from 1.63.0 to 1.63.1
2024-04-15 05:48:57 -04:00
dependabot[bot]
30938db02e
Bump rubocop from 1.63.0 to 1.63.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.0 to 1.63.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.63.0...v1.63.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-15 09:46:40 +00:00
puppet-release-bot
6c1fe12a44
Merge pull request #221 from puppetlabs/dependabot/bundler/rubocop-1.63.0
Bump rubocop from 1.62.1 to 1.63.0
2024-04-08 05:14:54 -04:00
puppet-release-bot
3425bec1d8
Merge pull request #220 from puppetlabs/dependabot/bundler/rake-13.2.1
Bump rake from 13.1.0 to 13.2.1
2024-04-08 05:14:37 -04:00
dependabot[bot]
03d7bb7963
Bump rubocop from 1.62.1 to 1.63.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.62.1 to 1.63.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.62.1...v1.63.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-08 09:13:58 +00:00
dependabot[bot]
c1f93e40f7
Bump rake from 13.1.0 to 13.2.1
Bumps [rake](https://github.com/ruby/rake) from 13.1.0 to 13.2.1.
- [Release notes](https://github.com/ruby/rake/releases)
- [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc)
- [Commits](https://github.com/ruby/rake/compare/v13.1.0...v13.2.1)

---
updated-dependencies:
- dependency-name: rake
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-08 09:13:47 +00:00
puppet-release-bot
e61be465ed
Merge pull request #219 from puppetlabs/dependabot/bundler/rubocop-1.62.1
Bump rubocop from 1.62.0 to 1.62.1
2024-03-18 05:16:00 -04:00
dependabot[bot]
e58a1eb68e
Bump rubocop from 1.62.0 to 1.62.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.62.0 to 1.62.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.62.0...v1.62.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 09:15:14 +00:00
puppet-release-bot
8f42af544a
Merge pull request #218 from puppetlabs/dependabot/bundler/rubocop-1.62.0
Bump rubocop from 1.61.0 to 1.62.0
2024-03-11 05:06:07 -04:00
dependabot[bot]
c0609d87b7
Bump rubocop from 1.61.0 to 1.62.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.61.0 to 1.62.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.61.0...v1.62.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 09:05:24 +00:00
puppet-release-bot
0d20d2cf2f
Merge pull request #217 from puppetlabs/dependabot/bundler/rubocop-1.61.0
Bump rubocop from 1.60.2 to 1.61.0
2024-03-04 04:55:24 -05:00
dependabot[bot]
961e3d9b3d
Bump rubocop from 1.60.2 to 1.61.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.60.2 to 1.61.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.60.2...v1.61.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 09:54:41 +00:00
puppet-release-bot
debc766d28
Merge pull request #216 from puppetlabs/dependabot/bundler/webmock-3.23.0
Bump webmock from 3.20.0 to 3.23.0
2024-02-26 04:37:50 -05:00
dependabot[bot]
df08f383fe
Bump webmock from 3.20.0 to 3.23.0
Bumps [webmock](https://github.com/bblimke/webmock) from 3.20.0 to 3.23.0.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.20.0...v3.23.0)

---
updated-dependencies:
- dependency-name: webmock
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 09:37:08 +00:00
puppet-release-bot
11beb6c933
Merge pull request #215 from puppetlabs/dependabot/bundler/webmock-3.20.0
Bump webmock from 3.19.1 to 3.20.0
2024-02-12 04:51:17 -05:00
dependabot[bot]
a5d5cdc53f
Bump webmock from 3.19.1 to 3.20.0
Bumps [webmock](https://github.com/bblimke/webmock) from 3.19.1 to 3.20.0.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.19.1...v3.20.0)

---
updated-dependencies:
- dependency-name: webmock
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 09:50:28 +00:00
puppet-release-bot
edff58a319
Merge pull request #214 from puppetlabs/dependabot/bundler/rspec-3.13.0
Bump rspec from 3.12.0 to 3.13.0
2024-02-05 04:33:44 -05:00
dependabot[bot]
cc018b0599
Bump rspec from 3.12.0 to 3.13.0
Bumps [rspec](https://github.com/rspec/rspec-metagem) from 3.12.0 to 3.13.0.
- [Commits](https://github.com/rspec/rspec-metagem/compare/v3.12.0...v3.13.0)

---
updated-dependencies:
- dependency-name: rspec
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 09:32:57 +00:00
puppet-release-bot
858e627c62
Merge pull request #213 from puppetlabs/dependabot/bundler/rubocop-1.60.2
Bump rubocop from 1.60.1 to 1.60.2
2024-01-29 04:03:26 -05:00
dependabot[bot]
cd412f8a07
Bump rubocop from 1.60.1 to 1.60.2
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.60.1 to 1.60.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.60.1...v1.60.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 09:02:48 +00:00
puppet-release-bot
0d8cb0232f
Merge pull request #212 from puppetlabs/dependabot/bundler/rubocop-1.60.1
Bump rubocop from 1.59.0 to 1.60.1
2024-01-22 04:22:58 -05:00
dependabot[bot]
0352a687c6
Bump rubocop from 1.59.0 to 1.60.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.59.0 to 1.60.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.59.0...v1.60.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 09:22:11 +00:00
Jake Spain
b388bc5f48
Merge pull request #209 from puppetlabs/fix-release-prep-param
(maint) Fix missing param in auto_release_prep
2024-01-19 16:48:17 -05:00
Jake Spain
4c9c82a7c2
Remove interactive option from release prep script 2024-01-19 15:12:37 -05:00
Jake Spain
50d3088ad8
Fix missing param in auto_release_prep 2024-01-15 09:24:30 -05:00
puppet-release-bot
cf362c4f08
Merge pull request #207 from puppetlabs/dependabot/docker/ruby-3.3.0-slim-bullseye
Bump ruby from 3.2.2-slim-bullseye to 3.3.0-slim-bullseye
2024-01-01 04:15:57 -05:00
dependabot[bot]
375eb6b9fd
Bump ruby from 3.2.2-slim-bullseye to 3.3.0-slim-bullseye
Bumps ruby from 3.2.2-slim-bullseye to 3.3.0-slim-bullseye.

---
updated-dependencies:
- dependency-name: ruby
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 09:15:12 +00:00
puppet-release-bot
d5f1d61bd1
Merge pull request #206 from puppetlabs/dependabot/bundler/rubocop-1.59.0
Bump rubocop from 1.58.0 to 1.59.0
2023-12-18 04:06:21 -05:00
dependabot[bot]
85ae0c9914
Bump rubocop from 1.58.0 to 1.59.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.58.0 to 1.59.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.58.0...v1.59.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 09:05:38 +00:00
puppet-release-bot
b460f1b2a8
Merge pull request #203 from puppetlabs/dependabot/bundler/rubocop-1.58.0
Bump rubocop from 1.56.4 to 1.58.0
2023-12-07 09:24:38 -05:00
Jake Spain
511ad870a5
Merge pull request #204 from puppetlabs/dependabot/github_actions/actions/setup-java-4
Bump actions/setup-java from 3 to 4
2023-12-07 09:15:31 -05:00
dependabot[bot]
93ecadf49a
Bump actions/setup-java from 3 to 4
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 14:14:53 +00:00
dependabot[bot]
05ae2e55da
Bump rubocop from 1.56.4 to 1.58.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.4 to 1.58.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.56.4...v1.58.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 14:14:46 +00:00
Jake Spain
b194e4a881
Merge pull request #202 from puppetlabs/dependabot/github_actions/actions/github-script-7
Bump actions/github-script from 6 to 7
2023-12-07 09:14:02 -05:00
dependabot[bot]
494bd3412c
Bump actions/github-script from 6 to 7
Bumps [actions/github-script](https://github.com/actions/github-script) from 6 to 7.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 13:50:01 +00:00
puppet-release-bot
415b92ff97
Merge pull request #201 from puppetlabs/dependabot/bundler/rake-13.1.0
Bump rake from 13.0.6 to 13.1.0
2023-12-07 08:46:30 -05:00
dependabot[bot]
03ebf1d79a
Bump rake from 13.0.6 to 13.1.0
Bumps [rake](https://github.com/ruby/rake) from 13.0.6 to 13.1.0.
- [Release notes](https://github.com/ruby/rake/releases)
- [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc)
- [Commits](https://github.com/ruby/rake/compare/v13.0.6...v13.1.0)

---
updated-dependencies:
- dependency-name: rake
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 13:45:52 +00:00
Jake Spain
affbdd64c4
Merge pull request #205 from puppetlabs/repo-sync
Add dependabot, release prep, and label reusable workflows from release-engineering-repo-standards
2023-12-07 08:45:03 -05:00
Jake Spain
5953ad89a4
syncing files from release-engineering-repo-standards 2023-12-06 17:15:07 -05:00
Jake Spain
215ec97dcf
Merge pull request #195 from puppetlabs/dependabot/github_actions/docker/build-push-action-5
Bump docker/build-push-action from 4 to 5
2023-10-02 09:47:56 -04:00
Jake Spain
28b64a6913
Merge pull request #198 from puppetlabs/dependabot/bundler/rubocop-1.56.4
Bump rubocop from 1.56.3 to 1.56.4
2023-10-02 09:38:05 -04:00
dependabot[bot]
c5ea73a3ad
Bump rubocop from 1.56.3 to 1.56.4
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.3 to 1.56.4.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.56.3...v1.56.4)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 09:05:59 +00:00
Jake Spain
648cb150c9
Merge pull request #196 from puppetlabs/dependabot/github_actions/docker/setup-buildx-action-3
Bump docker/setup-buildx-action from 2 to 3
2023-09-18 08:11:26 -04:00
Jake Spain
296a2eb5ef
Merge pull request #197 from puppetlabs/dependabot/github_actions/docker/login-action-3
Bump docker/login-action from 2 to 3
2023-09-18 08:11:04 -04:00
dependabot[bot]
df45ec0180
Bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 09:50:25 +00:00
dependabot[bot]
f77bb2b29a
Bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 09:50:21 +00:00
dependabot[bot]
ded2cd69dd
Bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 09:50:18 +00:00
Jake Spain
05432f0387
Merge pull request #193 from puppetlabs/dependabot/bundler/rubocop-1.56.3
Bump rubocop from 1.56.2 to 1.56.3
2023-09-11 08:22:15 -04:00
Jake Spain
aa623ecd3e
Merge pull request #194 from puppetlabs/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-11 08:21:13 -04:00
dependabot[bot]
9f72be5126
Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 09:36:32 +00:00
dependabot[bot]
a2bf9ead58
Bump rubocop from 1.56.2 to 1.56.3
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.2 to 1.56.3.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.56.2...v1.56.3)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 09:11:43 +00:00
Jake Spain
91328afc96
Merge pull request #191 from puppetlabs/dependabot/bundler/webmock-3.19.1
Bump webmock from 3.19.0 to 3.19.1
2023-09-05 09:37:37 -04:00
Jake Spain
93aef491c6
Merge pull request #192 from puppetlabs/dependabot/bundler/rubocop-1.56.2
Bump rubocop from 1.56.1 to 1.56.2
2023-09-05 09:37:10 -04:00
dependabot[bot]
75cd758aad
Bump rubocop from 1.56.1 to 1.56.2
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.1 to 1.56.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.56.1...v1.56.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 09:19:02 +00:00
dependabot[bot]
ae42ba08ae
Bump webmock from 3.19.0 to 3.19.1
Bumps [webmock](https://github.com/bblimke/webmock) from 3.19.0 to 3.19.1.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.19.0...v3.19.1)

---
updated-dependencies:
- dependency-name: webmock
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 09:18:54 +00:00
Jake Spain
e5c47691d3
Merge pull request #190 from puppetlabs/dependabot/bundler/webmock-3.19.0
Bump webmock from 3.18.1 to 3.19.0
2023-08-28 07:59:49 -04:00
dependabot[bot]
6afb47c609
Bump webmock from 3.18.1 to 3.19.0
Bumps [webmock](https://github.com/bblimke/webmock) from 3.18.1 to 3.19.0.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.18.1...v3.19.0)

---
updated-dependencies:
- dependency-name: webmock
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 09:41:09 +00:00
Jake Spain
0119f38ad9
Merge pull request #189 from puppetlabs/dependabot/bundler/rubocop-1.56.1
Bump rubocop from 1.56.0 to 1.56.1
2023-08-21 07:04:39 -04:00
dependabot[bot]
7f06fbd0bc
Bump rubocop from 1.56.0 to 1.56.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.0 to 1.56.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.56.0...v1.56.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-21 09:31:07 +00:00
Jake Spain
b2cd786a42
Merge pull request #188 from puppetlabs/dependabot/bundler/rubocop-1.56.0
Bump rubocop from 1.55.1 to 1.56.0
2023-08-14 07:06:38 -04:00
dependabot[bot]
ebede7799d
Bump rubocop from 1.55.1 to 1.56.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.55.1 to 1.56.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.55.1...v1.56.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-14 09:43:18 +00:00
Jake Spain
194b0e3aa6
Merge pull request #187 from puppetlabs/release-1.8.1
1.8.1 release prep
2023-08-07 19:38:18 -04:00
Jake Spain
06127d7e67
1.8.1 release prep 2023-08-07 16:13:19 -04:00
Jake Spain
8daf63665d
Bump docker tag to latest used in test matrix 2023-08-07 16:11:06 -04:00
Jake Spain
46810ebf65
Merge pull request #183 from puppetlabs/dependabot/bundler/rubocop-1.55.1
Bump rubocop from 1.54.2 to 1.55.1
2023-08-07 16:06:04 -04:00
dependabot[bot]
7b24c81360
Bump rubocop from 1.54.2 to 1.55.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.54.2 to 1.55.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.54.2...v1.55.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-07 17:59:07 +00:00
Jake Spain
bfae973e46
Merge pull request #186 from puppetlabs/fix_status_path
(RE-15687) Use relative path for pooler status and summary
2023-08-07 13:57:47 -04:00
Jake Spain
6b041f5c48
Use relative path for pooler status and summary 2023-08-07 11:31:37 -04:00
Jake Spain
67020d29b6
Merge pull request #184 from puppetlabs/revert-issue-management
Revert "Migrate issue management to Jira"
2023-08-07 09:59:32 -04:00
Jake Spain
a4e006615e
Revert "Migrate issue management to Jira"
This reverts commit 6fa018d0b1.
2023-08-07 09:53:23 -04:00
Jake Spain
f7016a1a58
Merge pull request #182 from puppetlabs/dependabot/bundler/rubocop-1.54.2
Bump rubocop from 1.52.0 to 1.54.2
2023-07-17 08:02:40 -04:00
dependabot[bot]
3702cc8c98
Bump rubocop from 1.52.0 to 1.54.2
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.52.0 to 1.54.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.52.0...v1.54.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 09:56:10 +00:00
Jake Spain
f9c6043a47
Merge pull request #177 from puppetlabs/dependabot/bundler/rubocop-1.52.0
Bump rubocop from 1.51.0 to 1.52.0
2023-06-05 08:08:03 -04:00
dependabot[bot]
0d7119bb8a
Bump rubocop from 1.51.0 to 1.52.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.51.0 to 1.52.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.51.0...v1.52.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 09:56:37 +00:00
Jake Spain
3680668a08
Merge pull request #176 from puppetlabs/dependabot/bundler/rubocop-1.51.0
Bump rubocop from 1.50.2 to 1.51.0
2023-05-15 07:40:36 -04:00
dependabot[bot]
ff6ee2ddd8
Bump rubocop from 1.50.2 to 1.51.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.50.2 to 1.51.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.50.2...v1.51.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-15 09:56:34 +00:00
Jake Spain
48e2c035ca
Merge pull request #174 from puppetlabs/dependabot/bundler/rubocop-1.50.2
Bump rubocop from 1.49.0 to 1.50.2
2023-04-20 11:28:06 -04:00
Jake Spain
2db6e8c3fd
Merge pull request #175 from puppetlabs/migrate-issues
Migrate issue management to Jira
2023-04-20 09:56:14 -04:00
Jake Spain
6fa018d0b1
Migrate issue management to Jira 2023-04-20 08:52:58 -04:00
dependabot[bot]
6b6bf539cc
Bump rubocop from 1.49.0 to 1.50.2
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.49.0 to 1.50.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.49.0...v1.50.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-17 09:56:44 +00:00
Jake Spain
99f8cd04aa
Merge pull request #166 from puppetlabs/dependabot/bundler/rspec-tw-3.12.0
Update rspec requirement from ~> 3.11.0 to ~> 3.12.0
2023-04-03 17:18:54 -04:00
dependabot[bot]
5b7b3e69f3
Update rspec requirement from ~> 3.11.0 to ~> 3.12.0
Updates the requirements on [rspec](https://github.com/rspec/rspec-metagem) to permit the latest version.
- [Release notes](https://github.com/rspec/rspec-metagem/releases)
- [Commits](https://github.com/rspec/rspec-metagem/compare/v3.11.0...v3.12.0)

---
updated-dependencies:
- dependency-name: rspec
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 13:08:53 +00:00
Jake Spain
c2bfb5f34f
Merge pull request #167 from puppetlabs/dependabot/bundler/simplecov-tw-0.22.0
Update simplecov requirement from ~> 0.21.2 to ~> 0.22.0
2023-04-03 08:59:50 -04:00
dependabot[bot]
9de7ef1635
Update simplecov requirement from ~> 0.21.2 to ~> 0.22.0
Updates the requirements on [simplecov](https://github.com/simplecov-ruby/simplecov) to permit the latest version.
- [Release notes](https://github.com/simplecov-ruby/simplecov/releases)
- [Changelog](https://github.com/simplecov-ruby/simplecov/blob/main/CHANGELOG.md)
- [Commits](https://github.com/simplecov-ruby/simplecov/compare/v0.21.2...v0.22.0)

---
updated-dependencies:
- dependency-name: simplecov
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 12:38:12 +00:00
Jake Spain
64f7185bdc
Merge pull request #173 from puppetlabs/dependabot/bundler/rubocop-1.49.0
Bump rubocop from 1.48.1 to 1.49.0
2023-04-03 08:37:27 -04:00
dependabot[bot]
2adf27a7e0
Bump rubocop from 1.48.1 to 1.49.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.48.1 to 1.49.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.48.1...v1.49.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 09:56:45 +00:00
Jake Spain
930277a730
Merge pull request #172 from puppetlabs/fix-release-indent
Fix release workflow indentation
2023-03-21 15:04:07 -04:00
Jake Spain
56757d6cb4
Fix release workflow indentation 2023-03-21 14:17:16 -04:00
Jake Spain
da27ffd04c
Merge pull request #171 from puppetlabs/release_prep
1.8.0 release prep
2023-03-21 14:15:18 -04:00
Jake Spain
f327e5d5ee
1.8.0 release prep 2023-03-21 08:29:30 -04:00
Jake Spain
fcea431868
Merge pull request #170 from puppetlabs/docker-and-actions-updates
Docker, Actions, and Docs Updates
2023-03-20 17:03:40 -04:00
Jake Spain
9b669f6aca
Add Gemfile.lock 2023-03-20 15:42:54 -04:00
Jake Spain
4ab4d511f7
Add release instructions and reference docker image 2023-03-20 15:42:53 -04:00
Jake Spain
68843c1ecf
Add changelog 2023-03-20 15:42:52 -04:00
Jake Spain
9fdbb4acb9
Update workflow to check changelog, add release notes and docker push 2023-03-20 15:42:46 -04:00
Jake Spain
dba1215db4
Use Dockerfile for publishing an image 2023-03-20 15:32:55 -04:00
Jake Spain
d50e903167
Dependabot scan for actions updates 2023-03-20 15:32:55 -04:00
Jake Spain
e65a1dad3b
Update test workflow names, action tags, and add ruby 3.2 2023-03-20 15:32:55 -04:00
Jake Spain
90437ddf86
Merge pull request #169 from puppetlabs/fix-vmpooler-api-v2-active
Fix `floaty list --active` for vmpooler api v2
2023-03-20 15:16:40 -04:00
Jake Spain
d5d87ed54a
Fix floaty list --active for vmpooler api v2 2023-03-20 15:06:28 -04:00
Jake Spain
15d9da4514
Merge pull request #168 from puppetlabs/add-mend
(RE-15111) Migrate Synk to Mend
2023-01-20 14:47:52 -05:00
Jake Spain
6f35d0b16b
Migrate Snyk to Mend Scanning 2023-01-20 12:41:02 -05:00
Jake Spain
cda848d214
Change dependabot to weekly 2023-01-19 19:23:14 -05:00
Jake Spain
1258e70d03
Merge pull request #165 from puppetlabs/update_codeowners
(RE-14811) Move codeowners from DIO to RE
2022-08-26 10:33:52 -04:00
Jake Spain
b69b17d00a
Merge pull request #164 from puppetlabs/migrate_snyk
Add Snyk action and Move to RE org
2022-08-26 10:09:38 -04:00
Jake Spain
594544ea67
Move codeowners from DIO to RE 2022-08-26 09:30:51 -04:00
Jake Spain
a93bc24649
Add Snyk action 2022-08-16 17:12:19 -04:00
Jake Spain
9be5cd233e
Merge pull request #163 from puppetlabs/update-codeowners
Add release-engineering to codeowners
2022-08-08 15:04:12 -04:00
Jake Spain
14c160c2bc
Add release-engineering to codeowners 2022-08-08 14:36:32 -04:00
Jake Spain
da3d707fc8
Merge pull request #162 from puppetlabs/release-prep
v1.7.0 release prep
2022-04-05 12:02:52 -04:00
Jake Spain
f74fe22245
v1.7.0 release prep
Includes the following PRs since the last release:
- https://github.com/puppetlabs/vmfloaty/pull/157
- https://github.com/puppetlabs/vmfloaty/pull/160
- https://github.com/puppetlabs/vmfloaty/pull/159
- https://github.com/puppetlabs/vmfloaty/pull/155
- https://github.com/puppetlabs/vmfloaty/pull/152
- https://github.com/puppetlabs/vmfloaty/pull/158
2022-04-05 11:51:23 -04:00
Jake Spain
8f7487b7c3
Merge pull request #158 from puppetlabs/vmpooler-api-v2
(DIO-3101) Add VMPooler API v2 Support
2022-04-05 11:43:16 -04:00
Jake Spain
667dacbcea
Add ondemand flag and api v2 support to floaty ssh 2022-04-05 11:41:44 -04:00
Jake Spain
b84bc2b5d5
Merge pull request #152 from puppetlabs/reviews-and-releases
Docs on contributing and releasing
2022-04-05 11:39:29 -04:00
Jake Spain
3e8ddca1e3
Update release workflow to on dispatch and add notes about releasing 2022-04-05 11:37:53 -04:00
Jake Spain
4103fdeccc
Add VMPooler api v2 support for floaty get 2022-04-04 14:14:40 -04:00
Jake Spain
22b525b5c5
Merge pull request #155 from puppetlabs/dependabot/bundler/rspec-tw-3.11.0
Update rspec requirement from ~> 3.10.0 to ~> 3.11.0
2022-04-04 11:46:15 -04:00
dependabot[bot]
da48a4de0a
Update rspec requirement from ~> 3.10.0 to ~> 3.11.0
Updates the requirements on [rspec](https://github.com/rspec/rspec-metagem) to permit the latest version.
- [Release notes](https://github.com/rspec/rspec-metagem/releases)
- [Commits](https://github.com/rspec/rspec-metagem/compare/v3.10.0...v3.11.0)

---
updated-dependencies:
- dependency-name: rspec
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 15:44:45 +00:00
Samuel
7108af4079
Merge pull request #159 from puppetlabs/bump-ruby
(maint) Add Ruby 3.1 to test matrix + dockerfile and drop EOL Ruby 2.6
2022-04-04 10:42:29 -05:00
Samuel
bbadec174c
Merge pull request #160 from puppetlabs/remove-colorize-usage
(maint) Remove colorize usage from `floaty status`
2022-04-04 10:37:03 -05:00
Jake Spain
6b67c216f5
Remove colorize usage from floaty status 2022-04-04 11:25:56 -04:00
Jake Spain
577579ffdd
Add Ruby 3.1 to test matrix + dockerfile and drop EOL Ruby 2.6 2022-04-04 11:13:31 -04:00
Brandon High
80f832ac20
Merge pull request #157 from binford2k/remove_previous_maintainers
(maint) removing previous maintainers
2022-03-17 23:57:29 -07:00
Ben Ford
0463180a67
(maint) removing previous maintainers
Cleaning up our github org and repos. I checked in with each previous
maintainer and they're cool with being off the hook here ;-)
2022-03-17 08:53:31 -07:00
trvs-sdlr
85c833a290
Merge pull request #156 from puppetlabs/DIO-2700
(DIO-2700) Vmfloaty should not use the Colorize gem
2022-02-16 11:12:14 -08:00
Samuel Beaulieu
6b9b4ea626
(DIO-2700) Vmfloaty should not use the Colorize gem
removing cosmetic use of colorize
2022-02-16 13:07:05 -06:00
Samuel
1b64ce3b03
Merge pull request #154 from cthorn42/maint/main/fix_nspooler_list_active_nil_error
(maint) Fix up nspooler list active bug
2022-02-08 14:04:31 -06:00
Christopher Thorn
5793ea78b9 (maint) Fix up nspooler list active bug
If no reason is defined for checking out a nspooler VM we'd get a nil
refrence error message when listing active nspooler VMs. This PR fixes
that.
2022-02-08 11:53:55 -08:00
903e59afb8
ignore .dccache 2021-10-12 13:48:52 -04:00
Heath Seals
ecf8925775
Merge pull request #151 from puppetlabs/readme-cleanup
Minor cleanup to the readme
2021-10-12 12:44:49 -05:00
61b87a5a58
Minor cleanup to the readme 2021-10-12 13:35:39 -04:00
Heath Seals
2fa122733a
Merge pull request #150 from puppetlabs/release-1.5.0
Release prep for 1.5.0
2021-10-12 12:18:21 -05:00
62f9731910
Release prep for 1.5.0 2021-10-12 13:11:30 -04:00
Tanisha Payne
8573a4e976
Merge pull request #149 from puppetlabs/DIO-2412
DIO 2412- Ondemand and Priority flag added to SSH command
2021-10-12 12:24:30 -04:00
Tanisha Payne
3c3623689a ondemand added to ssh command 2021-10-12 10:39:06 -04:00
Tanisha Payne
bd5d1a36f0 priority flag added to ssh command 2021-10-08 11:44:45 -04:00
Heath Seals
d361f4c0b7
Merge pull request #148 from puppetlabs/DIO-2135
(DIO-2135) Update docker FROM image to ruby 3.0.2
2021-08-13 10:01:31 -05:00
Samuel Beaulieu
33758081d1
(DIO-2135) Update docker FROM image to ruby 3.0.2 2021-08-11 15:13:24 -05:00
17b8dbfa5c
Merge pull request #146 from puppetlabs/release-1.4.0
v1.4.0 release prep
2021-07-21 09:47:38 -04:00
77a3eeb57a
Merge pull request #147 from puppetlabs/ci-updating
Migrate CI to GitHub Actions
2021-07-21 09:47:23 -04:00
38a465e862
Migrate CI to GitHub Actions 2021-07-16 17:13:51 -04:00
b89154648f
v1.4.0 release prep 2021-07-16 16:24:32 -04:00
f2f3a3bfa9
Merge pull request #140 from puppetlabs/dependabot/bundler/commander-gte-4.4.3-and-lt-4.7.0
Update commander requirement from >= 4.4.3, < 4.6.0 to >= 4.4.3, < 4.7.0
2021-07-16 16:20:59 -04:00
dependabot[bot]
bcd08fca15
Update commander requirement from >= 4.4.3, < 4.6.0 to >= 4.4.3, < 4.7.0
Updates the requirements on [commander](https://github.com/commander-rb/commander) to permit the latest version.
- [Release notes](https://github.com/commander-rb/commander/releases)
- [Changelog](https://github.com/commander-rb/commander/blob/master/History.rdoc)
- [Commits](https://github.com/commander-rb/commander/compare/v4.4.3...v4.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-13 17:02:52 +00:00
Brandon High
3b40cbe498
Merge pull request #145 from nmburgan/maint/master/fix_specs
(maint) Use latest Faraday/webmock, update specs
2021-07-13 10:02:14 -07:00
Nick Burgan-Illig
f6febc9b8f (maint) Use latest Faraday/webmock, update specs
This unpins Faraday and webmock, and updates specs so that the Faraday changes (primarily including auth in the header rather than in the URL) is reflected.
2021-07-12 18:33:50 +00:00
302d52a45e
Merge pull request #135 from puppetlabs/rubocop_auto_fix
Run the rubocop auto_correct
2021-07-12 10:04:35 -04:00
Heath Seals
d0fb0f3ac1
Merge pull request #137 from puppetlabs/release-1.3.0
Release prep for v1.3.0
2021-03-03 12:34:25 -06:00
Samuel
38f24f4ad1
Release prep for v1.3.0 2021-03-03 12:25:08 -06:00
Samuel Beaulieu
eb99ba1dec
Run the rubocop auto_correct
fixed 27 files inspected, 975 offenses detected, 804 offenses corrected
2021-02-25 13:38:11 -06:00
Samuel
7041df82f0
Merge pull request #124 from puppetlabs/dependabot/bundler/rubocop-tw-1.6
Update rubocop requirement from ~> 0.52 to ~> 1.6
2021-02-25 13:35:01 -06:00
Samuel
55ead89ab2
Merge pull request #134 from puppetlabs/DIO-1522
(DIO-1522) Show the VM state (running, destroyed) and colorize in red…
2021-02-25 13:24:57 -06:00
Samuel Beaulieu
8143641f83
(DIO-1522) Show the VM state (running, destroyed) and colorize in red when it has been deleted
the ABS system does not have a real sense of the current state of the resources
it has allocated. When running list --active it can list VMs that have been
deleted or reaped after their lifetime expired.
This change enables to show more information when a vmpooler_fallback service
is provided to ABS, and will show the state (running, destroyed) and colorize
in red when the VM is destroyed.
2021-02-25 10:14:41 -06:00
Samuel
f811e252eb
Merge pull request #132 from puppetlabs/release-1.2.0
Release prep for 1.2.0
2021-02-11 09:20:20 -06:00
a9c8d17e9a
Release prep for 1.2.0 2021-02-11 10:16:21 -05:00
796cd8e858
Merge pull request #131 from puppetlabs/DIO-908
(DIO-908) Floaty can now report the status of ABS requests
2021-02-11 10:11:13 -05:00
Samuel Beaulieu
4192631d70 (DIO-908) Adding a way to set Logger level via --loglevel
this is specially useful if you also use in combination --json to remove superfluous stdout
2021-02-09 15:38:43 -06:00
Samuel Beaulieu
a3d8484124 (DIO-908) Floaty can now report the status of ABS requests
- If ABS queries returns a body for 200 or 202, floaty will print it
this is useful in the new version of ABS, since it shows the progress
for ondemand requests (AWS or vmpooler)
- removed the queue_place and querying the queue for a 'get' request
this queue_place number was misleading since it was just a redis index
and did not represent well where the request was in the queue
- Also added a flag option --continue to be used when the cli was
interrupted for example with ctrl-c
2021-02-09 11:29:19 -06:00
Brandon High
f3299285b8
Merge branch 'master' into dependabot/bundler/rubocop-tw-1.6 2020-12-12 14:45:43 -08:00
Brandon High
85a63e85fe
Merge pull request #116 from puppetlabs/dependabot/bundler/rspec-tw-3.10.0
Update rspec requirement from ~> 3.9.0 to ~> 3.10.0
2020-12-12 14:43:52 -08:00
dependabot[bot]
d4c2795df0
Update rubocop requirement from ~> 0.52 to ~> 1.6
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.52.0...v1.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-09 13:04:56 +00:00
dependabot[bot]
c969e9c552
Update rspec requirement from ~> 3.9.0 to ~> 3.10.0
Updates the requirements on [rspec](https://github.com/rspec/rspec) to permit the latest version.
- [Release notes](https://github.com/rspec/rspec/releases)
- [Commits](https://github.com/rspec/rspec/compare/v3.9.0...v3.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 13:03:24 +00:00
e50c9ec4ca
Merge pull request #112 from puppetlabs/v1.1.1
V1.1.1
2020-10-16 16:03:05 -04:00
Samuel Beaulieu
4aa78a1b66 fix tests 2020-10-16 13:23:50 -05:00
Samuel Beaulieu
ced6b46032 (v1.1.1) Prepare for pushing the gem to rubygems 2020-10-16 13:15:15 -05:00
Samuel Beaulieu
846cc7050c when missing, adds the api/v2 to the url endpoint 2020-10-16 13:14:57 -05:00
Samuel
6d1130bc8b
Merge pull request #104 from nwolfe/maint/dont-require-fallback-config
(maint) Don't require configuration file for get
2020-10-09 14:56:25 -05:00
Samuel
ad8196970c
Merge branch 'master' into maint/dont-require-fallback-config 2020-10-09 14:54:29 -05:00
e146857706
Merge pull request #103 from cthorn42/maint/master/add_vmpooler_fallback_to_service_check
(maint) Add vmpooler_fallback to the get service check
2020-10-09 11:52:24 -04:00
3ce0222b38
Merge pull request #105 from puppetlabs/dont-require-vmfloaty.yml-list
(maint) Don't require config file for list --active
2020-10-09 11:45:13 -04:00
221f6c18cc
Merge pull request #107 from puppetlabs/fix-jobid-uniqueness
(maint) Add more uniqueness to jobid and useful termination message
2020-10-09 11:44:29 -04:00
3f8417d192
Merge pull request #106 from puppetlabs/fix-endpoint-check
(maint) Fix bug with detecting ABS service
2020-10-09 11:42:38 -04:00
Samuel Beaulieu
671623bc4f handle ctrl-c and term signal and return useful message on how
to query ABS for the state of the request or to delete it
2020-10-09 10:37:16 -05:00
Samuel Beaulieu
e0fac0bb6c (maint) Add more uniqueness to jobid
Before this change there was a non zero chance that two requests could be received
at the same millisecond and have the same jobid. Added the username as a prefix
to the job id
2020-10-09 10:23:23 -05:00
Samuel Beaulieu
fbd98f93ae (maint) Fix bug with detecting ABS service
Before this change the code would try to check if an object was ABS
by using is_a? which is only for instances of a class. It also compared
with ABS.class which returns the Class class.
Now fixed by comparing the object to the static class
2020-10-09 10:18:53 -05:00
a4231cc6f1
Merge pull request #102 from scotje/service_subcommand_completions
Update completion scripts for `service` subcommands
2020-09-25 13:02:06 -04:00
Nate Wolfe
56f0896d48
(maint) Don't require configuration file for get
Make the vmpooler_fallback optional for cases when there's no
configuration file and everything is specified on the CLI invocation.
2020-09-24 12:32:29 -07:00
Samuel Beaulieu
6deadb2267 Fix tests 2020-09-24 10:00:15 -05:00
Samuel Beaulieu
3a60ffbdbd (maint) Don't require config file for list --active
Will fallback to printing ABS information, which is less than what you
get if vmpooler_fallback is available
2020-09-24 09:46:22 -05:00
Christopher Thorn
5c8aa13081 (maint) Add vmpooler_fallback to the get service check
Previously the vmpooler_fallback setting was not being recognizied, this
PR will fix it.
2020-09-23 15:06:24 -07:00
Jesse Scott
c5b9e1d184
Update completion scripts for service subcommands 2020-09-22 12:07:11 -07:00
Belén
1e81c78a5b
Merge pull request #100 from puppetlabs/v1-release
Bump to version 1.0.0
2020-09-22 09:15:43 -07:00
d9b5bb5e89
Bump to version 1.0.0 2020-09-22 12:02:56 -04:00
bc1ea2e2d9
Merge pull request #90 from scotje/add_zsh_completions_new
Add tab completion script for zsh and fix bash completion for ABS services
2020-09-22 11:56:31 -04:00
Samuel Beaulieu
2b56448d50 Fix pretty print when multiple backend services
are returned by ABS. Added test with vmpooler and nspooler result
2020-09-22 09:53:13 -05:00
Samuel Beaulieu
45f0ef031e Fix spec tests for ABS pretty print
ABS now returns the ABS job_id on the first line, then every
vmpooler hostname indented. It queries them from vmpooler to
get the metadata like lifetime etc
2020-09-22 09:15:15 -05:00
013325b7a6
Merge pull request #99 from puppetlabs/fix-returned-abs-json
(maint) Fix for ABS PR#306 that includes json responses
2020-09-22 08:57:08 -04:00
Jesse Scott
8546c1c4b6
WIP: fixup specs after rebase 2020-09-21 16:59:04 -07:00
Jesse Scott
e269d71fea
Add README for zsh tab completion 2020-09-21 16:58:50 -07:00
Jesse Scott
dee735e017
(FIXUP) Collect hostnames in array before outputting 2020-09-21 16:55:09 -07:00
Jesse Scott
57e7542f73
Add tab completion script for zsh
This commit adds a new tab completion script for zsh. It also
fixes the completion script for bash to work with ABS backends.
2020-09-21 16:55:09 -07:00
Jesse Scott
b31f44fb40
Add --hostnameonly option to floaty list --active
Adds an option to the `floaty list` subcommand so that, when listing
active hosts, floaty will output just the hostnames, without any
additional information or formatting. Hostnames will be separated by a
newline.

This functionality is primarily intended for consuming by tooling (such
as the tab completion scripts).
2020-09-21 16:55:07 -07:00
Jesse Scott
40072e90e4
Fix print_to_stderr option for Utils.pretty_print_hosts
Previously this option had no effect on the output. This commit makes
the option effective and also refactors the tests for this method to
cover this case.
2020-09-21 16:54:17 -07:00
Samuel Beaulieu
cd7c0fae13 Adding spec tests for #list 2020-09-21 15:20:22 -05:00
Samuel Beaulieu
4df970b21f (maint) Fix for ABS PR#306 that includes json responses
Before this change ABS sometiimes returned a string of JSON with escaped
quotes, that had to be parsed again
With this change, floaty should accept both the legacy and the new
full JSON responses.
2020-09-21 14:46:00 -05:00
mattkirby
f3cd540455
Merge pull request #98 from puppetlabs/better-abs-config
(maint) Support any vmpooler for ABS via vmpooler_fallback
2020-09-17 10:08:05 -07:00
mattkirby
81c6e48528
Merge pull request #97 from puppetlabs/types-docs
(DIO-991) Add service command
2020-09-17 08:58:24 -07:00
mattkirby
e34964be00
Merge pull request #96 from puppetlabs/dio-911
( DIO-911) Include job_id in ABS --json output
2020-09-17 08:55:43 -07:00
9e61247cfe
Add service command
This change creates the `floaty service` command with two valid
arguemnts: types and examples

- `floaty service types` prints out a list of valid types for use in a
  service definition in ~/.vmfloaty.yml
- `floaty service examples` prints out example configuration files for
  both a single service and multiple services.
2020-09-16 12:55:42 -04:00
Samuel Beaulieu
5333158bdc (maint) Support any vmpooler for ABS via vmpooler_fallback
Before this change, the fallback vmpooler for ABS had to be named
'vmpooler' and it only supported one. With this new code, users can
set a key within an 'abs' service type called vmpooler_fallback that
points to any other service configured in the ~/.vmfloaty.yml config
file. If not set, the appropriate error message is returned, with
an example configuration.
Added the various use cases for the config to the unit tests
2020-09-16 11:25:49 -05:00
Samuel Beaulieu
4b7cbbf0e5 fix abs spec tests 2020-09-15 11:21:58 -05:00
mattkirby
512adb4af1
Merge pull request #94 from puppetlabs/fix-abs-vmpooler
ABS enables fallback to vmpooler for some scenarios
2020-09-11 13:27:02 -07:00
Samuel Beaulieu
c65b72d86b Document the ~/.vmfloaty content for ABS usage 2020-09-11 13:38:33 -05:00
Samuel Beaulieu
dbf6c54173 The main goal for this PR is to enable using all of the vmfloaty scenarios when
the service is set to ABS. Since ABS does not implement all the services, it
fallsback on vmpooler when needed (example increasing the lifetime value)

- Validating JSON can be parsed before parsing, as it used to throw uncaught errors
- self.list_active is returning hosts for both nspooler and vmpooler but was returning
job_ids for abs. Now standardized the returned values for use in the "modify" cli,
and created a separate list_active_job_ids for the cases where a job_id list is expected

- added a way to change the service in place for methods that do not make sense
for ABS, and instead fallback on using vmpooler in those cases:
1. summary
2. modify
3. snapshot
4. revert
5. disk
For those methods in the class itself, raising a NoMethodError, in case it is used directly

- query now returns the queue info. For information on VMs, users should use --service vmpooler
- pretty_print_hosts (used in list, and delete scenarios) will now print the job_id
ABS information and indent each VM within and print it's metadata. Useful for
knowing the running time and extending it.

- added a new utility method to get the config for the vmpooler service, used for the fallback
- added a passthrough for the vmpooler token to use when running ABS. This enables
vmpooler to track the VMs used by each token (user). Also aligns the list between
both ABS and vmpooler. Fixes the bit-bar issue where the VMs do not appear when created
via ABS
2020-09-11 13:38:24 -05:00
5a0640c515
Merge pull request #91 from nwolfe/maint/remove-warning
(maint) Remove warning about missing configuration file
2020-09-03 07:06:05 -04:00
Nate Wolfe
cb1ea8247b
WIP (DIO-911) Include job_id in ABS --json output
Prior to this commit, when using --service=abs and --json the job_id
value is not included in the JSON blob, which makes it difficult for
calling code to grab both the job_id and the hosts without text
processing the log messages printed to standard error.
2020-08-24 16:07:49 -07:00
Nate Wolfe
9a44cc480e
(maint) Add --user CLI option on delete and list subcommands
To support usage without a configuration file.
2020-08-24 12:11:06 -07:00
Nate Wolfe
8341a5f45d
(maint) Mention configuration file in CLI help text description
So users can be aware of the configuration file since it will no
longer be emitted as a warning during CLI invocation.
2020-08-21 15:45:10 -07:00
Nate Wolfe
04c73a970d
(maint) Remove warning about missing configuration file
Previously the CLI would emit a warning about missing configuration
file, but a configuration file does not appear to be a requirement, at
least based on the documentation and the fact that everything can be
specified directly on the command line.

This commit simply removes the warning.

Users will no longer get a warning when doing things like `floaty
--version`, `floaty help`, and any other subcommand.
2020-08-21 14:38:04 -07:00
mattkirby
b9bb08e3c0
Merge pull request #89 from puppetlabs/release_0111
Update version for 0.11.1 release
2020-08-20 14:07:45 -07:00
kirby@puppetlabs.com
3f10e987b4 Update version for 0.11.1 release 2020-08-20 14:06:08 -07:00
mattkirby
d3d6ebeb1a
Merge pull request #86 from McdonaldSeanp/json_output
Json output for delete/list + better ABS error handling
2020-08-20 14:02:53 -07:00
mattkirby
13fee7ef13
Merge pull request #87 from jarretlavallee/fix/master/nspooler
Fix the argument list for nonstandardpooler
2020-08-20 14:01:38 -07:00
mattkirby
5436f54258
Merge pull request #88 from cthorn42/maint/master/no_config_file_non_vmpooler_service_fix
(maint) Fix using ABS service without a .vmfloaty.yml file
2020-08-20 14:00:48 -07:00
Christopher Thorn
701534872d (maint) Fix using ABS service without a .vmfloaty.yml file
If you do not use a config file, and define everything on the command line,
previously the service always defaulted to vmpooler. Even if you requested ABS.
This PR fixes that, now we'll see if the config has no service defined and we
defined on the command line a service, we'll use that service.
2020-08-20 11:37:20 -07:00
Jarret Lavallee
e684933525 (maint) Fix the argument list for nonstandardpooler
Prior to this commit, 7 arguments would be sent into the `retrieve`
method in nonstandardpooler. There were only 6 arguments in the method
definition so an error would be thrown. This commit adds the `ondemand`
argument to the `retrieve` method, but does not utilize it.
2020-08-13 12:37:09 -06:00
Sean P. McDonald
1eaa80706c
(maint) Fail in ABS when queue requests don't return 200/202
When ABS returns an http status code other than 200 or 202, the ABS code
should fail
2020-08-12 16:14:02 -05:00
Sean P. McDonald
d22e2b4194
(new-feature) Add json option to list/delete command
This commit adds an option `--json` to the list and delete commands. When the
json flag is used the commands will print output as formatted JSON rather than
pretty printed strings.
2020-08-12 16:13:58 -05:00
b944760c93
Merge pull request #85 from puppetlabs/release_0110
Bump version for 0.11.0 release
2020-08-12 14:54:57 -04:00
kirby@puppetlabs.com
b44b9c6e98 Bump version for 0.11.0 release 2020-08-12 11:47:58 -07:00
mattkirby
3b91d6f582
Merge pull request #84 from austb/print-debug-to-stderr
Print all non-success output to STDERR
2020-08-12 11:34:11 -07:00
Austin Blatt
35faeab6be Move logger instance to class var in FloatyLogger
This moves the instance of the logger class to a class variable in the
`FloatyLogger` class and provides three class methods to log with in the
rest of the project `FloatyLogger.info`, `FloatyLogger.warn`, and
`FloatyLogger.error`.
2020-08-12 09:57:18 -07:00
barriserloth
8ec90007ca Use Logger for non-result output
This adds the Logger class for log output, all of which goes to STDERR,
and uses puts to send only the command result to STDOUT.
2020-08-11 12:41:22 -07:00
Austin Blatt
4755343df2 Print all non-success output to STDERR 2020-08-10 16:20:25 -07:00
mattkirby
d843066a56
Merge pull request #83 from puppetlabs/maint_update_travis
Update travis.yml
2020-08-06 12:22:59 -07:00
Belen Bustamante
309929f8d8 Update travis.yml 2020-08-06 11:50:43 -07:00
John O'Connor
13b6bc31f3
Merge pull request #82 from puppetlabs/version_010
Bump version to 0.10.0 for release
2020-08-05 11:42:39 +01:00
kirby@puppetlabs.com
a245316252 Bump version to 0.10.0 for release 2020-08-04 15:16:19 -07:00
mattkirby
d1fc70f96f
Merge pull request #67 from mattkirby/pooler_158
Add support for vmpooler on demand provisioning
2020-08-04 15:03:46 -07:00
kirby@puppetlabs.com
7b0a7679da Add Dockerfile to make it easier to test changes to vmfloaty by using Docker 2020-08-04 11:24:11 -07:00
kirby@puppetlabs.com
05a133fc72 Add support for ondemand provisioning to vmfloaty
This commit adds support for provisioning instances on demand with
vmpooler. Additionally, this change adds a capability to detect on
demand pools available in ABS. Without this change vmfloaty does not
support provisioning instances via the vmpooler ondemand endpoints.
2020-08-04 11:24:11 -07:00
482d4328d1
Merge pull request #73 from puppetlabs/dependabot/bundler/commander-gte-4.4.3-and-lt-4.6.0
Update commander requirement from ~> 4.4.3 to >= 4.4.3, < 4.6.0
2020-07-07 10:48:49 -04:00
b873e4a099
Merge pull request #78 from puppetlabs/dependabot/add-v2-config-file
Update Dependabot config file
2020-07-07 10:47:16 -04:00
dependabot-preview[bot]
980793c979
Update Dependabot config file 2020-07-07 14:43:17 +00:00
dependabot-preview[bot]
d0f7452998
Update commander requirement from ~> 4.4.3 to >= 4.4.3, < 4.6.0
Updates the requirements on [commander](https://github.com/commander-rb/commander) to permit the latest version.
- [Release notes](https://github.com/commander-rb/commander/releases)
- [Changelog](https://github.com/commander-rb/commander/blob/master/History.rdoc)
- [Commits](https://github.com/commander-rb/commander/compare/v4.4.3...v4.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-07 14:35:22 +00:00
f357607187
Merge pull request #75 from puppetlabs/dependabot/bundler/rspec-tw-3.9.0
Update rspec requirement from ~> 3.5.0 to ~> 3.9.0
2020-07-07 10:34:09 -04:00
dependabot-preview[bot]
458ddf192d
Update rspec requirement from ~> 3.5.0 to ~> 3.9.0
Updates the requirements on [rspec](https://github.com/rspec/rspec) to permit the latest version.
- [Release notes](https://github.com/rspec/rspec/releases)
- [Commits](https://github.com/rspec/rspec/compare/v3.5.0...v3.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-07 14:21:10 +00:00
2ff562cb40
Merge pull request #70 from puppetlabs/tools
Add Dependabot and Coveralls
2020-07-07 10:18:57 -04:00
a6f53c0310
Add Dependabot and Coveralls
This adds Dependabot to keep things updated and Coveralls so we can see
how code coverage changes over time. Coveralls / SimpleCov are
configured so that both the SimpleCov html report and the Coveralls
report are generated. This facilitates easily seeing coverage locally in
addtion to via CI.
2020-07-07 10:17:10 -04:00
498a9ac94f
Merge pull request #71 from puppetlabs/codeowners-fix
Fix formatting of CODEOWNERS
2020-07-07 10:14:21 -04:00
7a969d121e
Fix formatting of CODEOWNERS 2020-07-07 10:12:23 -04:00
Brandon High
2de284f2c0
Merge pull request #69 from puppetlabs/docs-update
Update docs
2020-07-02 11:13:00 -07:00
28fb9290d4
Update docs
This chane updates docs to reflect that ownership has moved to the DIO
team at Puppet. It also includes some formatting changes.
2020-07-02 12:52:32 -04:00
Brandon High
b7a210aa15
Merge pull request #68 from puppetlabs/fixup/edit-maintainers
Remove old maintainer note
2020-07-01 14:58:39 -07:00
Brian Cain
e942e7534d
Remove rubocop 2020-07-01 14:55:32 -07:00
Brian Cain
d4bd4f5163
Comment out rubocop rules that aren't helpful 2020-07-01 14:52:39 -07:00
Brian Cain
4ff9b9d0d5
Remove old maintainer note 2020-07-01 14:41:57 -07:00
Brandon High
c0b047eab8
Merge pull request #66 from briancain/highb-remove-gpr-push
Update gempush action to remove GPR publish
2020-02-05 15:54:21 -08:00
Brandon High
6697077adf
Update gempush action to remove GPR publish
We don't need to publish to GPR right now.
2020-02-05 15:50:53 -08:00
Brandon High
8588cd8fa1
Merge pull request #65 from briancain/highb-bump-092
Bump version.rb to 0.9.2 for release
2020-02-05 15:01:39 -08:00
Brandon High
707ced4b37
Merge branch 'master' into highb-bump-092 2020-02-05 14:55:12 -08:00
Brandon High
796555672d
Merge pull request #64 from briancain/highb-create-gempush
Create gempush.yml Github Action
2020-02-05 14:51:42 -08:00
Brandon High
1e38bb4244
Bump version.rb to 0.9.2 for release 2020-02-05 11:08:10 -08:00
Brandon High
331444751d
Create gempush.yml Github Action
I think this action should be able to build/push the gem whenever a matching is pushed.
2020-02-05 11:05:20 -08:00
Brandon High
8b4cc806a3
Merge pull request #62 from nicklewis/bump-faraday-for-ruby-2.7
Bump faraday dependency for Ruby 2.7 compatibility
2020-01-28 14:29:01 -08:00
Brandon High
7860bec0cd
Merge branch 'master' into bump-faraday-for-ruby-2.7 2020-01-28 14:27:09 -08:00
Brian Cain
05dd5bb6b2
Update PULL_REQUEST_TEMPLATE 2020-01-28 13:47:13 -08:00
Brian Cain
fffc16c412
Merge pull request #60 from highb/qeng-7604_add_jobid_to_delete
(QENG-7604) Add support for Job IDs to ABS delete
2020-01-28 13:42:23 -08:00
Brian Cain
5dbe19e10b
Merge branch 'master' into qeng-7604_add_jobid_to_delete 2020-01-28 13:40:53 -08:00
Nick Lewis
c417c3574c Bump faraday dependency for Ruby 2.7 compatibility
The only significant changes between 0.15.4 and 0.17.3 are silencing
some deprecation warnings on Ruby 2.7.
2020-01-28 13:05:33 -08:00
Brandon High
5fa9c12a85
Merge pull request #61 from mikkergimenez/fix_ssh_command_breaking
SSH Command respects ABS now and tests should fail if the API changes…
2020-01-27 17:05:17 -08:00
Mikker Gimenez-Peterson
ac14629eb3 SSH Command respects ABS now and tests should fail if the API changes again 2020-01-27 15:29:00 -08:00
Brandon High
51a7eb809e
(QENG-7604) Add support for Job IDs to ABS delete
This commit adds support for passing in a JobID when deleting with ABS.
2020-01-27 14:17:06 -08:00
Brian Cain
d6a69d08ac
Merge pull request #59 from highb/bump_091
Bump version.rb to 0.9.1
2020-01-14 10:47:54 -08:00
Brandon High
f1be1fec23
Bump version.rb to 0.9.1
For 0.9.1 release. Includes:
- Bug fix for delete action on vmpooler and nspooler #58
2020-01-14 10:03:34 -08:00
Brandon High
39770cbbfd
Merge pull request #58 from mikkergimenez/fix_method_signature
Fix error with delete command for vmpooler and nspooler
2020-01-14 10:02:33 -08:00
Mikker Gimenez-Peterson
dc3bfecd28 Adding spec test to ensure that all the interfaces are the same, while doing so, fix the broken interfaces for delete on vmpooler and nonstandard pooler(they were passed 5 by service.rb but expected 4) 2020-01-14 09:45:28 -08:00
Brian Cain
bc1198f81c
Merge pull request #56 from highb/bump_version_to_0.9.0
Minor version bump to 0.9.0
2019-12-17 09:47:16 -08:00
Brian Cain
dac2c2bae6
Merge branch 'master' into bump_version_to_0.9.0 2019-12-17 09:45:47 -08:00
Brandon High
e6bd4054cb
Merge pull request #57 from mikkergimenez/check_for_blank_lines_returned_from_abs_status_queue
ABS will sometimes return null values in the /status/queue endpoint
2019-12-16 16:17:40 -08:00
Mikker Gimenez-Peterson
2c456f1157 ABS will sometimes return null values in the /status/queue endpoint 2019-12-16 16:13:33 -08:00
Brandon High
6605a3eee6
Minor version bump to 0.9.0
I figure adding a new service like ABS would necessitate at least a
minor bump since it's more than a security/bug fix.
2019-12-05 10:08:07 -08:00
Brian Cain
7d0a72517b
Merge pull request #55 from highb/add_handling_for_failed_modify_request
Update pooler provider to throw an exception if the API returns non-OK
2019-12-05 08:02:06 -08:00
Brandon High
17c18679e2
Update pooler provider to throw an exception if the API returns non-OK
Prior to this commit the API could fail and return `ok: false` but
floaty wouldn't recognize that as a failure.
This commit updates the pooler code to check for `ok` and raise and
error with the body of what the api returns if it's non-truthy.
2019-12-04 16:44:42 -08:00
Brandon High
6954321c87
Merge pull request #53 from mikkergimenez/add_abs_vm_get
Add abs vm get
2019-12-04 16:43:26 -08:00
Brandon High
1e67715e2c
Fix rubocop issues 2019-12-04 16:40:57 -08:00
Brandon High
9a2cd816df
Update Rubocop to not use old cop name 2019-12-04 16:26:43 -08:00
Mikker Gimenez-Peterson
d963e357d3 Adding delete and get active requests 2019-12-04 11:37:17 -08:00
Mikker Gimenez-Peterson
7e27542670 Adding delete and get active requests 2019-11-04 11:41:49 -08:00
Mikker Gimenez-Peterson
a77ea84092 Rebasing fixed tests 2019-10-31 14:25:47 -07:00
Mikker Gimenez-Peterson
de7d0fdeab Adding command to list pools out of ABS 2019-10-31 11:33:07 -07:00
Brian Cain
d8dd0885ab
Merge pull request #54 from highb/update_faraday
Update Faraday to 0.15, remove unnecessary headers
2019-10-22 13:49:54 -07:00
Brandon High
c140e7af48
Update Faraday to 0.15, remove unnecessary headers 2019-10-22 13:28:14 -07:00
Brian Cain
aaeaa1acda
Update travis-ci ruby rvm version 2019-10-21 21:14:48 -07:00
Brian Cain
b2574325a0
Fixup rubocop again 2019-10-21 21:09:04 -07:00
Brian Cain
79422000a7
Fix rubocop 2019-10-21 21:04:47 -07:00
Britt Gresham
697cc878ef
Merge pull request #50 from steveax/change-urls-in-docs
change urls in docs to use example.net/.com
2019-04-09 17:00:04 -07:00
Steve Axthelm
42b5ba3669 change urls in docs to use example.net/.com
Prior to this commit, the docs and vmfloaty.yml.example file used
a variety of live domains (mycompany.net, alternate.net). This commit
changes those to example.net and example.com which are IANA-managed
Reserved Domains. This will reduce the chance that any credentials
could be harvested if a user executes the example commands without
changing the domains.
2019-04-09 16:50:31 -07:00
Brian Cain
d57b168153
Merge pull request #49 from rodjek/rubocop
Rubocop cleanup
2019-02-04 09:38:02 -08:00
Tim Sharpe
4440164f8a Run rubocop during CI 2019-02-03 15:59:29 +11:00
Tim Sharpe
893f9363e0 (rubocop) Defer Metrics cop changes for now 2019-02-03 15:50:07 +11:00
Tim Sharpe
6e1f626d7b (rubocop) Fix Style/IfUnlessModifier 2019-02-03 15:40:17 +11:00
Tim Sharpe
426e9ce96b (rubocop) Fix Style/ConditionalAssignment 2019-02-03 15:37:50 +11:00
Tim Sharpe
af6dc740e4 (rubocop) Fix Naming/UncommunicativeMethodParamName 2019-02-03 13:28:43 +11:00
Tim Sharpe
e50d4b3259 (rubocop) Fix Naming/HeredocDelimiterNaming 2019-02-03 13:27:25 +11:00
Tim Sharpe
e1379a8b9c (rubocop) Fix Naming/PredicateName 2019-02-03 13:25:33 +11:00
Tim Sharpe
66993b43fd (rubocop) Fix Gemspec/OrderedDependencies 2019-02-03 13:22:01 +11:00
Tim Sharpe
63eb49c747 (rubocop) Fix Lint/UnusedBlockArgument 2019-02-03 13:20:57 +11:00
Tim Sharpe
f0863e7fb0 (rubocop) Fix Lint/UnusedMethodArgument 2019-02-03 13:19:54 +11:00
Tim Sharpe
2a05f0d976 (rubocop) Fix Lint/ScriptPermission 2019-02-03 13:18:24 +11:00
Tim Sharpe
c97af3f7db (rubocop) Fix Performance/RegexpMatch 2019-02-03 13:15:53 +11:00
Tim Sharpe
c78ad33104 (rubocop) Fix Layout/LeadingCommentSpace 2019-02-03 13:12:33 +11:00
Tim Sharpe
7d9545f202 (rubocop) Fix Layout/IndentHeredoc 2019-02-03 13:11:07 +11:00
Tim Sharpe
851009b1f6 (rubocop) Fix Layout/AlignHash & Layout/IndentHash 2019-02-03 13:08:00 +11:00
Tim Sharpe
f2167f8be7 (rubocop) Fix Layout/CaseIndentation 2019-02-03 12:59:34 +11:00
Tim Sharpe
f2ab052fa4 (rubocop) Fix Layout/ExtraSpacing 2019-02-03 12:49:03 +11:00
Tim Sharpe
9afae18ee2 (rubocop) Fix Layout/SpaceAfterComma 2019-02-03 12:48:04 +11:00
Tim Sharpe
cecea8bc05 (rubocop) Fix Layout/SpaceAfterNot 2019-02-03 12:47:16 +11:00
Tim Sharpe
e8f420a08c (rubocop) Fix Layout/EmptyLineAfterGuardClause 2019-02-03 12:46:15 +11:00
Tim Sharpe
e6d1fbf954 (rubocop) Fix Layout/TrailingBlankLines 2019-02-03 12:44:11 +11:00
Tim Sharpe
bb9e821d5e (rubocop) Fix Layout/EmptyLinesAroundClassBody 2019-02-03 12:43:27 +11:00
Tim Sharpe
edaa3e5645 (rubocop) Fix Layout/EmptyLinesAroundBlockBody 2019-02-03 12:41:22 +11:00
Tim Sharpe
b2ac1ddf2f (rubocop) Fix Layout/MultilineMethodCallIndentation 2019-02-03 12:39:47 +11:00
Tim Sharpe
6f40397136 (rubocop) Fix Layout/DotPosition 2019-02-03 12:36:47 +11:00
Tim Sharpe
fd753ba188 (rubocop) Fix Layout/SpaceBeforeBlockBraces 2019-02-03 12:34:24 +11:00
Tim Sharpe
b8971c040a (rubocop) Fix Layout/SpaceInsideLiteralHashBraces 2019-02-03 12:32:05 +11:00
Tim Sharpe
eb0d31260f (rubocop) Fix Layout/SpaceAroundEqualsInParameterDefault 2019-02-03 12:30:26 +11:00
Tim Sharpe
7cd0256a97 (rubocop) Fix Layout/SpaceInsideBlockBraces 2019-02-03 12:28:17 +11:00
Tim Sharpe
b16e3fc792 (rubocop) Fix Layout/SpaceAroundOperators 2019-02-03 12:26:38 +11:00
Tim Sharpe
6a771a8d76 (rubocop) Fix Style/GuardClause 2019-02-03 12:22:41 +11:00
Tim Sharpe
b7b08c9c9e (rubocop) Fix Style/MissingRespondToMissing 2019-02-03 12:22:41 +11:00
Tim Sharpe
6c4fe8384c (rubocop) Fix Style/IfInsideElse 2019-02-03 12:22:41 +11:00
Tim Sharpe
dec621e9b8 (rubocop) Fix Style/ConditionalAssignment 2019-02-03 12:22:41 +11:00
Tim Sharpe
613121f34d (rubocop) Fix Style/BlockDelimiters 2019-02-03 12:22:41 +11:00
Tim Sharpe
692577a486 (rubocop) Fix Style/TrailingCommaInArguments 2019-02-03 12:22:41 +11:00
Tim Sharpe
0e5dd9b7db (rubocop) Fix Style/TrailingCommaInArrayLiteral 2019-02-03 12:22:41 +11:00
Tim Sharpe
58f64b2843 (rubocop) Fix Style/TrailingCommaInHashLiteral 2019-02-03 12:22:41 +11:00
Tim Sharpe
1aea79a9a1 (rubocop) Fix Style/SymbolArray 2019-02-03 12:22:41 +11:00
Tim Sharpe
095ac9e75e (rubocop) Fix Style/WordArray 2019-02-03 12:22:41 +11:00
Tim Sharpe
cdb9b0ca3d (rubocop) Fix Style/NestedParenthesizedCalls 2019-02-03 12:22:41 +11:00
Tim Sharpe
397bbd4dce (rubocop) Fix Style/RedundantFreeze 2019-02-03 12:22:41 +11:00
Tim Sharpe
d25732b950 (rubocop) Fix Style/NegatedIf 2019-02-03 12:22:41 +11:00
Tim Sharpe
5ad213075b (rubocop) Fix Style/StringLiteralsInInterpolation 2019-02-03 12:22:41 +11:00
Tim Sharpe
12c1795046 (rubocop) Fix Style/RescueStandardError 2019-02-03 12:22:41 +11:00
Tim Sharpe
7bafee35a7 (rubocop) Fix Style/IfUnlessModifier 2019-02-03 12:22:41 +11:00
Tim Sharpe
c7c8e48e2f (rubocop) Fix Style/ExpandPathArguments 2019-02-03 12:22:41 +11:00
Tim Sharpe
d95c6946b8 (rubocop) Fix Style/BracesAroundHashParameters 2019-02-03 12:22:41 +11:00
Tim Sharpe
79f764560d (rubocop) Fix Style/AndOr 2019-02-03 12:22:41 +11:00
Tim Sharpe
874a6e7cf6 (rubocop) Fix Style/ClassCheck 2019-02-03 12:22:41 +11:00
Tim Sharpe
fcf7154a8b (rubocop) Style/HashSyntax to use hash_rockets for consistency 2019-02-03 12:22:41 +11:00
Tim Sharpe
42014ae39f (rubocop) Fix Style/RedundantReturn 2019-02-03 12:22:41 +11:00
Tim Sharpe
0d95977db3 (rubocop) Disable Style/Documentation for now 2019-02-03 12:22:41 +11:00
Tim Sharpe
e0cbf89b8f (rubocop) Fix Style/FrozenStringLiteralComment 2019-02-03 12:22:41 +11:00
Tim Sharpe
02e49e5c4f (rubocop) Fix Style/ColonMethodCall 2019-02-03 10:46:35 +11:00
Tim Sharpe
1cf00a5a4c (rubocop) Fix Style/ZeroLengthPredicate 2019-02-03 10:44:25 +11:00
Tim Sharpe
1272343cdd (rubocop) Fix Style/StringLiterals 2019-02-03 10:42:28 +11:00
Brian Cain
cf2295ccfd Tag v0.8.2 2018-01-04 16:54:58 -08:00
Brian Cain
5837351dd0
Merge pull request #47 from nicklewis/json-output-for-get
🎂🎂🎂 Add --json option for `floaty get`
2018-01-04 16:53:14 -08:00
Nick Lewis
50eeb8f265 Add --json option for floaty get
This option will return structured output from `floaty get`, which is
easier to parse in some cases.

Example output:

```json
{
  "centos-7-x86_64": [
    "hpfhhf5aqxowfd8.delivery.puppetlabs.net",
    "k65euywltpz9fz0.delivery.puppetlabs.net"
  ],
  "centos-6-x86_64": [
    "oahunrurl7xis05.delivery.puppetlabs.net"
  ]
}
```
2018-01-02 10:23:54 -08:00
Brian Cain
941d8452d6 Update rubocop dep 2017-12-23 12:36:12 -08:00
Brian Cain
837fa94af5 Version 0.8.1 2017-10-24 08:59:28 -07:00
Brian Cain
6fc8e14f8f Update travis to ruby 2.4 2017-10-24 08:54:10 -07:00
Brian Cain
53eb14a7d1 Merge pull request #46 from highb/bump_commander_version
Bump commander version to clear up deprecation warnings
2017-10-24 08:52:22 -07:00
Brandon High
8550e1fa2f
Bump commander version
This commit bumps the commander version up to 4.4.3 in order to clear
up the deprecation warnings being emitted from 4.3.0:
```
> floaty get centos-7-x86_64
/Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333:
warning: constant ::NIL is deprecated
/Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333:
warning: constant ::TRUE is deprecated
/Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333:
warning: constant ::FALSE is deprecated
/Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333:
warning: constant ::Fixnum is deprecated
/Users/highb/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/commander-4.3.8/lib/commander/user_interaction.rb:333:
warning: constant ::Bignum is deprecated
- as9r7rigltr70zt.delivery.puppetlabs.net (centos-7-x86_64)
```
2017-10-18 10:51:43 -07:00
Brian Cain
6622a2ea17 Update example config 2017-10-13 16:19:39 -07:00
Brian Cain
24722279d0 Update LICENSE 2017-10-13 16:13:54 -07:00
Brian Cain
bc621f3601 Release v0.8.0 2017-10-13 16:10:15 -07:00
Brian Cain
44d573301a Merge pull request #45 from caseywilliams/nspooler-integration
Add configuration for multiple pooler services and integration with nspooler
2017-10-13 16:02:27 -07:00
Casey Williams
ca5b0f5e8b Integrate nonstandard pooler service into vmfloaty 2017-10-12 12:53:04 -07:00
Casey Williams
e78bcc6216 Allow configuration of multiple services 2017-09-25 15:23:10 -07:00
Brian Cain
e7fcb7c7d5 Update readme 2017-09-21 13:18:48 -07:00
Brian Cain
7fe2cdc42d Add issue template 2017-09-21 13:18:04 -07:00
Brian Cain
ed82c44af5 Update email 2017-08-17 13:49:03 -07:00
Brian Cain
b670596f57 Update to 0.7.9 2017-07-31 08:04:40 -07:00
Brian Cain
2cd2bd15dc Merge pull request #44 from scotje/add_bash_completion
Add basic bash completion script and framework for others
2017-07-31 08:03:54 -07:00
Jesse Scott
6d57a1b5df Add basic bash completion script and framework for others 2017-07-27 11:27:16 -07:00
Brian Cain
5fa65b6400 Merge branch 'master' of github.com:briancain/vmfloaty 2017-03-14 08:58:51 -07:00
Brian Cain
cfbad921ce (maint) Be clearer about which password to use 2017-03-14 08:58:28 -07:00
Brian Cain
0ebc134851 Merge pull request #43 from mckern/developersdevelopersdevelopers
Developersdevelopersdevelopers
2017-03-01 15:33:39 -08:00
Ryan McKern
d7e3bc9a02 Improve Travis platforms
Ruby 2.0 is dead, but 2.1 is not. Of note is that Ruby 2.1 *will* be
unsupported soon, but it's definitely not dead yet.
2017-03-01 15:17:09 -08:00
Ryan McKern
5c794cd2b0 Use the Classname::VERSION pattern
Instead of having a hardcoded version identifier in multiple
locations, we can leverage the Classname::VERSION pattern to have a
single canonical version number that everything can reference
programmatically.
2017-03-01 14:02:58 -08:00
Ryan McKern
0380b5fc9a Gemspec whitespace & tighter version constraints
Pessimistic versioning means that Faraday 0.11.0 will be installed if
the constraint is "~> 0.9", and that will break spec tests due to
newer restrictions in Faraday around how HTTP requests are handled by
rspec. We don't want to break tests.
2017-03-01 14:02:58 -08:00
Ryan McKern
21c42dbffa Clarify license in Gemspec
As per https://opensource.org/licenses/alphabetical, the name should
be Apache-2.0, not Apache.
2017-03-01 14:02:58 -08:00
Ryan McKern
ee0c73dfda Add a little formatting to Rspec 2017-03-01 14:02:58 -08:00
Ryan McKern
8babbe32ce Add Rubocop support to Rakefile 2017-03-01 14:02:58 -08:00
Ryan McKern
573f0d83a9 Update Gemspec
Formatting is slightly more idiomatic now.
2017-03-01 12:44:06 -08:00
Brian Cain
c8525bd0f1 Bump to 0.7.8 2016-12-20 08:42:09 -08:00
Brian Cain
313742ebfd Use actual hostname when creating snapshots in warn msg 2016-12-16 11:21:20 -08:00
Brian Cain
82afa94b6e Properly check for large pool size requests 2016-12-14 11:04:51 -08:00
Brian Cain
b5c6ce7a20 Update usage to match help text 2016-12-09 09:00:32 -08:00
Brian Cain
82a3589db8 Bump to version 0.7.6 2016-12-09 08:57:25 -08:00
Brian Cain
c9b718b379 (#40) Require a --force flag when users request large pools
Prior to this commit, a user could easily steam roll vmpooler by
accidentally adding an extra digit to their get request:

$ floaty get centos=100

Accidentially hitting enter on this would completely drain a centos
pool.

This commit updates that bevaior to force users to use the --force flag
if they really want to get more than 5 vms per template. 5 was choosen
because most vm pools at Puppet were in the 5-10 range.
2016-12-08 21:26:14 -08:00
Brian Cain
345300f58a (#41) Improve help text for vmfloaty
General clean up of the text around the --help flag for all vmfloaty
commands.
2016-12-08 21:15:01 -08:00
50 changed files with 4577 additions and 858 deletions

9
.dockerignore Normal file
View file

@ -0,0 +1,9 @@
**/*.yml
**/*.yaml
**/*.md
**/*example
**/Dockerfile*
coverage
examples
scripts
vendor

17
.github/PULL_REQUEST_TEMPLATE vendored Normal file
View file

@ -0,0 +1,17 @@
## Status
[Ready for Merge | In Progress | ???]
## Description
FIXME
## Related Issues
-
## Todos
- [ ] Tests
- [ ] Documentation

19
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,19 @@
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

12
.github/workflows/auto_release_prep.yml vendored Normal file
View file

@ -0,0 +1,12 @@
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

View file

@ -0,0 +1,8 @@
name: Dependabot auto-merge
on: pull_request
jobs:
dependabot_merge:
uses: puppetlabs/release-engineering-repo-standards/.github/workflows/dependabot_merge.yml@v1
secrets: inherit

8
.github/workflows/ensure_label.yml vendored Normal file
View file

@ -0,0 +1,8 @@
name: Ensure label
on: pull_request
jobs:
ensure_label:
uses: puppetlabs/release-engineering-repo-standards/.github/workflows/ensure_label.yml@v1
secrets: inherit

118
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,118 @@
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}}

39
.github/workflows/security.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: Security
on:
workflow_dispatch:
push:
branches:
- main
jobs:
scan:
name: Mend Scanning
runs-on: ubuntu-latest
steps:
- name: checkout repo content
uses: actions/checkout@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 }}

54
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,54 @@
# 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

View file

@ -0,0 +1,3 @@
project=vmfloaty
user=puppetlabs
exclude_labels=maintenance

4
.gitignore vendored
View file

@ -22,11 +22,13 @@ 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

View file

@ -1,5 +0,0 @@
sudo: false
language: ruby
rvm:
- 2.0.0-p247
script: rspec spec

340
CHANGELOG.md Normal file
View file

@ -0,0 +1,340 @@
# 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)*

3
CODEOWNERS Normal file
View file

@ -0,0 +1,3 @@
# Set the default code owners
* @puppetlabs/release-engineering

23
Dockerfile Normal file
View file

@ -0,0 +1,23 @@
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" ]

23
Gemfile
View file

@ -1,11 +1,18 @@
# frozen_string_literal: true
source 'https://rubygems.org'
gem 'commander'
gem 'faraday', '0.9.2'
gem 'colorize', '~> 0.8'
gem 'rspec'
gem 'webmock', '1.21.0'
gem 'rake'
gemspec
gem 'rake', require: false
group :test do
gem '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'
end

125
Gemfile.lock Normal file
View file

@ -0,0 +1,125 @@
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

190
LICENSE
View file

@ -1,6 +1,192 @@
vmfloaty
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Copyright (C) 2014-2016 Puppet
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

172
README.md
View file

@ -1,38 +1,76 @@
vmfloaty
========
# vmfloaty
[![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty) [![Build Status](https://travis-ci.org/briancain/vmfloaty.svg?branch=master)](https://travis-ci.org/briancain/vmfloaty)
[![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty)
[![Test](https://github.com/puppetlabs/vmfloaty/actions/workflows/test.yml/badge.svg)](https://github.com/puppetlabs/vmfloaty/actions/workflows/test.yml)
A CLI helper tool for [Puppet Labs vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat.
A CLI helper tool for [Puppet's VMPooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat.
<img src="http://i.imgur.com/xGcGwuH.jpg" width=200 height=200>
![float image](float.jpg)
- [vmfloaty](#vmfloaty)
- [Install](#install)
- [Ruby](#ruby)
- [Docker](#docker)
- [Usage](#usage)
- [Example workflow](#example-workflow)
- [vmfloaty dotfile](#vmfloaty-dotfile)
- [Basic configuration](#basic-configuration)
- [Using multiple services](#using-multiple-services)
- [Using backends besides VMPooler](#using-backends-besides-vmpooler)
- [Valid config keys](#valid-config-keys)
- [Tab Completion](#tab-completion)
- [VMPooler API](#vmpooler-api)
- [Using the Pooler class](#using-the-pooler-class)
- [Example Projects](#example-projects)
- [Contributing](#contributing)
- [Code Reviews](#code-reviews)
- [Releasing](#releasing)
- [Special thanks](#special-thanks)
## Install
### Ruby
Grab the latest from ruby gems...
```bash
gem install vmfloaty
```
$ gem install vmfloaty
...
...
$ floaty --help
```
### Docker
Run the docker image:
`docker run -it --rm -v ~/.vmfloaty.yml:/home/floatyuser/.vmfloaty.yml ghcr.io/puppetlabs/vmfloaty --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 flag
get Gets a vm or vms based on the os argument
help Display global or [command] help documentation
list Shows a list of available vms from the pooler
modify Modify a vms tags and TTL
list Shows a list of available vms from the pooler or vms obtained with a token
modify Modify a 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 vmpooler
summary Prints the summary of vmpooler
token Retrieves or deletes a token
status Prints the status of pools in the pooler service
summary Prints a summary of a pooler service
token Retrieves or deletes a token or checks token status
GLOBAL OPTIONS:
@ -50,55 +88,113 @@ $ floaty --help
Grabbing a token for authenticated pooler requests:
```
floaty token get --user username --url https://vmpooler.mycompany.net/api/v1
```bash
floaty token get --user username --url https://vmpooler.example.net/api/v1
```
This command will then ask you to log in. If successful, it will return a token that you can save either in a dotfile or use with other cli commands.
Grabbing vms:
```
floaty get centos-7-x86_64=2 debian-7-x86_64=1 windows-10=3 --token mytokenstring --url https://vmpooler.mycompany.net/api/v1
```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 continuely specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example:
If you do not wish to continually specify various config options with the cli, you can `~/.vmfloaty.yml` for some defaults. You can get a list of valid service types and example configuration files via `floaty service types` and `floaty service examples`, respectively.
#### Basic configuration
This is the simplest type of configuration where you only need a single service:
```yaml
#file at /Users/me/.vmfloaty.yml
url: 'https://vmpooler.mycompany.net/api/v1'
# file at ~/.vmfloaty.yml
url: 'https://vmpooler.example.net/api/v1'
user: 'brian'
token: 'tokenstring'
```
Now vmfloaty will use those config files if no flag was specified.
Run `floaty service examples` to see additional configuration options
#### Using multiple services
Most commands allow you to specify a `--service <servicename>` option to allow the use of multiple pooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services.
- If you run `floaty` without a `--service <name>` option, vmfloaty will use the first configured service by default.
- 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`.
#### Using backends besides VMPooler
vmfloaty supports additional backends besides VMPooler. To see a complete list, run `floaty service types`. The output of `floaty service examples` will show you how to configure each of the supported backends.
#### Valid config keys
Here are the keys that vmfloaty currently supports:
- verbose
+ Boolean
- token
+ String
- user
+ String
- url
+ String
- verbose (Boolean)
- token (String)
- user (String)
- url (String)
- services (String)
- type (String)
- vmpooler_fallback (String)
## vmpooler API
### Tab Completion
This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md).
There is a basic completion script for Bash (and possibly other shells) included with the gem in the [extras/completions](https://github.com/puppetlabs/vmfloaty/blob/master/extras/completions) folder. To activate, that file simply needs to be sourced somehow in your shell profile.
For convenience, the path to the completion script for the currently active version of the gem can be found with the `floaty completion` subcommand. This makes it easy to add the completion script to your profile like so:
```bash
source $(floaty completion --shell bash)
```
If you are running on macOS and use Homebrew's `bash-completion` formula, you can symlink the script to `/usr/local/etc/bash_completion.d/floaty` and it will be sourced automatically:
```bash
ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty
```
There is also tab completion for zsh:
```zsh
source $(floaty completion --shell zsh)
```
## VMPooler API
This cli tool uses the [VMPooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md).
## 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
- 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 <https://rubygems.org>, 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 <https://github.com/puppetlabs/vmfloaty/actions/workflows/release.yml> --> 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.

View file

@ -1,6 +1,9 @@
# frozen_string_literal: true
require 'rubygems'
require 'bundler/setup'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'
# Immediately sync all stdout so that tools like buildbot can
# immediately load in the output.
@ -8,7 +11,7 @@ $stdout.sync = true
$stderr.sync = true
# Change to the directory of this file.
Dir.chdir(File.expand_path("../", __FILE__))
Dir.chdir(File.expand_path(__dir__))
# This installs the tasks that help with gem creation and
# publishing.
@ -16,7 +19,13 @@ Bundler::GemHelper.install_tasks
# Install the `spec` task so that we can run tests.
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = "--order defined"
t.rspec_opts = '--order defined'
end
desc 'Run RuboCop'
RuboCop::RakeTask.new(:rubocop) do |task|
task.options << '--display-cop-names'
end
# Default task is to run the unit tests
task :default => :spec
task default: :spec

View file

@ -1,6 +1,7 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
require 'vmfloaty'

View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
_vmfloaty()
{
local cur prev commands template_arg_commands hostname_arg_commands service_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"
if [[ $cur == -* ]] ; then
# TODO: option completion
COMPREPLY=()
elif [[ $template_arg_commands =~ (^| )$prev($| ) ]] ; then
if [[ -z "$_vmfloaty_avail_templates" ]] ; then
# TODO: need a --hostnameonly equivalent here because the section headers of
# `floaty list` are adding some spurious entries (including files in current
# directory because part of the headers is `**` which is getting expanded)
_vmfloaty_avail_templates=$(floaty list 2>/dev/null)
fi
COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") )
elif [[ $hostname_arg_commands =~ (^| )$prev($| ) ]] ; then
_vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null)
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}") )
fi
}
complete -F _vmfloaty floaty

View file

@ -0,0 +1,43 @@
_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

BIN
float.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,406 +1,372 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'rubygems'
require 'commander'
require 'colorize'
require 'json'
require 'pp'
require 'uri'
require 'vmfloaty/auth'
require 'vmfloaty/pooler'
require 'vmfloaty/version'
require 'vmfloaty/conf'
require 'vmfloaty/utils'
require 'vmfloaty/service'
require 'vmfloaty/ssh'
require 'vmfloaty/logger'
class Vmfloaty
include Commander::Methods
def run
program :version, Version.get
program :description, 'A CLI helper tool for Puppet Labs vmpooler to help you stay afloat'
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."
config = Conf.read_config
command :get do |c|
c.syntax = 'floaty get os_type1=x ox_type2=y ...'
c.summary = 'Gets a vm or vms based on the os flag'
c.description = ''
c.syntax = 'floaty get os_type0 os_type1=x ox_type2=y [options]'
c.summary = 'Gets a vm or vms based on the os argument'
c.description = 'A command to retrieve vms from a pooler service. Can either be a single vm, or multiple with the `=` syntax.'
c.example 'Gets a few vms', 'floaty get centos=3 debian --user brian --url http://vmpooler.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--user STRING', String, 'User to authenticate with'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--token STRING', String, 'Token for pooler service'
c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))'
c.option '--notoken', 'Makes a request without a token'
c.option '--force', 'Forces vmfloaty to get requested vms'
c.option '--json', 'Prints retrieved vms in JSON format'
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']
token = options.token || config['token']
user = options.user ||= config['user']
url = options.url ||= config['url']
no_token = options.notoken
FloatyLogger.setlevel = options.loglevel if options.loglevel
service = Service.new(options, config)
use_token = !options.notoken
force = options.force
if args.empty?
STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs."
FloatyLogger.error '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)
unless os_types.empty?
if no_token
begin
response = Pooler.retrieve(verbose, os_types, nil, url)
rescue MissingParamError
STDERR.puts e
STDERR.puts "See `floaty get --help` for more information on how to get VMs."
rescue AuthError => e
STDERR.puts e
exit 1
end
puts Utils.format_hosts(response)
exit 0
else
unless token
puts "No token found. Retrieving a token..."
if !user
STDERR.puts "You did not provide a user to authenticate to vmpooler with"
exit 1
end
pass = password "Enter your password please:", '*'
begin
token = Auth.get_token(verbose, url, user, pass)
rescue TokenError => e
STDERR.puts e
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
puts "\nToken retrieved!"
puts token
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`'
exit 1
end
begin
response = Pooler.retrieve(verbose, os_types, token, url)
rescue MissingParamError
STDERR.puts e
STDERR.puts "See `floaty get --help` for more information on how to get VMs."
rescue AuthError => e
STDERR.puts e
exit 1
end
puts Utils.format_hosts(response)
exit 0
end
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
hosts = Utils.standardize_hostnames(response)
if options.json || options.ondemand
puts JSON.pretty_generate(hosts)
else
STDERR.puts "No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs."
exit 1
puts Utils.format_host_output(hosts)
end
end
end
command :list do |c|
c.syntax = 'floaty list [options]'
c.summary = 'Shows a list of available vms from the pooler'
c.description = ''
c.summary = 'Shows a list of available vms from the pooler or vms obtained with a token'
c.description = 'List will either show all vm templates available in pooler service, or with the --active flag it will list vms obtained with a pooler service token.'
c.example 'Filter the list on centos', 'floaty list centos --url http://vmpooler.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--active', 'Prints information about active vms for a given token'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--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]
url = options.url ||= config['url']
token = options.token || config['token']
active = options.active
if active
if options.active
# list active vms
begin
running_vms = Utils.get_all_token_vms(verbose, url, token)
rescue TokenError => e
STDERR.puts e
exit 1
rescue Exception => e
STDERR.puts e
exit 1
running_vms = if service.type == 'ABS'
# this is actually job_ids
service.list_active_job_ids(verbose, service.url, service.user)
else
service.list_active(verbose)
end
if ! running_vms.nil?
Utils.prettyprint_hosts(running_vms, verbose, url)
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
else
puts "Your VMs on #{host}:"
Utils.pretty_print_hosts(verbose, service, running_vms)
end
else
# list available vms from pooler
os_list = Pooler.list(verbose, url, filter)
os_list = service.list(verbose, filter)
puts os_list
end
end
end
command :query do |c|
c.syntax = 'floaty query [hostname] [options]'
c.syntax = 'floaty query hostname [options]'
c.summary = 'Get information about a given vm'
c.description = ''
c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm. If using ABS, you can query a job_id'
c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.action do |args, options|
verbose = options.verbose || config['verbose']
url = options.url ||= config['url']
service = Service.new(options, config)
hostname = args[0]
query_req = Pooler.query(verbose, url, hostname)
query_req = service.query(verbose, hostname)
pp query_req
end
end
command :modify do |c|
c.syntax = 'floaty modify [hostname] [options]'
c.summary = 'Modify a vms tags, TTL, and disk space'
c.description = ''
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.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.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--lifetime INT', Integer, 'VM TTL (Integer, in hours)'
c.option '--disk INT', Integer, 'Increases VM disk space (Integer, in gb)'
c.option '--tags STRING', String, 'free-form VM tagging (json)'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--token STRING', String, 'Token for pooler service'
c.option '--lifetime INT', Integer, 'VM TTL (Integer, in hours) [vmpooler only]'
c.option '--disk INT', Integer, 'Increases VM disk space (Integer, in gb) [vmpooler only]'
c.option '--tags STRING', String, 'free-form VM tagging (json) [vmpooler only]'
c.option '--reason STRING', String, 'VM reservation reason [nspooler only]'
c.option '--all', 'Modifies all vms acquired by a token'
c.action do |args, options|
verbose = options.verbose || config['verbose']
url = options.url ||= config['url']
service = Service.new(options, config)
hostname = args[0]
lifetime = options.lifetime
disk = options.disk
tags = JSON.parse(options.tags) if options.tags
token = options.token || config['token']
modify_all = options.all
running_vms = nil
if hostname.nil? && !modify_all
FloatyLogger.error 'ERROR: Provide a hostname or specify --all.'
exit 1
end
running_vms =
if modify_all
begin
running_vms = Utils.get_all_token_vms(verbose, url, token)
rescue Exception => e
STDERR.puts e
end
elsif hostname.include? ","
running_vms = hostname.split(",")
service.list_active(verbose)
else
hostname.split(',')
end
if lifetime || tags
# all vms
if !running_vms.nil?
begin
modify_hash = {}
modify_flag = true
tags = options.tags ? JSON.parse(options.tags) : nil
modify_hash = {
lifetime: options.lifetime,
disk: options.disk,
tags: tags,
reason: options.reason
}
modify_hash.delete_if { |_, value| value.nil? }
unless modify_hash.empty?
ok = true
modified_hash = {}
running_vms.each do |vm|
modify_hash[vm] = Pooler.modify(verbose, url, vm, token, lifetime, tags)
end
modify_hash.each do |hostname,status|
if status == false
STDERR.puts "Could not modify #{hostname}."
modify_flag = false
end
end
if modify_flag
puts "Successfully modified all vms. Use `floaty list --active` to see the results."
end
rescue Exception => e
STDERR.puts e
exit 1
modified_hash[vm] = service.modify(verbose, vm, modify_hash)
rescue ModifyError => e
FloatyLogger.error e
ok = false
end
if ok
if modify_all
puts "Successfully modified all #{running_vms.count} VMs."
else
# Single Vm
begin
modify_req = Pooler.modify(verbose, url, hostname, token, lifetime, tags)
rescue TokenError => e
STDERR.puts e
exit 1
end
if modify_req["ok"]
puts "Successfully modified vm #{hostname}."
else
STDERR.puts "Could not modify given host #{hostname} at #{url}."
puts modify_req
exit 1
end
end
end
if disk
# all vms
if !running_vms.nil?
begin
modify_hash = {}
modify_flag = true
running_vms.each do |vm|
modify_hash[vm] = Pooler.disk(verbose, url, vm, token, disk)
end
modify_hash.each do |hostname,status|
if status == false
STDERR.puts "Could not update disk space on #{hostname}."
modify_flag = false
end
end
if modify_flag
puts "Successfully made request to update disk space on all vms."
end
rescue Exception => e
STDERR.puts e
exit 1
end
else
# single vm
begin
disk_req = Pooler.disk(verbose, url, hostname, token, disk)
rescue TokenError => e
STDERR.puts e
exit 1
end
if disk_req["ok"]
puts "Successfully made request to update disk space of vm #{hostname}."
else
STDERR.puts "Could not modify given host #{hostname} at #{url}."
puts disk_req
exit 1
puts "Successfully modified VM #{hostname}."
end
puts 'Use `floaty list --active` to see the results.'
end
end
end
end
command :delete do |c|
c.syntax = 'floaty delete [hostname,...]'
c.syntax = 'floaty delete hostname,hostname2 [options]'
c.syntax += "\n floaty delete job1,job2 [options] (only supported with ABS)"
c.summary = 'Schedules the deletion of a host or hosts'
c.description = ''
c.description = 'Given a comma separated list of hostnames, or --all for all vms, vmfloaty makes a request to the pooler service to schedule the deletion of those vms. If you are using the ABS service, you can also pass in JobIDs here. Note that passing in a Job ID will delete *all* of the hosts in the job.' # rubocop:disable Layout/LineLength
c.example 'Schedules the deletion of a host or hosts', 'floaty delete myhost1,myhost2 --url http://vmpooler.example.com'
c.example 'Schedules the deletion of a JobID or JobIDs', 'floaty delete 1579300120799,1579300120800 --url http://abs.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--all', 'Deletes all vms acquired by a token'
c.option '-f', 'Does not prompt user when deleting all vms'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--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]
token = options.token || config['token']
url = options.url ||= config['url']
delete_all = options.all
force = options.f
failures = []
successes = []
if delete_all
# get vms with token
begin
running_vms = Utils.get_all_token_vms(verbose, url, token)
rescue TokenError => e
STDERR.puts e
exit 1
rescue Exception => e
STDERR.puts e
exit 1
end
if ! running_vms.nil?
Utils.prettyprint_hosts(running_vms, verbose, url)
# query y/n
puts
if force
ans = true
running_vms = if service.type == 'ABS'
# this is actually job_ids
service.list_active_job_ids(verbose, service.url, service.user)
else
ans = agree("Delete all VMs associated with token #{token}? [y/N]")
service.list_active(verbose)
end
if ans
# delete vms
puts "Scheduling all vms for for deletion"
response = Pooler.delete(verbose, url, running_vms, token)
response.each do |host,vals|
if vals['ok'] == false
STDERR.puts "There was a problem with your request for vm #{host}."
STDERR.puts vals
end
end
end
end
exit 0
end
if hostnames.nil?
STDERR.puts "You did not provide any hosts to delete"
exit 1
if running_vms.empty?
if options.json
puts {}.to_json
else
hosts = hostnames.split(',')
begin
Pooler.delete(verbose, url, hosts, token)
rescue TokenError => e
STDERR.puts e
FloatyLogger.info 'You have no running VMs.'
end
else
confirmed = true
unless force
Utils.pretty_print_hosts(verbose, service, running_vms, true)
# Confirm deletion
confirmed = agree('Delete all these VMs? [y/N]')
end
if confirmed
response = service.delete(verbose, running_vms)
response.each do |hostname, result|
if result['ok']
successes << hostname
else
failures << hostname
end
end
end
end
elsif hostnames || args
hostnames = hostnames.split(',')
results = service.delete(verbose, hostnames)
results.each do |hostname, result|
if result['ok']
successes << hostname
else
failures << hostname
end
end
else
FloatyLogger.info 'You did not provide any hosts to delete'
exit 1
end
puts "Schedulered vmpooler to delete vms #{hosts}."
exit 0
unless failures.empty?
FloatyLogger.info 'Unable to delete the following VMs:'
failures.each do |hostname|
FloatyLogger.info "- #{hostname}"
end
FloatyLogger.info '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
end
end
exit 1 unless failures.empty?
end
end
command :snapshot do |c|
c.syntax = 'floaty snapshot [hostname] [options]'
c.syntax = 'floaty snapshot hostname [options]'
c.summary = 'Takes a snapshot of a given vm'
c.description = ''
c.example 'Takes a snapshot for a given host', 'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
c.description = 'Will request a snapshot be taken of the given hostname in the pooler service. This command is known to take a while depending on how much load is on the pooler service.'
c.example 'Takes a snapshot for a given host',
'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--token STRING', String, 'Token for pooler service'
c.action do |args, options|
verbose = options.verbose || config['verbose']
url = options.url ||= config['url']
service = Service.new(options, config)
hostname = args[0]
token = options.token ||= config['token']
begin
snapshot_req = Pooler.snapshot(verbose, url, hostname, token)
rescue TokenError => e
STDERR.puts e
snapshot_req = service.snapshot(verbose, hostname)
rescue TokenError, ModifyError => e
FloatyLogger.error e
exit 1
end
puts "Snapshot pending. Use `floaty query host` to determine when snapshot is valid."
puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid."
pp snapshot_req
end
end
command :revert do |c|
c.syntax = 'floaty revert [hostname] [snapshot] [options]'
c.syntax = 'floaty revert hostname snapshot [options]'
c.summary = 'Reverts a vm to a specified snapshot'
c.description = ''
c.example 'Reverts to a snapshot for a given host', 'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
c.description = 'Given a snapshot SHA, vmfloaty will request a revert to the pooler service to go back to a previous snapshot.'
c.example 'Reverts to a snapshot for a given host',
'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--token STRING', String, 'Token for pooler service'
c.option '--snapshot STRING', String, 'SHA of snapshot'
c.action do |args, options|
verbose = options.verbose || config['verbose']
url = options.url ||= config['url']
service = Service.new(options, config)
hostname = args[0]
token = options.token || config['token']
snapshot_sha = args[1] || options.snapshot
if args[1] && options.snapshot
STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}"
FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}"
end
begin
revert_req = Pooler.revert(verbose, url, hostname, token, snapshot_sha)
rescue TokenError => e
STDERR.puts e
revert_req = service.revert(verbose, hostname, snapshot_sha)
rescue TokenError, ModifyError => e
FloatyLogger.error e
exit 1
end
@ -410,145 +376,206 @@ class Vmfloaty
command :status do |c|
c.syntax = 'floaty status [options]'
c.summary = 'Prints the status of vmpooler'
c.description = ''
c.example 'Gets the current vmpooler status', 'floaty status --url http://vmpooler.example.com'
c.summary = 'Prints the status of pools in the pooler service'
c.description = 'Makes a request to the pooler service to request the information about vm pools and how many are ready to be used, what pools are empty, etc.'
c.example 'Gets the current pooler service status', 'floaty status --url http://vmpooler.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--json', 'Prints status in JSON format'
c.action do |args, options|
c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
c.action do |_, options|
verbose = options.verbose || config['verbose']
url = options.url ||= config['url']
status = Pooler.status(verbose, url)
message = status['status']['message']
pools = status['pools']
FloatyLogger.setlevel = options.loglevel if options.loglevel
service = Service.new(options, config)
if options.json
pp status
pp service.status(verbose)
else
Utils.prettyprint_status(status, message, pools, verbose)
Utils.pretty_print_status(verbose, service)
end
exit status['status']['ok']
end
end
command :summary do |c|
c.syntax = 'floaty summary [options]'
c.summary = 'Prints the summary of vmpooler'
c.description = ''
c.example 'Gets the current day summary of vmpooler', 'floaty summary --url http://vmpooler.example.com'
c.summary = 'Prints a summary of a pooler service'
c.description = 'Gives a very detailed summary of information related to the pooler service.'
c.example 'Gets the current day summary of the pooler service', 'floaty summary --url http://vmpooler.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.action do |args, options|
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.action do |_, options|
verbose = options.verbose || config['verbose']
url = options.url ||= config['url']
service = Service.new(options, config)
summary = Pooler.summary(verbose, url)
summary = service.summary(verbose)
pp summary
exit 0
end
end
command :token do |c|
c.syntax = 'floaty token [get | delete | status] [token]'
c.summary = 'Retrieves or deletes a token'
c.description = ''
c.syntax = 'floaty token <get delete status> [options]'
c.summary = 'Retrieves or deletes a token or checks token status'
c.description = 'This command is used to manage your pooler service token. Through the various options, you are able to get a new token, delete an existing token, and request a tokens status.'
c.example 'Gets a token from the pooler', 'floaty token get'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--user STRING', String, 'User to authenticate with'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--token STRING', String, 'Token for pooler service'
c.action do |args, options|
verbose = options.verbose || config['verbose']
service = Service.new(options, config)
action = args.first
url = options.url ||= config['url']
token = args[1] ||= options.token ||= config['token']
user = options.user ||= config['user']
begin
case action
when "get"
pass = password "Enter your password please:", '*'
begin
token = Auth.get_token(verbose, url, user, pass)
rescue TokenError => e
STDERR.puts e
exit 1
end
when 'get'
token = service.get_new_token(verbose)
puts token
exit 0
when "delete"
pass = password "Enter your password please:", '*'
begin
result = Auth.delete_token(verbose, url, user, pass, token)
rescue TokenError => e
STDERR.puts e
exit 1
end
when 'delete'
result = service.delete_token(verbose, options.token)
puts result
exit 0
when "status"
begin
status = Auth.token_status(verbose, url, token)
rescue TokenError => e
STDERR.puts e
when 'status'
token_value = options.token
token_value = args[1] if token_value.nil?
status = service.token_status(verbose, token_value)
puts status
when nil
FloatyLogger.error 'No action provided'
exit 1
else
FloatyLogger.error "Unknown action: #{action}"
exit 1
end
puts status
exit 0
when nil
STDERR.puts "No action provided"
else
STDERR.puts "Unknown action: #{action}"
rescue TokenError => e
FloatyLogger.error e
exit 1
end
exit 0
end
end
command :ssh do |c|
c.syntax = 'floaty ssh os_type'
c.syntax = 'floaty ssh os_type [options]'
c.summary = 'Grabs a single vm and sshs into it'
c.description = ''
c.description = 'This command simply will grab a vm template that was requested, and then ssh the user into the machine all at once.'
c.example 'SSHs into a centos vm', 'floaty ssh centos7 --url https://vmpooler.example.com'
c.option '--verbose', 'Enables verbose output'
c.option '--url STRING', String, 'URL of vmpooler'
c.option '--service STRING', String, 'Configured pooler service name'
c.option '--url STRING', String, 'URL of pooler service'
c.option '--user STRING', String, 'User to authenticate with'
c.option '--token STRING', String, 'Token for vmpooler'
c.option '--token STRING', String, 'Token for pooler service'
c.option '--notoken', 'Makes a request without a token'
c.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']
url = options.url ||= config['url']
token = options.token ||= config['token']
user = options.user ||= config['user']
no_token = options.notoken
service = Service.new(options, config)
use_token = !options.notoken
if args.empty?
STDERR.puts "No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs."
FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
exit 1
end
host_os = args.first
if !no_token && !token
puts "No token found. Retrieving a token..."
if !user
STDERR.puts "You did not provide a user to authenticate to vmpooler with"
exit 1
end
pass = password "Enter your password please:", '*'
begin
token = Auth.get_token(verbose, url, user, pass)
rescue TokenError => e
STDERR.puts e
STDERR.puts 'Could not get token...requesting vm without a token anyway...'
else
puts "\nToken retrieved!"
puts token
FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
service.ssh(verbose, host_os, use_token, options.ondemand)
exit 0
end
end
Ssh.ssh(verbose, host_os, token, url)
command :completion do |c|
c.syntax = 'floaty completion [options]'
c.summary = 'Outputs path to completion script'
c.description = Utils.strip_heredoc(<<-DESCRIPTION)
Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile:
source $(floaty completion --shell bash)
This subcommand will exit non-zero with an error message if no completion script is available for the requested shell.
DESCRIPTION
c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash'
c.option '--shell STRING', String, 'Shell to request completion script for'
c.action do |_, options|
shell = (options.shell || 'bash').downcase.strip
completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__)
if File.exist?(completion_file)
puts completion_file
exit 0
else
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 <types examples>'
c.summary = 'Display information about floaty services and their configuration'
c.description = 'Display information about floaty services to aid in setting up a configuration file.'
c.example 'Print a list of the valid service types', 'floaty service types'
c.example 'Print a sample config file with multiple services', 'floaty service examples'
c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod'
c.action do |args, _options|
action = args.first
example_config = Utils.strip_heredoc(<<-CONFIG)
# Sample ~/.vmfloaty.yml with just vmpooler
user: 'jdoe'
url: 'https://vmpooler.example.net'
token: '456def789'
# Sample ~/.vmfloaty.yml with multiple services
# Note: when the --service is not specified on the command line,
# the first service listed here is selected automatically
user: 'jdoe'
services:
abs-prod:
type: 'abs'
url: 'https://abs.example.net/api/v2'
token: '123abc456'
vmpooler_fallback: 'vmpooler-prod'
nspooler-prod:
type: 'nspooler'
url: 'https://nspooler.example.net'
token: '789ghi012'
vmpooler-dev:
type: 'vmpooler'
url: 'https://vmpooler-dev.example.net'
token: '987dsa654'
vmpooler-prod:
type: 'vmpooler'
url: 'https://vmpooler.example.net'
token: '456def789'
CONFIG
types_output = Utils.strip_heredoc(<<-TYPES)
The values on the left below can be used in ~/.vmfloaty.yml as the value of type:
abs: Puppet's Always Be Scheduling
nspooler: Puppet's Non-standard Pooler, aka NSPooler
vmpooler: Puppet's VMPooler
TYPES
case action
when 'examples'
FloatyLogger.info example_config
when 'types'
FloatyLogger.info types_output
when nil
FloatyLogger.error 'No action provided'
exit 1
else
FloatyLogger.error "Unknown action: #{action}"
exit 1
end
end
end

422
lib/vmfloaty/abs.rb Normal file
View file

@ -0,0 +1,422 @@
# frozen_string_literal: true
require 'vmfloaty/errors'
require 'vmfloaty/http'
require 'vmfloaty/utils'
require 'faraday'
require 'json'
class ABS
# List active VMs in ABS
# This is what a job request looks like:
# {
# "state":"filled",
# "last_processed":"2019-10-31 20:59:33 +0000",
# "allocated_resources": [
# {
# "hostname":"h3oyntawjm7xdch.delivery.puppetlabs.net",
# "type":"centos-7.2-tmpfs-x86_64",
# "engine":"vmpooler"}
# ],
# "audit_log":{
# "2019-10-30 20:33:12 +0000":"Allocated h3oyntawjm7xdch.delivery.puppetlabs.net for job 1572467589"
# },
# "request":{
# "resources":{
# "centos-7.2-tmpfs-x86_64":1
# },
# "job": {
# "id":1572467589,
# "tags": {
# "user":"mikker",
# "url_string":"floaty://mikker/1572467589"
# },
# "user":"mikker",
# "time-received":1572467589
# }
# }
# }
#
@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')
req_hash['allocated_resources'].each do |onehost|
hosts.push(onehost['hostname'])
end
end
hosts
end
def self.get_active_requests(verbose, url, user)
conn = Http.get_conn(verbose, supported_abs_url(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
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
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: "
end
end
ret_val
end
def self.all_job_resources_accounted_for(allocated_resources, hosts)
allocated_host_list = allocated_resources.map { |ar| ar['hostname'] }
(allocated_host_list - hosts).empty?
end
def self.delete(verbose, url, hosts, token, user)
# In ABS terms, this is a "returned" host.
conn = Http.get_conn(verbose, supported_abs_url(url))
conn.headers['X-AUTH-TOKEN'] = token if token
FloatyLogger.info "Trying to delete hosts #{hosts}" if verbose
requests = get_active_requests(verbose, url, user)
jobs_to_delete = []
ret_status = {}
hosts.each do |host|
ret_status[host] = {
'ok' => false
}
end
requests.each do |req_hash|
next unless req_hash['state'] == 'allocated' || req_hash['state'] == 'filled'
if hosts.include? req_hash['request']['job']['id']
jobs_to_delete.push(req_hash)
next
end
req_hash['allocated_resources'].each do |vm_name, _i|
if hosts.include? vm_name['hostname']
if all_job_resources_accounted_for(req_hash['allocated_resources'], hosts)
ret_status[vm_name['hostname']] = {
'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']}"
end
end
end
end
response_body = {}
jobs_to_delete.each do |job|
req_obj = {
'job_id' => job['request']['job']['id'],
'hosts' => job['allocated_resources']
}
FloatyLogger.info "Deleting #{req_obj}" if verbose
return_result = conn.post 'return', req_obj.to_json
req_obj['hosts'].each do |host|
response_body[host['hostname']] = { 'ok' => true } if return_result.body == 'OK'
end
end
response_body
end
# List available VMs in ABS
def self.list(verbose, url, os_filter = nil)
conn = Http.get_conn(verbose, supported_abs_url(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 = 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 = 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
os_list.delete 'ok'
os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list
end
# Retrieve an OS from ABS.
def self.retrieve(verbose, os_types, token, url, user, config, _ondemand = nil, continue = nil)
#
# Contents of post must be like:
#
# {
# "resources": {
# "centos-7-i386": 1,
# "ubuntu-1404-x86_64": 2
# },
# "job": {
# "id": "12345",
# "tags": {
# "user": "username",
# }
# }
# }
conn = Http.get_conn(verbose, supported_abs_url(url))
conn.headers['X-AUTH-TOKEN'] = token if token
saved_job_id = if continue.nil?
"#{user}-#{DateTime.now.strftime('%Q')}"
else
continue
end
req_obj = {
resources: os_types,
job: {
id: saved_job_id,
tags: {
user: user
}
}
}
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'
1
when 'medium'
2
when 'low'
3
else
config['priority'].to_i
end
end
FloatyLogger.info "Posting to ABS #{req_obj.to_json}" if verbose
# os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
# raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
FloatyLogger.info "Requesting VMs with job_id: #{saved_job_id} Will retry for up to an hour."
res = conn.post 'request', req_obj.to_json
retries = 360
status = validate_queue_status_response(res.status, res.body, 'Initial request', verbose)
begin
(1..retries).each do |i|
res_body = check_queue(conn, saved_job_id, req_obj, verbose)
return translated(res_body, saved_job_id) if res_body.is_a?(Array) # when we get a response with hostnames
sleep_seconds = 10 if i >= 10
sleep_seconds = i if i < 10
FloatyLogger.info "Waiting #{sleep_seconds}s (x#{i}) #{res_body.strip}"
sleep(sleep_seconds)
end
rescue SystemExit, Interrupt
FloatyLogger.info "\n\nFloaty interrupted, you can resume polling with\n1) `floaty get [same arguments] and adding the flag --continue #{saved_job_id}` or query the state of the queue via\n2) `floaty query #{saved_job_id}` or delete it via\n3) `floaty delete #{saved_job_id}`"
exit 1
end
nil
end
#
# 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 }
res_body.each do |host|
if vmpooler_formatted_body[host['type']] && vmpooler_formatted_body[host['type']]['hostname'].instance_of?(Array)
vmpooler_formatted_body[host['type']]['hostname'] << host['hostname']
else
vmpooler_formatted_body[host['type']] = { 'hostname' => [host['hostname']] }
end
end
vmpooler_formatted_body['ok'] = true
vmpooler_formatted_body
end
def self.check_queue(conn, _job_id, req_obj, verbose)
res = conn.post 'request', req_obj.to_json
status = validate_queue_status_response(res.status, res.body, 'Check queue request', verbose)
unless res.body.empty? || !valid_json?(res.body)
res_body = JSON.parse(res.body)
return res_body
end
res.body
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)"
end
def self.status(verbose, url)
conn = Http.get_conn(verbose, supported_abs_url(url))
res = conn.get 'status'
res.body == 'OK'
end
def self.summary(_verbose, _url)
raise NoMethodError, 'summary is not defined for ABS'
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?
# 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
end
def self.modify(_verbose, _url, _hostname, _token, _modify_hash)
raise NoMethodError, 'modify is not defined for ABS'
end
def self.disk(_verbose, _url, _hostname, _token, _disk)
raise NoMethodError, 'disk is not defined for ABS'
end
def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha)
raise NoMethodError, 'revert is not defined for ABS'
end
# 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

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'faraday'
require 'json'
require 'vmfloaty/http'
@ -7,46 +9,36 @@ class Auth
def self.get_token(verbose, url, user, password)
conn = Http.get_conn_with_auth(verbose, url, user, password)
resp = conn.post "token"
resp = conn.post 'token'
res_body = JSON.parse(resp.body)
if res_body["ok"]
return res_body["token"]
else
return res_body['token'] if res_body['ok']
raise TokenError, "HTTP #{resp.status}: There was a problem requesting a token:\n#{res_body}"
end
end
def self.delete_token(verbose, url, user, password, token)
if token.nil?
raise TokenError, 'You did not provide a token'
end
raise TokenError, 'You did not provide a token' if token.nil?
conn = Http.get_conn_with_auth(verbose, url, user, password)
response = conn.delete "token/#{token}"
res_body = JSON.parse(response.body)
if res_body["ok"]
return res_body
else
return res_body if res_body['ok']
raise TokenError, "HTTP #{response.status}: There was a problem deleting a token:\n#{res_body}"
end
end
def self.token_status(verbose, url, token)
if token.nil?
raise TokenError, 'You did not provide a token'
end
raise TokenError, 'You did not provide a token' if token.nil?
conn = Http.get_conn(verbose, url)
response = conn.get "token/#{token}"
res_body = JSON.parse(response.body)
if res_body["ok"]
return res_body
else
return res_body if res_body['ok']
raise TokenError, "HTTP #{response.status}: There was a problem getting the status of a token:\n#{res_body}"
end
end
end

View file

@ -1,13 +1,14 @@
# frozen_string_literal: true
require 'yaml'
class Conf
def self.read_config
conf = {}
begin
conf = YAML.load_file("#{Dir.home}/.vmfloaty.yml")
rescue
STDERR.puts "WARNING: There was no config file at #{Dir.home}/.vmfloaty.yml"
rescue StandardError
# ignore
end
conf
end

View file

@ -1,17 +1,25 @@
# frozen_string_literal: true
class AuthError < StandardError
def initialize(msg="Could not authenticate to pooler")
def initialize(msg = 'Could not authenticate to pooler')
super
end
end
class TokenError < StandardError
def initialize(msg="Could not do operation with token provided")
def initialize(msg = 'Could not do operation with token provided')
super
end
end
class MissingParamError < StandardError
def initialize(msg="Argument provided to function is missing")
def initialize(msg = 'Argument provided to function is missing')
super
end
end
class ModifyError < StandardError
def initialize(msg = 'Could not modify VM')
super
end
end

View file

@ -1,60 +1,45 @@
# frozen_string_literal: true
require 'faraday'
require 'uri'
class Http
def self.is_url(url)
def self.url?(url)
# This method exists because it seems like Farady
# has no handling around if a user gives us a URI
# with no protocol on the beginning of the URL
uri = URI.parse(url)
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS)
return true
end
return true if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
return false
false
end
def self.get_conn(verbose, url)
if url.nil?
raise "Did not provide a url to connect to"
end
raise 'Did not provide a url to connect to' if url.nil?
unless is_url(url)
url = "https://#{url}"
end
url = "https://#{url}" unless url?(url)
conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday|
Faraday.new(url: url, ssl: { verify: false }) do |faraday|
faraday.request :url_encoded
faraday.response :logger if verbose
faraday.adapter Faraday.default_adapter
end
return conn
end
def self.get_conn_with_auth(verbose, url, user, password)
if url.nil?
raise "Did not provide a url to connect to"
end
raise 'Did not provide a url to connect to' if url.nil?
if user.nil?
raise "You did not provide a user to authenticate with"
end
raise 'You did not provide a user to authenticate with' if user.nil?
unless is_url(url)
url = "https://#{url}"
end
url = "https://#{url}" unless url?(url)
conn = Faraday.new(:url => url, :ssl => {:verify => false}) do |faraday|
Faraday.new(url: url, ssl: { verify: false }) do |faraday|
faraday.request :url_encoded
faraday.request :basic_auth, user, password
faraday.response :logger if verbose
faraday.adapter Faraday.default_adapter
end
return conn
end
end

43
lib/vmfloaty/logger.rb Normal file
View file

@ -0,0 +1,43 @@
# 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

View file

@ -0,0 +1,120 @@
# frozen_string_literal: true
require 'vmfloaty/errors'
require 'vmfloaty/http'
require 'faraday'
require 'json'
class NonstandardPooler
def self.list(verbose, url, os_filter = nil)
conn = Http.get_conn(verbose, url)
response = conn.get 'status'
response_body = JSON.parse(response.body)
os_list = response_body.keys.sort
os_list.delete 'ok'
os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list
end
def self.list_active(verbose, url, token, _user)
status = Auth.token_status(verbose, url, token)
status['reserved_hosts'] || []
end
def self.retrieve(verbose, os_type, token, url, _user, _options, _ondemand = nil, _continue = nil)
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
response = conn.post "host/#{os_string}"
res_body = JSON.parse(response.body)
if res_body['ok']
res_body
elsif response.status == 401
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
else
raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/host/#{os_string}. #{res_body}"
end
end
def self.modify(verbose, url, hostname, token, modify_hash)
raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' if token.nil?
modify_hash.each do |key, _value|
raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason
reserved_for_reason].include? key
end
if modify_hash[:reason]
# "reason" is easier to type than "reserved_for_reason", but nspooler needs the latter
modify_hash[:reserved_for_reason] = modify_hash.delete :reason
end
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token
response = conn.put do |req|
req.url "host/#{hostname}"
req.body = modify_hash.to_json
end
response.body.empty? ? {} : JSON.parse(response.body)
end
def self.disk(_verbose, _url, _hostname, _token, _disk)
raise ModifyError, 'Configured service type does not support modification of disk space'
end
def self.snapshot(_verbose, _url, _hostname, _token)
raise ModifyError, 'Configured service type does not support snapshots'
end
def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha)
raise ModifyError, 'Configured service type does not support snapshots'
end
def self.delete(verbose, url, hosts, token, _user)
raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil?
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
response_body = {}
hosts = hosts.split(',') unless hosts.is_a? Array
hosts.each do |host|
response = conn.delete "host/#{host}"
res_body = JSON.parse(response.body)
response_body[host] = res_body
end
response_body
end
def self.status(verbose, url)
conn = Http.get_conn(verbose, url)
response = conn.get '/status'
JSON.parse(response.body)
end
def self.summary(verbose, url)
conn = Http.get_conn(verbose, url)
response = conn.get '/summary'
JSON.parse(response.body)
end
def self.query(verbose, url, hostname)
conn = Http.get_conn(verbose, url)
response = conn.get "host/#{hostname}"
JSON.parse(response.body)
end
end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'faraday'
require 'vmfloaty/http'
require 'json'
@ -11,98 +13,124 @@ class Pooler
response_body = JSON.parse(response.body)
if os_filter
hosts = response_body.select { |i| i[/#{os_filter}/] }
response_body.select { |i| i[/#{os_filter}/] }
else
hosts = response_body
response_body
end
end
hosts
def self.list_active(verbose, url, token, _user)
status = Auth.token_status(verbose, url, token)
vms = []
vms = status[token]['vms']['running'] if status[token] && status[token]['vms']
vms
end
def self.retrieve(verbose, os_type, token, url)
def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil, _continue = nil)
# NOTE:
# Developers can use `Utils.generate_os_hash` to
# generate the os_type param.
conn = Http.get_conn(verbose, url)
if token
conn.headers['X-AUTH-TOKEN'] = token
end
conn.headers['X-AUTH-TOKEN'] = token if token
os_string = ""
os_type.each do |os,num|
num.times do |i|
os_string << os+"+"
end
end
os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
os_string = os_string.chomp("+")
if os_string.size == 0
raise MissingParamError, "No operating systems provided to obtain."
end
response = conn.post "vm/#{os_string}"
response = conn.post "vm/#{os_string}" unless ondemand
response ||= conn.post "ondemandvm/#{os_string}"
res_body = JSON.parse(response.body)
if res_body["ok"]
if res_body['ok']
res_body
elsif response.status == 401
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
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}"
end
end
def self.modify(verbose, url, hostname, token, lifetime, tags)
if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to modify vm"
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
modify_body = {}
if lifetime
modify_body['lifetime'] = lifetime
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
if tags
modify_body['tags'] = tags
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
end
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token
if modify_hash['disk']
disk(verbose, url, hostname, token, modify_hash['disk'])
modify_hash.delete 'disk'
end
response = conn.put do |req|
req.url "vm/#{hostname}"
req.body = modify_body.to_json
req.body = modify_hash.to_json
end
res_body = JSON.parse(response.body)
if res_body['ok']
res_body
elsif response.status == 401
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
else
raise ModifyError, "HTTP #{response.status}: Failed to modify VMs from the pooler vm/#{hostname}. #{res_body}"
end
end
def self.disk(verbose, url, hostname, token, disk)
if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to modify vm"
end
raise TokenError, 'Token provided was nil. Request cannot be made to modify vm' if token.nil?
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token
response = conn.post "vm/#{hostname}/disk/#{disk}"
res_body = JSON.parse(response.body)
res_body
JSON.parse(response.body)
end
def self.delete(verbose, url, hosts, token)
if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to delete vm"
end
def self.delete(verbose, url, hosts, token, _user)
raise TokenError, 'Token provided was nil. Request cannot be made to delete vm' if token.nil?
conn = Http.get_conn(verbose, url)
if token
conn.headers['X-AUTH-TOKEN'] = token
end
conn.headers['X-AUTH-TOKEN'] = token if token
response_body = {}
@ -118,55 +146,43 @@ class Pooler
def self.status(verbose, url)
conn = Http.get_conn(verbose, url)
response = conn.get '/status'
res_body = JSON.parse(response.body)
res_body
response = conn.get 'status'
JSON.parse(response.body)
end
def self.summary(verbose, url)
conn = Http.get_conn(verbose, url)
response = conn.get '/summary'
res_body = JSON.parse(response.body)
res_body
response = conn.get 'summary'
JSON.parse(response.body)
end
def self.query(verbose, url, hostname)
conn = Http.get_conn(verbose, url)
response = conn.get "vm/#{hostname}"
res_body = JSON.parse(response.body)
res_body
JSON.parse(response.body)
end
def self.snapshot(verbose, url, hostname, token)
if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to snapshot vm"
end
raise TokenError, 'Token provided was nil. Request cannot be made to snapshot vm' if token.nil?
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token
response = conn.post "vm/#{hostname}/snapshot"
res_body = JSON.parse(response.body)
res_body
JSON.parse(response.body)
end
def self.revert(verbose, url, hostname, token, snapshot_sha)
if token.nil?
raise TokenError, "Token provided was nil. Request cannot be made to revert vm"
end
raise TokenError, 'Token provided was nil. Request cannot be made to revert vm' if token.nil?
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token
if snapshot_sha.nil?
raise "Snapshot SHA provided was nil, could not revert #{hostname}"
end
raise "Snapshot SHA provided was nil, could not revert #{hostname}" if snapshot_sha.nil?
response = conn.post "vm/#{hostname}/snapshot/#{snapshot_sha}"
res_body = JSON.parse(response.body)
res_body
JSON.parse(response.body)
end
end

152
lib/vmfloaty/service.rb Normal file
View file

@ -0,0 +1,152 @@
# frozen_string_literal: true
require 'commander/user_interaction'
require 'commander/command'
require 'vmfloaty/utils'
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)
if @service_object.respond_to?(method_name)
@service_object.send(method_name, *args, &block)
else
super
end
end
def respond_to_missing?(method_name, *)
@service_object.respond_to?(method_name) || super
end
def url
@config['url']
end
def type
@service_object.name
end
def user
unless @config['user']
FloatyLogger.info "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...'
@config['token'] = get_new_token(nil)
end
@config['token']
end
def get_new_token(verbose)
username = user
pass = Commander::UI.password "Enter your #{@config['url']} service password:", '*'
Auth.get_token(verbose, url, username, pass)
end
def delete_token(verbose, token_value = @config['token'])
username = user
pass = Commander::UI.password "Enter your #{@config['url']} service password:", '*'
Auth.delete_token(verbose, url, username, pass, token_value)
end
def token_status(verbose, token_value)
token_value ||= @config['token']
Auth.token_status(verbose, url, token_value)
end
def list(verbose, os_filter = nil)
@service_object.list verbose, url, os_filter
end
def list_active(verbose)
@service_object.list_active verbose, url, token, 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
token_value = use_token ? token : nil
@service_object.retrieve verbose, os_types, token_value, url, user, @config, ondemand, continue
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)
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...'
end
end
Ssh.ssh(verbose, self, host_os, token_value, ondemand)
end
def query(verbose, hostname)
@service_object.query verbose, url, hostname
end
def modify(verbose, hostname, modify_hash)
maybe_use_vmpooler
@service_object.modify verbose, url, hostname, token, modify_hash
end
def delete(verbose, hosts)
@service_object.delete verbose, url, hosts, token, user
end
def status(verbose)
@service_object.status verbose, url
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

View file

@ -1,43 +1,61 @@
class Ssh
# frozen_string_literal: true
class Ssh
def self.which(cmd)
# Gets path of executable for given command
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each { |ext|
exts.each do |ext|
exe = File.join(path, "#{cmd}#{ext}")
return exe if File.executable?(exe) && !File.directory?(exe)
}
end
return nil
end
nil
end
def self.ssh(verbose, host_os, token, url)
ssh_path = which("ssh")
if !ssh_path
raise "Could not determine path to ssh"
end
os_types = {}
def self.command_string(verbose, service, host_os, use_token, ondemand = nil)
ssh_path = which('ssh')
raise 'Could not determine path to ssh' unless ssh_path
os_types = Utils.generate_os_hash([host_os])
os_types[host_os] = 1
response = Pooler.retrieve(verbose, os_types, token, url)
if response["ok"] == true
if host_os =~ /win/
user = "Administrator"
response = service.retrieve(verbose, os_types, use_token, ondemand)
raise "Could not get vm from #{service.type}:\n #{response}" unless response['ok']
user = /win/.match?(host_os) ? 'Administrator' : 'root'
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
user = "root"
# 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"]}.#{response["domain"]}"
cmd = "#{ssh_path} #{user}@#{hostname}"
"#{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)
# TODO: Should this respect more ssh settings? Can it be configured
# by users ssh config and does this respect those settings?
Kernel.exec(cmd)
else
raise "Could not get vm from vmpooler:\n #{response}"
end
return
nil
end
end

View file

@ -1,27 +1,84 @@
# frozen_string_literal: true
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.format_hosts(hostname_hash)
host_hash = {}
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`:
# {
# "ok": true,
# "domain": "delivery.mycompany.net",
# "ubuntu-1610-x86_64": {
# "hostname": ["gdoy8q3nckuob0i", "ctnktsd0u11p9tm"]
# },
# "centos-7-x86_64": {
# "hostname": "dlgietfmgeegry2"
# }
# }
hostname_hash.delete("ok")
domain = hostname_hash["domain"]
hostname_hash.each do |type, hosts|
if type != "domain"
if hosts["hostname"].kind_of?(Array)
hosts["hostname"].map!{|host| host + "." + domain }
else
hosts["hostname"] = hosts["hostname"] + "." + domain
# 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,
# "solaris-10-sparc": {
# "hostname": ["sol10-10.delivery.mycompany.net", "sol10-11.delivery.mycompany.net"]
# },
# "ubuntu-16.04-power8": {
# "hostname": "power8-ubuntu1604-6.delivery.mycompany.net"
# }
# }
# abs pooler response body example when `floaty get` arguments are :
# {
# "hostname"=>"thin-soutane.delivery.puppetlabs.net",
# "type"=>"centos-7.2-tmpfs-x86_64",
# "engine"=>"vmpooler"
# }
unless response_body.delete('ok')
raise ArgumentError,
"Bad GET response passed to format_hosts: #{response_body.to_json}"
end
host_hash[type] = hosts["hostname"]
end
# 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|
hostnames = Array(value['hostname'])
hostnames.map! { |host| "#{host}.#{domain}" } if domain
result[os] = hostnames
end
host_hash.to_json
result
end
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
end.join("\n")
end
def self.generate_os_hash(os_args)
@ -35,82 +92,248 @@ class Utils
# ...]
os_types = {}
os_args.each do |arg|
os_arr = arg.split("=")
if os_arr.size == 1
# assume they didn't specify an = sign if split returns 1 size
os_types[os_arr[0]] = 1
else
os_types[os_arr[0]] = os_arr[1].to_i
end
os_arr = arg.split('=')
os_types[os_arr[0]] = os_arr.size == 1 ? 1 : os_arr[1].to_i
end
os_types
end
def self.get_vm_info(hosts, verbose, url)
vms = {}
hosts.each do |host|
vm_info = Pooler.query(verbose, url, host)
if vm_info['ok']
vms[host] = {}
vms[host]['domain'] = vm_info[host]['domain']
vms[host]['template'] = vm_info[host]['template']
vms[host]['lifetime'] = vm_info[host]['lifetime']
vms[host]['running'] = vm_info[host]['running']
vms[host]['tags'] = vm_info[host]['tags']
end
end
vms
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
def self.prettyprint_hosts(hosts, verbose, url)
puts "Running VMs:"
vm_info = get_vm_info(hosts, verbose, url)
vm_info.each do |vm,info|
domain = info['domain']
template = info['template']
lifetime = info['lifetime']
running = info['running']
tags = info['tags'] || {}
tag_pairs = tags.map {|key,value| "#{key}: #{value}" }
duration = "#{running}/#{lifetime} hours"
metadata = [template, duration, *tag_pairs]
puts "- #{vm}.#{domain} (#{metadata.join(", ")})"
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.get_all_token_vms(verbose, url, token)
# get vms with token
status = Auth.token_status(verbose, url, token)
def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false, indent = 0)
output_target = print_to_stderr ? $stderr : $stdout
vms = status[token]['vms']
if vms.nil?
raise "You have no running vms"
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
running_vms = vms['running']
running_vms
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.prettyprint_status(status, message, pools, verbose)
pools.select! {|name,pool| pool['ready'] < pool['max']} if ! verbose
def self.get_host_data(verbose, service, hostnames = [])
result = {}
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
case service.type
when 'ABS'
# For ABS, 'hostname' variable is the jobID
result[hostname] = host_data if host_data['state'] == 'allocated' || host_data['state'] == 'filled'
when 'Pooler'
result[hostname] = host_data
when 'NonstandardPooler'
result[hostname] = host_data
else
raise "Invalid service type #{service.type}"
end
end
rescue StandardError => e
FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:")
FloatyLogger.error(e)
end
result
end
def self.pretty_print_status(verbose, service)
status_response = service.status(verbose)
case service.type
when 'Pooler'
message = status_response['status']['message']
pools = status_response['pools']
pools.select! { |_, pool| pool['ready'] < pool['max'] } unless verbose
width = pools.keys.map(&:length).max
pools.each do |name, pool|
begin
max = pool['max']
ready = pool['ready']
pending = pool['pending']
missing = max - ready - pending
char = 'o'
puts "#{name.ljust(width)} #{(char*ready).green}#{(char*pending).yellow}#{(char*missing).red}"
rescue => e
puts "#{name.ljust(width)} #{e.red}"
puts "#{name.ljust(width)} #{(char * ready)}#{(char * pending)}#{(char * missing)}"
rescue StandardError => e
FloatyLogger.error "#{name.ljust(width)} #{e}"
end
puts message
when 'NonstandardPooler'
pools = status_response
pools.delete 'ok'
pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose
width = pools.keys.map(&:length).max
pools.each do |name, pool|
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}"
end
when 'ABS'
FloatyLogger.error 'ABS Not OK' unless status_response
puts 'ABS is OK' if status_response
else
raise "Invalid service type #{service.type}"
end
end
puts
puts message.colorize(status['status']['ok'] ? :default : :red)
# Adapted from ActiveSupport
def self.strip_heredoc(str)
min_indent = str.scan(/^[ \t]*(?=\S)/).min
min_indent_size = min_indent.nil? ? 0 : min_indent.size
str.gsub(/^[ \t]{#{min_indent_size}}/, '')
end
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
NonstandardPooler
elsif vmpooler_strings.include? type.downcase
Pooler
else
Pooler
end
end
def self.get_service_config(config, options)
# The top-level url, user, and token values in the config file are treated as defaults
service_config = {
'url' => config['url'],
'user' => config['user'],
'token' => config['token'],
'vmpooler_fallback' => config['vmpooler_fallback'],
'type' => config['type'] || 'vmpooler'
}
if config['services']
if options.service.nil?
# If the user did not specify a service name at the command line, but configured services do exist,
# use the first configured service in the list by default.
_, values = config['services'].first
service_config.merge! values
else
# If the user provided a service name at the command line, use that service if posible, or fail
unless config['services'][options.service]
raise ArgumentError,
"Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml"
end
# If the service is configured but some values are missing, use the top-level defaults to fill them in
service_config.merge! config['services'][options.service]
end
# 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
service_config['priority'] = options.priority unless options.priority.nil?
service_config['url'] = options.url unless options.url.nil?
service_config['token'] = options.token unless options.token.nil?
service_config['user'] = options.user unless options.user.nil?
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

View file

@ -1,8 +1,5 @@
# frozen_string_literal: true
class Version
@version = '0.7.5'
def self.get
@version
end
class Vmfloaty
VERSION = '1.8.1'
end

12
release-prep Executable file
View file

@ -0,0 +1,12 @@
#!/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)

View file

@ -1,2 +1,53 @@
# 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'
# Mock Commander Options object to allow pre-population with values
class MockOptions < Commander::Command::Options
def initialize(values = {})
@table = values
end
end
RSpec.configure do |config|
config.color = true
config.tty = true
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

View file

@ -0,0 +1,93 @@
# frozen_string_literal: true
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
describe '#get_token' do
before :each do
@get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}'
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
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: {})
token = Auth.get_token(false, @abs_url, user, pass)
expect(token).to eq @token
end
it 'raises a token error if something goes wrong' do
stub_request(:post, 'https://abs.example.com/api/v2/token')
.with(headers: get_headers(username: user, password: pass, content_length: 0))
.to_return(status: 500, body: '{"ok":false}', headers: {})
expect { Auth.get_token(false, @abs_url, user, pass) }.to raise_error(TokenError)
end
end
describe '#delete_token' do
before :each do
@delete_token_response = '{"ok":true}'
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end
it 'deletes the specified token' do
stub_request(:delete, 'https://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
.with(headers: get_headers(username: user, password: pass))
.to_return(status: 200, body: @delete_token_response, headers: {})
expect(Auth.delete_token(false, @abs_url, user, pass,
@token)).to eq JSON.parse(@delete_token_response)
end
it 'raises a token error if something goes wrong' do
stub_request(:delete, 'https://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
.with(headers: get_headers(username: user, password: pass))
.to_return(status: 500, body: '{"ok":false}', headers: {})
expect { Auth.delete_token(false, @abs_url, user, pass, @token) }.to raise_error(TokenError)
end
it 'raises a token error if no token provided' do
expect { Auth.delete_token(false, @abs_url, user, pass, nil) }.to raise_error(TokenError)
end
end
describe '#token_status' do
before :each do
@token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}'
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end
it 'checks the status of a token' do
stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
.with(headers: get_headers)
.to_return(status: 200, body: @token_status_response, headers: {})
expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response)
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: {})
expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError)
end
it 'raises a token error if no token provided' do
expect { Auth.token_status(false, @abs_url, nil) }.to raise_error(TokenError)
end
end
end

182
spec/vmfloaty/abs_spec.rb Normal file
View file

@ -0,0 +1,182 @@
# frozen_string_literal: true
require 'spec_helper'
require 'vmfloaty/utils'
require 'vmfloaty/errors'
require 'vmfloaty/abs'
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'
abs_formatted_response = [
{ 'hostname' => 'aaaaaaaaaaaaaaa.delivery.puppetlabs.net', 'type' => 'centos-7.2-x86_64',
'engine' => 'vmpooler' },
{ 'hostname' => 'aaaaaaaaaaaaaab.delivery.puppetlabs.net', 'type' => 'centos-7.2-x86_64',
'engine' => 'vmpooler' },
{ 'hostname' => 'aaaaaaaaaaaaaac.delivery.puppetlabs.net', 'type' => 'ubuntu-7.2-x86_64',
'engine' => 'vmpooler' }
]
vmpooler_formatted_response = ABS.translated(abs_formatted_response, job_id)
vmpooler_formatted_compare = {
'centos-7.2-x86_64' => {},
'ubuntu-7.2-x86_64' => {}
}
vmpooler_formatted_compare['centos-7.2-x86_64']['hostname'] =
['aaaaaaaaaaaaaaa.delivery.puppetlabs.net', 'aaaaaaaaaaaaaab.delivery.puppetlabs.net']
vmpooler_formatted_compare['ubuntu-7.2-x86_64']['hostname'] = ['aaaaaaaaaaaaaac.delivery.puppetlabs.net']
vmpooler_formatted_compare['ok'] = true
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')
expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare)
end
it 'won\'t delete a job if not all vms are listed' do
hosts = ['host1']
allocated_resources = [
{
'hostname' => 'host1'
},
{
'hostname' => 'host2'
}
]
expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(false)
hosts = %w[host1 host2]
allocated_resources = [
{
'hostname' => 'host1'
},
{
'hostname' => 'host2'
}
]
expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(true)
end
before :each do
@abs_url = 'https://abs.example.com'
end
describe '#test_abs_status_queue_endpoint' do
before :each do
# rubocop:disable Layout/LineLength
@active_requests_response = '
[
{ "state":"allocated","last_processed":"2019-12-16 23:00:34 +0000","allocated_resources":[{"hostname":"take-this.delivery.puppetlabs.net","type":"win-2012r2-x86_64","engine":"vmpooler"}],"audit_log":{"2019-12-13 16:45:29 +0000":"Allocated take-this.delivery.puppetlabs.net for job 1576255517241"},"request":{"resources":{"win-2012r2-x86_64":1},"job":{"id":"1576255517241","tags":{"user":"test-user"},"user":"test-user","time-received":1576255519},"priority":1}},
"null",
{"state":"allocated","last_processed":"2019-12-16 23:00:34 +0000","allocated_resources":[{"hostname":"not-this.delivery.puppetlabs.net","type":"win-2012r2-x86_64","engine":"vmpooler"}],"audit_log":{"2019-12-13 16:46:14 +0000":"Allocated not-this.delivery.puppetlabs.net for job 1576255565159"},"request":{"resources":{"win-2012r2-x86_64":1},"job":{"id":"1576255565159","tags":{"user":"not-test-user"},"user":"not-test-user","time-received":1576255566},"priority":1}}
]'
# rubocop:enable Layout/LineLength
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
@test_user = 'test-user'
end
it 'will skip a line with a null value returned from abs' do
stub_request(:get, 'https://abs.example.com/api/v2/status/queue')
.to_return(status: 200, body: @active_requests_response, headers: {})
ret = ABS.get_active_requests(false, @abs_url, @test_user)
expect(ret[0]).to include(
'allocated_resources' => [{
'hostname' => 'take-this.delivery.puppetlabs.net',
'type' => 'win-2012r2-x86_64',
'engine' => 'vmpooler'
}]
)
end
end
describe '#test_abs_delete_jobid' do
before :each do
# rubocop:disable Layout/LineLength
@active_requests_response = '
[
{ "state":"allocated", "last_processed":"2020-01-17 22:29:13 +0000", "allocated_resources":[{"hostname":"craggy-chord.delivery.puppetlabs.net", "type":"centos-7-x86_64", "engine":"vmpooler"}, {"hostname":"visible-revival.delivery.puppetlabs.net", "type":"centos-7-x86_64", "engine":"vmpooler"}], "audit_log":{"2020-01-17 22:28:45 +0000":"Allocated craggy-chord.delivery.puppetlabs.net, visible-revival.delivery.puppetlabs.net for job 1579300120799"}, "request":{"resources":{"centos-7-x86_64":2}, "job":{"id":"1579300120799", "tags":{"user":"test-user"}, "user":"test-user", "time-received":1579300120}, "priority":3}}
]'
@return_request = {
"job_id" => "1579300120799",
"hosts" => [{"hostname"=>"craggy-chord.delivery.puppetlabs.net","type"=>"centos-7-x86_64","engine"=>"vmpooler"},
{"hostname"=>"visible-revival.delivery.puppetlabs.net","type"=>"centos-7-x86_64","engine"=>"vmpooler"}]
}
# rubocop:enable Layout/LineLength
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
@test_user = 'test-user'
# Job ID
@hosts = ['1579300120799']
end
it 'will delete the whole job' do
stub_request(:get, 'https://abs.example.com/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: {})
ret = ABS.delete(false, @abs_url, @hosts, @token, @test_user)
expect(ret).to include(
'craggy-chord.delivery.puppetlabs.net' => { 'ok' => true }, 'visible-revival.delivery.puppetlabs.net' => { 'ok' => true }
)
end
end
end
end

View file

@ -1,85 +1,91 @@
# frozen_string_literal: true
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"
@vmpooler_url = 'https://vmpooler.example.com'
end
describe "#get_token" do
describe '#get_token' do
before :each do
@get_token_response = "{\"ok\": true,\"token\":\"utpg2i2xswor6h8ttjhu3d47z53yy47y\"}"
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y"
@get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}'
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end
it "returns a token from vmpooler" do
stub_request(:post, "https://first.last:password@vmpooler.example.com/token").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => @get_token_response, :headers => {})
it 'returns a token from vmpooler' do
stub_request(:post, 'https://vmpooler.example.com/token')
.with(headers: get_headers(username: user, password: pass, content_length: 0))
.to_return(status: 200, body: @get_token_response, headers: {})
token = Auth.get_token(false, @vmpooler_url, "first.last", "password")
token = Auth.get_token(false, @vmpooler_url, user, pass)
expect(token).to eq @token
end
it "raises a token error if something goes wrong" do
stub_request(:post, "https://first.last:password@vmpooler.example.com/token").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {})
it 'raises a token error if something goes wrong' do
stub_request(:post, 'https://vmpooler.example.com/token')
.with(headers: get_headers(username: user, password: pass, content_length: 0))
.to_return(status: 500, body: '{"ok":false}', headers: {})
expect{ Auth.get_token(false, @vmpooler_url, "first.last", "password") }.to raise_error(TokenError)
expect { Auth.get_token(false, @vmpooler_url, user, pass) }.to raise_error(TokenError)
end
end
describe "#delete_token" do
describe '#delete_token' do
before :each do
@delete_token_response = "{\"ok\":true}"
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y"
@delete_token_response = '{"ok":true}'
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end
it "deletes the specified token" do
stub_request(:delete, "https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => @delete_token_response, :headers => {})
it 'deletes the specified token' do
stub_request(:delete, 'https://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
.with(headers: get_headers(username: user, password: pass))
.to_return(status: 200, body: @delete_token_response, headers: {})
expect(Auth.delete_token(false, @vmpooler_url, "first.last", "password", @token)).to eq JSON.parse(@delete_token_response)
expect(Auth.delete_token(false, @vmpooler_url, user, pass,
@token)).to eq JSON.parse(@delete_token_response)
end
it "raises a token error if something goes wrong" do
stub_request(:delete, "https://first.last:password@vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {})
it 'raises a token error if something goes wrong' do
stub_request(:delete, 'https://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
.with(headers: get_headers(username: user, password: pass))
.to_return(status: 500, body: '{"ok":false}', headers: {})
expect{ Auth.delete_token(false, @vmpooler_url, "first.last", "password", @token) }.to raise_error(TokenError)
expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
end
it "raises a token error if no token provided" do
expect{ Auth.delete_token(false, @vmpooler_url, "first.last", "password", nil) }.to raise_error(TokenError)
it 'raises a token error if no token provided' do
expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', nil) }.to raise_error(TokenError)
end
end
describe "#token_status" do
describe '#token_status' do
before :each do
@token_status_response = "{\"ok\":true,\"utpg2i2xswor6h8ttjhu3d47z53yy47y\":{\"created\":\"2015-04-28 19:17:47 -0700\"}}"
@token = "utpg2i2xswor6h8ttjhu3d47z53yy47y"
@token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}'
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
end
it "checks the status of a token" do
stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => @token_status_response, :headers => {})
it 'checks the status of a token' do
stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
.with(headers: get_headers)
.to_return(status: 200, body: @token_status_response, headers: {})
expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response)
end
it "raises a token error if something goes wrong" do
stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 500, :body => "{\"ok\":false}", :headers => {})
it 'raises a token error if something goes wrong' do
stub_request(:get, "#{@vmpooler_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
.with(headers: get_headers)
.to_return(status: 500, body: '{"ok":false}', headers: {})
expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError)
end
it "raises a token error if no token provided" do
it 'raises a token error if no token provided' do
expect { Auth.token_status(false, @vmpooler_url, nil) }.to raise_error(TokenError)
end
end

View file

@ -0,0 +1,312 @@
# frozen_string_literal: true
require 'spec_helper'
require 'vmfloaty/utils'
require 'vmfloaty/errors'
require 'vmfloaty/nonstandard_pooler'
describe NonstandardPooler do
before :each do
@nspooler_url = 'https://nspooler.example.com'
@auth_token_headers = get_headers(token: 'token-value')
end
describe '#list' do
before :each do
@status_response_body = <<~BODY
{
"ok": true,
"solaris-10-sparc": {
"total_hosts": 11,
"available_hosts": 11
},
"ubuntu-16.04-power8": {
"total_hosts": 10,
"available_hosts": 10
},
"aix-7.2-power": {
"total_hosts": 5,
"available_hosts": 4
}
}
BODY
end
it 'returns an array with operating systems from the pooler' do
stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 200, body: @status_response_body, headers: {})
list = NonstandardPooler.list(false, @nspooler_url, nil)
expect(list).to be_an_instance_of Array
end
it 'filters operating systems based on the filter param' do
stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 200, body: @status_response_body, headers: {})
list = NonstandardPooler.list(false, @nspooler_url, 'aix')
expect(list).to be_an_instance_of Array
expect(list.size).to equal 1
end
it 'returns nothing if the filter does not match' do
stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 199, body: @status_response_body, headers: {})
list = NonstandardPooler.list(false, @nspooler_url, 'windows')
expect(list).to be_an_instance_of Array
expect(list.size).to equal 0
end
end
describe '#list_active' do
before :each do
@token_status_body_active = <<~BODY
{
"ok": true,
"user": "first.last",
"created": "2017-09-18 01:25:41 +0000",
"last_accessed": "2017-09-21 19:46:25 +0000",
"reserved_hosts": ["sol10-9", "sol10-11"]
}
BODY
@token_status_body_empty = <<~BODY
{
"ok": true,
"user": "first.last",
"created": "2017-09-18 01:25:41 +0000",
"last_accessed": "2017-09-21 19:46:25 +0000",
"reserved_hosts": []
}
BODY
end
it 'prints an output of fqdn, template, and duration' do
allow(Auth).to receive(:token_status)
.with(false, @nspooler_url, 'token-value')
.and_return(JSON.parse(@token_status_body_active))
list = NonstandardPooler.list_active(false, @nspooler_url, 'token-value', 'user')
expect(list).to eql %w[sol10-9 sol10-11]
end
end
describe '#retrieve' do
before :each do
@retrieve_response_body_single = <<~BODY
{
"ok": true,
"solaris-11-sparc": {
"hostname": "sol11-4.delivery.puppetlabs.net"
}
}
BODY
@retrieve_response_body_many = <<~BODY
{
"ok": true,
"solaris-10-sparc": {
"hostname": [
"sol10-9.delivery.puppetlabs.net",
"sol10-10.delivery.puppetlabs.net"
]
},
"aix-7.1-power": {
"hostname": "pe-aix-71-ci-acceptance.delivery.puppetlabs.net"
}
}
BODY
end
it 'raises an AuthError if the token is invalid' do
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
.with(headers: get_headers(token: 'token-value'))
.to_return(status: 401, body: '{"ok":false,"reason": "token: token-value does not exist"}', headers: {})
vm_hash = { 'solaris-11-sparc' => 1 }
expect do
NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {})
end.to raise_error(AuthError)
end
it 'retrieves a single vm with a token' do
stub_request(:post, "#{@nspooler_url}/host/solaris-11-sparc")
.with(headers: @auth_token_headers)
.to_return(status: 200, body: @retrieve_response_body_single, headers: {})
vm_hash = { 'solaris-11-sparc' => 1 }
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, 'first.last', {})
expect(vm_req).to be_an_instance_of Hash
expect(vm_req['ok']).to equal true
expect(vm_req['solaris-11-sparc']['hostname']).to eq 'sol11-4.delivery.puppetlabs.net'
end
it 'retrieves a multiple vms with a token' do
stub_request(:post, "#{@nspooler_url}/host/aix-7.1-power+solaris-10-sparc+solaris-10-sparc")
.with(headers: @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['aix-7.1-power']['hostname']).to eq 'pe-aix-71-ci-acceptance.delivery.puppetlabs.net'
end
end
describe '#modify' do
before :each do
@modify_response_body_success = '{"ok":true}'
end
it 'raises an error if the user tries to modify an unsupported attribute' do
stub_request(:put, 'https://nspooler.example.com/host/myfakehost')
.with(body: { '{}' => true },
headers: @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 }
stub_request(:put, "#{@nspooler_url}/host/myfakehost")
.with(body: modify_request_body,
headers: @auth_token_headers)
.to_return(status: 200, body: '{"ok": true}', headers: {})
modify_hash = { reason: 'testing' }
modify_req = NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', modify_hash)
expect(modify_req['ok']).to be true
end
end
describe '#status' do
before :each do
@status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}'
# TODO: make this report stuff like 'broken'
@status_response_body = <<~BODY
{
"ok": true,
"solaris-10-sparc": {
"total_hosts": 11,
"available_hosts": 10
},
"ubuntu-16.04-power8": {
"total_hosts": 10,
"available_hosts": 10
},
"aix-7.2-power": {
"total_hosts": 5,
"available_hosts": 4
}
}
BODY
end
it 'prints the status' do
stub_request(:get, "#{@nspooler_url}/status")
.to_return(status: 200, body: @status_response_body, headers: {})
status = NonstandardPooler.status(false, @nspooler_url)
expect(status).to be_an_instance_of Hash
end
end
describe '#summary' do
before :each do
@status_response_body = <<~BODY
{
"ok": true,
"total": 57,
"available": 39,
"in_use": 16,
"resetting": 2,
"broken": 0
}
BODY
end
it 'prints the summary' do
stub_request(:get, "#{@nspooler_url}/summary")
.to_return(status: 200, body: @status_response_body, headers: {})
summary = NonstandardPooler.summary(false, @nspooler_url)
expect(summary).to be_an_instance_of Hash
end
end
describe '#query' do
before :each do
@query_response_body = <<~BODY
{
"ok": true,
"sol10-11": {
"fqdn": "sol10-11.delivery.puppetlabs.net",
"os_triple": "solaris-10-sparc",
"reserved_by_user": "first.last",
"reserved_for_reason": "testing",
"hours_left_on_reservation": 29.12
}
}
BODY
end
it 'makes a query about a vm' do
stub_request(:get, "#{@nspooler_url}/host/sol10-11")
.to_return(status: 200, body: @query_response_body, headers: {})
query_req = NonstandardPooler.query(false, @nspooler_url, 'sol10-11')
expect(query_req).to be_an_instance_of Hash
end
end
describe '#delete' do
before :each do
@delete_response_success = '{"ok": true}'
@delete_response_failure = '{"ok": false, "failure": "ERROR: fakehost does not exist"}'
end
it 'deletes a single existing vm' do
stub_request(:delete, "#{@nspooler_url}/host/sol11-7")
.with(headers: @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
end
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: {})
request = NonstandardPooler.delete(false, @nspooler_url, 'fakehost', 'token-value', nil)
expect(request['fakehost']['ok']).to be false
end
end
describe '#snapshot' do
it 'logs an error explaining that snapshots are not supported' do
expect { NonstandardPooler.snapshot(false, @nspooler_url, 'myfakehost', 'token-value') }
.to raise_error(ModifyError)
end
end
describe '#revert' do
it 'logs an error explaining that snapshots are not supported' do
expect { NonstandardPooler.revert(false, @nspooler_url, 'myfakehost', 'token-value', 'snapshot-sha') }
.to raise_error(ModifyError)
end
end
describe '#disk' do
it 'logs an error explaining that disk modification is not supported' do
expect { NonstandardPooler.disk(false, @nspooler_url, 'myfakehost', 'token-value', 'diskname') }
.to raise_error(ModifyError)
end
end
end

View file

@ -1,222 +1,246 @@
# frozen_string_literal: true
require 'spec_helper'
require_relative '../../lib/vmfloaty/pooler'
describe Pooler do
before :each do
@vmpooler_url = "https://vmpooler.example.com"
@vmpooler_url = 'https://vmpooler.example.com'
end
describe "#list" do
describe '#list' do
before :each do
@list_response_body = "[\"debian-7-i386\",\"debian-7-x86_64\",\"centos-7-x86_64\"]"
@list_response_body = '["debian-7-i386","debian-7-x86_64","centos-7-x86_64"]'
end
it "returns a hash with operating systems from the pooler" do
stub_request(:get, "#{@vmpooler_url}/vm").
to_return(:status => 200, :body => @list_response_body, :headers => {})
it 'returns a hash with operating systems from the pooler' do
stub_request(:get, "#{@vmpooler_url}/vm")
.to_return(status: 200, body: @list_response_body, headers: {})
list = Pooler.list(false, @vmpooler_url, nil)
expect(list).to be_an_instance_of Array
end
it "filters operating systems based on the filter param" do
stub_request(:get, "#{@vmpooler_url}/vm").
to_return(:status => 200, :body => @list_response_body, :headers => {})
it 'filters operating systems based on the filter param' do
stub_request(:get, "#{@vmpooler_url}/vm")
.to_return(status: 200, body: @list_response_body, headers: {})
list = Pooler.list(false, @vmpooler_url, "deb")
list = Pooler.list(false, @vmpooler_url, 'deb')
expect(list).to be_an_instance_of Array
expect(list.size).to equal 2
end
it "returns nothing if the filter does not match" do
stub_request(:get, "#{@vmpooler_url}/vm").
to_return(:status => 200, :body => @list_response_body, :headers => {})
it 'returns nothing if the filter does not match' do
stub_request(:get, "#{@vmpooler_url}/vm")
.to_return(status: 200, body: @list_response_body, headers: {})
list = Pooler.list(false, @vmpooler_url, "windows")
list = Pooler.list(false, @vmpooler_url, 'windows')
expect(list).to be_an_instance_of Array
expect(list.size).to equal 0
end
end
describe "#retrieve" do
describe '#retrieve' do
before :each do
@retrieve_response_body_single = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":\"fq6qlpjlsskycq6\"}}"
@retrieve_response_body_double = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":[\"sc0o4xqtodlul5w\",\"4m4dkhqiufnjmxy\"]},\"centos-7-x86_64\":{\"hostname\":\"zb91y9qbrbf6d3q\"}}"
@retrieve_response_body_single = '{"ok":true,"debian-7-i386":{"hostname":"fq6qlpjlsskycq6"}}'
@retrieve_response_body_double = '{"ok":true,"debian-7-i386":{"hostname":["sc0o4xqtodlul5w","4m4dkhqiufnjmxy"]},"centos-7-x86_64":{"hostname":"zb91y9qbrbf6d3q"}}'
end
it "raises an AuthError if the token is invalid" do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 401, :body => "{\"ok\":false}", :headers => {})
it 'raises an AuthError if the token is invalid' do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' })
.to_return(status: 401, body: '{"ok":false}', headers: {})
vm_hash = {}
vm_hash['debian-7-i386'] = 1
expect{ Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url) }.to raise_error(AuthError)
expect { Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {}) }.to raise_error(AuthError)
end
it "retrieves a single vm with a token" do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
it 'retrieves a single vm with a token' do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' })
.to_return(status: 200, body: @retrieve_response_body_single, headers: {})
vm_hash = {}
vm_hash['debian-7-i386'] = 1
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url)
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {})
expect(vm_req).to be_an_instance_of Hash
expect(vm_req["ok"]).to equal true
expect(vm_req["debian-7-i386"]["hostname"]).to eq "fq6qlpjlsskycq6"
expect(vm_req['ok']).to equal true
expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6'
end
it "retrieves a multiple vms with a token" do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 200, :body => @retrieve_response_body_double, :headers => {})
it 'retrieves a multiple vms with a token' do
stub_request(:post, "#{@vmpooler_url}/vm/debian-7-i386+debian-7-i386+centos-7-x86_64")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' })
.to_return(status: 200, body: @retrieve_response_body_double, headers: {})
vm_hash = {}
vm_hash['debian-7-i386'] = 2
vm_hash['centos-7-x86_64'] = 1
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url)
vm_req = Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {})
expect(vm_req).to be_an_instance_of Hash
expect(vm_req["ok"]).to equal true
expect(vm_req["debian-7-i386"]["hostname"]).to be_an_instance_of Array
expect(vm_req["debian-7-i386"]["hostname"]).to eq ["sc0o4xqtodlul5w", "4m4dkhqiufnjmxy"]
expect(vm_req["centos-7-x86_64"]["hostname"]).to eq "zb91y9qbrbf6d3q"
expect(vm_req['ok']).to equal true
expect(vm_req['debian-7-i386']['hostname']).to be_an_instance_of Array
expect(vm_req['debian-7-i386']['hostname']).to eq %w[sc0o4xqtodlul5w 4m4dkhqiufnjmxy]
expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q'
end
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
describe '#modify' do
before :each do
@modify_response_body_success = "{\"ok\":true}"
@modify_response_body_fail = "{\"ok\":false}"
@modify_response_body_success = '{"ok":true}'
@modify_response_body_fail = '{"ok":false}'
end
it "raises a TokenError if token provided is nil" do
expect{ Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, 12, nil) }.to raise_error(TokenError)
it 'raises a TokenError if token provided is nil' do
expect { Pooler.modify(false, @vmpooler_url, 'myfakehost', nil, {}) }.to raise_error(TokenError)
end
it "modifies the TTL of a vm" do
stub_request(:put, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6").
with(:body => {"{\"lifetime\":12}"=>true},
:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 200, :body => @modify_response_body_success, :headers => {})
it 'modifies the TTL of a vm' do
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: {})
modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12, nil)
expect(modify_req["ok"]).to be true
modify_req = Pooler.modify(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', modify_hash)
expect(modify_req['ok']).to be true
end
end
describe "#delete" do
describe '#delete' do
before :each do
@delete_response_body_success = "{\"ok\":true}"
@delete_response = {"fq6qlpjlsskycq6"=>{"ok"=>true}}
@delete_response_body_success = '{"ok":true}'
@delete_response = { 'fq6qlpjlsskycq6' => { 'ok' => true } }
end
it "deletes a specified vm" do
stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 200, :body => @delete_response_body_success, :headers => {})
it 'deletes a specified vm' do
stub_request(:delete, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' })
.to_return(status: 200, body: @delete_response_body_success, headers: {})
expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile')).to eq @delete_response
expect(Pooler.delete(false, @vmpooler_url, ['fq6qlpjlsskycq6'], 'mytokenfile', nil)).to eq @delete_response
end
it "raises a token error if no token provided" do
expect{ Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil) }.to raise_error(TokenError)
it 'raises a token error if no token provided' do
expect { Pooler.delete(false, @vmpooler_url, ['myfakehost'], nil, nil) }.to raise_error(TokenError)
end
end
describe "#status" do
describe '#status' do
before :each do
# smaller version
@status_response_body = "{\"capacity\":{\"current\":716,\"total\":717,\"percent\": 99.9},\"status\":{\"ok\":true,\"message\":\"Battle station fully armed and operational.\"}}"
@status_response_body = '{"capacity":{"current":716,"total":717,"percent": 99.9},"status":{"ok":true,"message":"Battle station fully armed and operational."}}'
end
it "prints the status" do
stub_request(:get, "#{@vmpooler_url}/status").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => @status_response_body, :headers => {})
it 'prints the status' do
stub_request(:get, "#{@vmpooler_url}/status")
.to_return(status: 200, body: @status_response_body, headers: {})
status = Pooler.status(false, @vmpooler_url)
expect(status).to be_an_instance_of Hash
end
end
describe "#summary" do
describe '#summary' do
before :each do
@status_response_body = ""
@status_response_body = ''
it "prints the summary" do
it 'prints the summary' do
end
end
end
describe "#query" do
describe '#query' do
before :each do
@query_response_body = "{\"ok\": true,\"fq6qlpjlsskycq6\":{\"template\":\"debian-7-x86_64\",\"lifetime\": 2,\"running\": 0.08,\"state\":\"running\",\"snapshots\":[\"n4eb4kdtp7rwv4x158366vd9jhac8btq\" ],\"domain\": \"delivery.puppetlabs.net\"}}"
@query_response_body = '{"ok": true,"fq6qlpjlsskycq6":{"template":"debian-7-x86_64","lifetime": 2,"running": 0.08,"state":"running","snapshots":["n4eb4kdtp7rwv4x158366vd9jhac8btq" ],"domain": "delivery.puppetlabs.net"}}'
end
it "makes a query about a vm" do
stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => @query_response_body, :headers => {})
it 'makes a query about a vm' do
stub_request(:get, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6")
.to_return(status: 200, body: @query_response_body, headers: {})
query_req = Pooler.query(false, @vmpooler_url, 'fq6qlpjlsskycq6')
expect(query_req).to be_an_instance_of Hash
end
end
describe "#snapshot" do
describe '#snapshot' do
before :each do
@snapshot_response_body = "{\"ok\":true}"
@snapshot_response_body = '{"ok":true}'
end
it "makes a snapshot for a single vm" do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 200, :body => @snapshot_response_body, :headers => {})
it 'makes a snapshot for a single vm' do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' })
.to_return(status: 200, body: @snapshot_response_body, headers: {})
snapshot_req = Pooler.snapshot(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile')
expect(snapshot_req["ok"]).to be true
expect(snapshot_req['ok']).to be true
end
end
describe "#revert" do
describe '#revert' do
before :each do
@revert_response_body = "{\"ok\":true}"
@revert_response_body = '{"ok":true}'
end
it "makes a request to revert a vm from a snapshot" do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}).
to_return(:status => 200, :body => @revert_response_body, :headers => {})
it 'makes a request to revert a vm from a snapshot' do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/snapshot/dAfewKNfaweLKNve")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' })
.to_return(status: 200, body: @revert_response_body, headers: {})
revert_req = Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 'dAfewKNfaweLKNve')
expect(revert_req["ok"]).to be true
expect(revert_req['ok']).to be true
end
it "doesn't make a request to revert a vm if snapshot is not provided" do
expect{ Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', nil) }.to raise_error(RuntimeError, "Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6")
expect do
Pooler.revert(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile',
nil)
end.to raise_error(RuntimeError, 'Snapshot SHA provided was nil, could not revert fq6qlpjlsskycq6')
end
it "raises a TokenError if no token was provided" do
it 'raises a TokenError if no token was provided' do
expect { Pooler.revert(false, @vmpooler_url, 'myfakehost', nil, 'shaaaaaaa') }.to raise_error(TokenError)
end
end
describe "#disk" do
describe '#disk' do
before :each do
@disk_response_body_success = "{\"ok\":true}"
@disk_response_body_fail = "{\"ok\":false}"
@disk_response_body_success = '{"ok":true}'
@disk_response_body_fail = '{"ok":false}'
end
it "makes a request to extend disk space of a vm" do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length'=>'0', 'User-Agent'=>'Faraday v0.9.2', 'X-Auth-Token'=>'mytokenfile'}). to_return(:status => 200, :body => @disk_response_body_success, :headers => {})
it 'makes a request to extend disk space of a vm' do
stub_request(:post, "#{@vmpooler_url}/vm/fq6qlpjlsskycq6/disk/12")
.with(headers: { 'X-Auth-Token' => 'mytokenfile' }).to_return(status: 200, body: @disk_response_body_success, headers: {})
disk_req = Pooler.disk(false, @vmpooler_url, 'fq6qlpjlsskycq6', 'mytokenfile', 12)
expect(disk_req["ok"]).to be true
expect(disk_req['ok']).to be true
end
it "raises a TokenError if no token was provided" do
it 'raises a TokenError if no token was provided' do
expect { Pooler.disk(false, @vmpooler_url, 'myfakehost', nil, 12) }.to raise_error(TokenError)
end
end

View file

@ -0,0 +1,79 @@
# frozen_string_literal: true
require_relative '../../lib/vmfloaty/service'
describe Service do
describe '#initialize' do
it 'store configuration options' do
options = MockOptions.new({})
config = { 'url' => 'http://example.url' }
service = Service.new(options, config)
expect(service.config).to include config
end
end
describe '#get_new_token' do
it 'prompts the user for their password and retrieves a token' do
config = { 'user' => 'first.last', 'url' => 'http://default.url' }
service = Service.new(MockOptions.new, config)
allow($stdout).to receive(:puts).with('Enter your http://default.url service password:')
allow(Commander::UI).to(receive(:password)
.with('Enter your http://default.url service password:', '*')
.and_return('hunter2'))
allow(Auth).to(receive(:get_token)
.with(nil, config['url'], config['user'], 'hunter2')
.and_return('token-value'))
expect(service.get_new_token(nil)).to eql 'token-value'
end
it 'prompts the user for their username and password if the username is unknown' do
config = { 'url' => 'http://default.url' }
service = Service.new(MockOptions.new({}), config)
allow($stdout).to receive(:puts).with 'Enter your 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'))
allow(Auth).to(receive(:get_token)
.with(nil, config['url'], 'first.last', 'hunter2')
.and_return('token-value'))
expect(service.get_new_token(nil)).to eql 'token-value'
end
end
describe '#delete_token' do
it 'deletes a token' do
service = Service.new(MockOptions.new, 'user' => 'first.last', 'url' => 'http://default.url')
allow(Commander::UI).to(receive(:password)
.with('Enter your http://default.url service password:', '*')
.and_return('hunter2'))
allow(Auth).to(receive(:delete_token)
.with(nil, 'http://default.url', 'first.last', 'hunter2', 'token-value')
.and_return('ok' => true))
expect(service.delete_token(nil, 'token-value')).to eql('ok' => true)
end
end
describe '#token_status' do
it 'reports the status of a token' do
config = {
'user' => 'first.last',
'url' => 'http://default.url'
}
options = MockOptions.new('token' => 'token-value')
service = Service.new(options, config)
status = {
'ok' => true,
'user' => config['user'],
'created' => '2017-09-22 02:04:18 +0000',
'last_accessed' => '2017-09-22 02:04:28 +0000',
'reserved_hosts' => []
}
allow(Auth).to(receive(:token_status)
.with(nil, config['url'], 'token-value')
.and_return(status))
expect(service.token_status(nil, 'token-value')).to eql(status)
end
end
end

112
spec/vmfloaty/ssh_spec.rb Normal file
View file

@ -0,0 +1,112 @@
# frozen_string_literal: true
require 'spec_helper'
require 'vmfloaty/ssh'
class ServiceStub
def retrieve(_verbose, os_types, _use_token, ondemand)
if os_types.keys[0] == 'abs_host_string'
return {
os_types.keys[0] => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net'] },
'ok' => true
}
elsif os_types.keys[0] == 'vmpooler_api_v2_host_string'
return {
os_types.keys[0] => { 'hostname' => ['vmpooler-v2-hostname.delivery.puppetlabs.net'] },
'ok' => true
}
else
return {
os_types.keys[0] => { 'hostname' => 'vmpooler-v1-hostname' },
'domain' => 'delivery.puppetlabs.net',
'ok' => true
}
end
end
def type
return 'abs' if os_types == 'abs_host_string'
return 'vmpooler' if os_types == 'vmpooler_api_v1_host_string' || os_types == 'vmpooler_api_v2_host_string'
end
def wait_for_request(verbose, requestid)
return true
end
end
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
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
end
end

View file

@ -1,91 +1,727 @@
# frozen_string_literal: true
require 'spec_helper'
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 "#get_hosts" do
describe '#standardize_hostnames' do
before :each do
@hostname_hash = "{\"ok\":true,\"debian-7-i386\":{\"hostname\":[\"sc0o4xqtodlul5w\",\"4m4dkhqiufnjmxy\"]},\"debian-7-x86_64\":{\"hostname\":\"zb91y9qbrbf6d3q\"},\"domain\":\"company.com\"}"
@format_hash = "{\"debian-7-i386\":[\"sc0o4xqtodlul5w.company.com\",\"4m4dkhqiufnjmxy.company.com\"],\"debian-7-x86_64\":\"zb91y9qbrbf6d3q.company.com\"}"
@vmpooler_api_v1_response_body = '{
"ok": true,
"domain": "delivery.mycompany.net",
"ubuntu-1610-x86_64": {
"hostname": ["gdoy8q3nckuob0i", "ctnktsd0u11p9tm"]
},
"centos-7-x86_64": {
"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": {
"hostname": ["sol10-10.delivery.mycompany.net", "sol10-11.delivery.mycompany.net"]
},
"ubuntu-16.04-power8": {
"hostname": "power8-ubuntu16.04-6.delivery.mycompany.net"
}
}'
end
it "formats a hostname hash into os, hostnames, and domain name" do
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
expect(Utils.format_hosts(JSON.parse(@hostname_hash))).to eq @format_hash
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'])
end
it 'formats a result from the nonstandard pooler into a hash of os to hostnames' do
result = Utils.standardize_hostnames(JSON.parse(@nonstandard_response_body))
expect(result).to eq('solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'],
'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net'])
end
end
describe "#generate_os_hash" do
describe '#format_host_output' do
before :each do
@host_hash = {"centos"=>1, "debian"=>5, "windows"=>1}
@vmpooler_results = {
'centos-7-x86_64' => ['dlgietfmgeegry2.delivery.mycompany.net'],
'ubuntu-1610-x86_64' => ['gdoy8q3nckuob0i.delivery.mycompany.net', 'ctnktsd0u11p9tm.delivery.mycompany.net']
}
@nonstandard_results = {
'solaris-10-sparc' => ['sol10-10.delivery.mycompany.net', 'sol10-11.delivery.mycompany.net'],
'ubuntu-16.04-power8' => ['power8-ubuntu16.04-6.delivery.mycompany.net']
}
@vmpooler_output = <<~OUT.chomp
- dlgietfmgeegry2.delivery.mycompany.net (centos-7-x86_64)
- gdoy8q3nckuob0i.delivery.mycompany.net (ubuntu-1610-x86_64)
- ctnktsd0u11p9tm.delivery.mycompany.net (ubuntu-1610-x86_64)
OUT
@nonstandard_output = <<~OUT.chomp
- sol10-10.delivery.mycompany.net (solaris-10-sparc)
- sol10-11.delivery.mycompany.net (solaris-10-sparc)
- power8-ubuntu16.04-6.delivery.mycompany.net (ubuntu-16.04-power8)
OUT
end
it 'formats a hostname hash from vmpooler into a list that includes the os' do
expect(Utils.format_host_output(@vmpooler_results)).to eq(@vmpooler_output)
end
it "takes an array of os arguments and returns a formatted hash" do
host_arg = ["centos", "debian=5", "windows=1"]
it 'formats a hostname hash from the nonstandard pooler into a list that includes the os' do
expect(Utils.format_host_output(@nonstandard_results)).to eq(@nonstandard_output)
end
end
describe '#get_service_object' do
it 'assumes vmpooler by default' do
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'
}
@services_config = {
'services' => {
'vm' => {
'url' => 'http://vmpooler.url',
'user' => 'first.last.vmpooler',
'token' => 'vmpooler-token'
},
'ns' => {
'url' => 'http://nspooler.url',
'user' => 'first.last.nspooler',
'token' => 'nspooler-token'
}
}
}
end
it "returns the first service configured under 'services' as the default if available" do
config = @default_config.merge @services_config
options = MockOptions.new({})
expect(Utils.get_service_config(config, options)).to include @services_config['services']['vm']
end
it 'allows selection by configured service key' do
config = @default_config.merge @services_config
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')
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')
expect { Utils.get_service_config(config, options) }.to raise_error ArgumentError
end
it 'prioritizes values passed as command line options over configuration options' do
config = @default_config
options = MockOptions.new(url: 'http://alternate.url', token: 'alternate-token')
expected = config.merge('url' => 'http://alternate.url', 'token' => 'alternate-token')
expect(Utils.get_service_config(config, options)).to include expected
end
end
describe '#generate_os_hash' do
before :each do
@host_hash = { 'centos' => 1, 'debian' => 5, 'windows' => 1 }
end
it 'takes an array of os arguments and returns a formatted hash' do
host_arg = ['centos', 'debian=5', 'windows=1']
expect(Utils.generate_os_hash(host_arg)).to eq @host_hash
end
it "returns an empty hash if there are no arguments provided" do
it 'returns an empty hash if there are no arguments provided' do
host_arg = []
expect(Utils.generate_os_hash(host_arg)).to be_empty
end
end
describe '#prettyprint_hosts' do
let(:host_without_tags) { 'mcpy42eqjxli9g2' }
let(:host_with_tags) { 'aiydvzpg23r415q' }
describe '#print_fqdn_for_host' do
let(:url) { 'http://pooler.example.com' }
let(:host_info_with_tags) do
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
{
host_with_tags => {
"template" => "redhat-7-x86_64",
"lifetime" => 48,
"running" => 7.67,
"tags" => {
"user" => "bob",
"role" => "agent"
'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
allow(service).to receive(:query)
.with(anything, hostname)
.and_return(response_body)
end
subject { Utils.pretty_print_hosts(verbose, service, hostname, print_to_stderr) }
describe 'with vmpooler api v2 service' do
let(:service) { Service.new(MockOptions.new, 'url' => url) }
let(:hostname) { 'mcpy42eqjxli9g2' }
let(:fqdn) { [hostname, 'delivery.puppetlabs.net'].join('.') }
let(:response_body) do
{
hostname => {
'template' => 'ubuntu-1604-x86_64',
'lifetime' => 12,
'running' => 9.66,
'state' => 'running',
'ip' => '127.0.0.1',
'fqdn' => fqdn
}
}
end
let(:default_output) { "- #{fqdn} (running, ubuntu-1604-x86_64, 9.66/12 hours)" }
it 'prints output with host fqdn, template and duration info' do
expect($stdout).to receive(:puts).with(default_output)
subject
end
context 'when tags are supplied' do
let(:hostname) { 'aiydvzpg23r415q' }
let(:response_body) do
{
hostname => {
'template' => 'redhat-7-x86_64',
'lifetime' => 48,
'running' => 7.67,
'state' => 'running',
'tags' => {
'user' => 'bob',
'role' => 'agent'
},
"domain" => "delivery.puppetlabs.net"
'ip' => '127.0.0.1',
'fqdn' => fqdn
}
}
end
let(:host_info_without_tags) do
it 'prints output with host fqdn, template, duration info, and tags' do
output = "- #{fqdn} (running, redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)"
expect($stdout).to receive(:puts).with(output)
subject
end
end
context 'when print_to_stderr option is true' do
let(:print_to_stderr) { true }
it 'outputs to stderr instead of stdout' do
expect($stderr).to receive(:puts).with(default_output)
subject
end
end
end
describe 'with vmpooler api v1 service' do
let(:service) { Service.new(MockOptions.new, 'url' => url) }
let(:hostname) { 'mcpy42eqjxli9g2' }
let(:domain) { 'delivery.mycompany.net' }
let(:fqdn) { [hostname, domain].join('.') }
let(:response_body) do
{
host_without_tags => {
"template" => "ubuntu-1604-x86_64",
"lifetime" => 12,
"running" => 9.66,
"domain" => "delivery.puppetlabs.net"
hostname => {
'template' => 'ubuntu-1604-x86_64',
'lifetime' => 12,
'running' => 9.66,
'state' => 'running',
'ip' => '127.0.0.1',
'domain' => domain
}
}
end
let(:output_with_tags) { "- #{host_with_tags}.delivery.puppetlabs.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)" }
let(:output_without_tags) { "- #{host_without_tags}.delivery.puppetlabs.net (ubuntu-1604-x86_64, 9.66/12 hours)" }
let(:default_output) { "- #{fqdn} (running, ubuntu-1604-x86_64, 9.66/12 hours)" }
it 'prints an output with host fqdn, template and duration info' do
allow(Utils).to receive(:get_vm_info).
with(host_without_tags, false, url).
and_return(host_info_without_tags)
it 'prints output with host fqdn, template and duration info' do
expect($stdout).to receive(:puts).with(default_output)
expect(Utils).to receive(:puts).with("Running VMs:")
expect(Utils).to receive(:puts).with(output_without_tags)
Utils.prettyprint_hosts(host_without_tags, false, url)
subject
end
it 'prints an output with host fqdn, template, duration info, and tags when supplied' do
allow(Utils).to receive(:get_vm_info).
with(host_with_tags, false, url).
and_return(host_info_with_tags)
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
expect(Utils).to receive(:puts).with("Running VMs:")
expect(Utils).to receive(:puts).with(output_with_tags)
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)"
Utils.prettyprint_hosts(host_with_tags, false, url)
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 nonstandard pooler service' do
let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') }
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
let(:default_output) { "- #{hostname} (solaris-11-sparc, 35.89h remaining)" }
it 'prints output with host, template, and time remaining' do
expect($stdout).to receive(:puts).with(default_output)
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}] <allocated>" }
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}] <allocated>" }
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'
})
end
end
end

View file

@ -0,0 +1,39 @@
# frozen_string_literal: true
# All of the interfaces for the different services must be the
# same, otherwise there will be errors when you change the caller
# for the services from services.rb.
#
require_relative '../../lib/vmfloaty/pooler'
require_relative '../../lib/vmfloaty/abs'
require_relative '../../lib/vmfloaty/nonstandard_pooler'
shared_examples 'a vmfloaty service' do
it { is_expected.to respond_to(:delete).with(5).arguments }
it { is_expected.to respond_to(:disk).with(5).arguments }
it { is_expected.to respond_to(:list).with(3).arguments }
it { is_expected.to respond_to(:list_active).with(4).arguments }
it { is_expected.to respond_to(:modify).with(5).arguments }
it { is_expected.to respond_to(:retrieve).with(6).arguments }
it { is_expected.to respond_to(:revert).with(5).arguments }
it { is_expected.to respond_to(:query).with(3).arguments }
it { is_expected.to respond_to(:snapshot).with(4).arguments }
it { is_expected.to respond_to(:status).with(2).arguments }
it { is_expected.to respond_to(:summary).with(2).arguments }
end
describe Pooler do
subject { Pooler }
it_behaves_like 'a vmfloaty service'
end
describe ABS do
subject { ABS }
it_behaves_like 'a vmfloaty service'
end
describe NonstandardPooler do
subject { NonstandardPooler }
it_behaves_like 'a vmfloaty service'
end

View file

@ -1,17 +1,26 @@
# frozen_string_literal: true
$LOAD_PATH.push File.expand_path('lib', __dir__)
require 'vmfloaty/version'
Gem::Specification.new do |s|
s.name = 'vmfloaty'
s.version = '0.7.5'
s.authors = ['Brian Cain']
s.email = ['brian.cain@puppetlabs.com']
s.license = 'Apache'
s.homepage = 'https://github.com/briancain/vmfloaty'
s.version = Vmfloaty::VERSION
s.authors = [
'Brian Cain',
'Puppet'
]
s.email = 'info@puppet.com'
s.license = 'Apache-2.0'
s.homepage = 'https://github.com/puppetlabs/vmfloaty'
s.description = 'A helper tool for vmpooler to help you stay afloat'
s.summary = 'CLI application to interface with vmpooler'
s.executables = ['floaty']
s.files = Dir['LICENSE', 'README.md', 'lib/**/*']
s.files = Dir['LICENSE', 'README.md', 'lib/**/*', 'extras/**/*']
s.test_files = Dir['spec/**/*']
s.require_path = 'lib'
s.add_dependency 'commander', '~> 4.3'
s.add_dependency 'faraday', '~> 0.9'
s.add_dependency 'colorize', '0.8.1'
s.add_dependency 'commander', '>= 4.4.3', '< 4.7.0'
s.add_dependency 'faraday', '~> 1.5', '>= 1.5.1'
end

View file

@ -1,3 +1,8 @@
url: 'http://vmpooler.example.com/api/v1'
user: 'brian'
token: 'token here'
services:
main:
url: 'https://vmpooler.example.net/api/v1'
token: 'tokenstring'
alternate:
url: 'https://vmpooler.example.com/api/v1'
token: 'alternate-tokenstring'