vmfloaty 0.9.2 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19668270f1933ad365a4ee6c6ae0df7328c91dc9dc8500af7e127d7bc93e5f8b
4
- data.tar.gz: c0134595ed849c2d81f769473e2bc7c52604ac405d4f3bd5add34b61456c317c
3
+ metadata.gz: cfd72279e6067194457cfff7e798bffb6c3f7e516a215ab25507836a35918dfa
4
+ data.tar.gz: e5f63b9b99f8969e557cf14993d89063353b2b8d2201e2945204375f4c8599f1
5
5
  SHA512:
6
- metadata.gz: 3225e02bcddf4c2e16dd5f6e26f0daa797bd266ac7078d133ab225e6e317e6a4912ab4d360c96dabd34fccb45d7b79dec9e3b8302fd28d0d8eac9070e9c02134
7
- data.tar.gz: 75f4363eb6339d58bf9750d304c47f32b85420c4dd2171a0405b659050c19fb07356619f917cb877133af3bfca92714b745d34391822a8940601e954cad19f6a
6
+ metadata.gz: 57500a3436d64a3edc4aa8a11bcfc5590a05788268fb7c556d70816a0dede112225298f657a762c8a5eec3b829117f91599e286115237e5e039dfe5554d9d2c2
7
+ data.tar.gz: 288ded1bca5cfe6bff06be880b17264ddd49a10674649a1424515af7a48d646eb0b693123aee0ec353b6bb57424f209ca7cd653e1fd3287831b137593ebfe50b
data/README.md CHANGED
@@ -1,40 +1,64 @@
1
- vmfloaty
2
- ========
3
-
4
- [![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)
5
-
6
- A CLI helper tool for [Puppet Labs vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat.
7
-
8
- <img src="http://i.imgur.com/xGcGwuH.jpg" width=200 height=200>
9
-
10
- This project is still supported by @briancain and @demophoon. Ping either of us if you'd like something merged and released.
1
+ # vmfloaty
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/vmfloaty.svg)](https://badge.fury.io/rb/vmfloaty)
4
+ [![Build Status](https://travis-ci.com/puppetlabs/vmfloaty.svg?branch=master)](https://travis-ci.com/puppetlabs/vmfloaty)
5
+ [![Coverage Status](https://coveralls.io/repos/github/puppetlabs/vmfloaty/badge.svg?branch=master)](https://coveralls.io/github/puppetlabs/vmfloaty?branch=master)
6
+ [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=puppetlabs/vmfloaty)](https://dependabot.com)
7
+
8
+ A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler) to help you stay afloat.
9
+
10
+ ![float image](float.jpg)
11
+
12
+ - [Install](#install)
13
+ - [Usage](#usage)
14
+ - [Example workflow](#example-workflow)
15
+ - [vmfloaty dotfile](#vmfloaty-dotfile)
16
+ - [Basic configuration](#basic-configuration)
17
+ - [Using multiple services](#using-multiple-services)
18
+ - [Using backends besides VMPooler](#using-backends-besides-vmpooler)
19
+ - [Valid config keys](#valid-config-keys)
20
+ - [Tab Completion](#tab-completion)
21
+ - [vmpooler API](#vmpooler-api)
22
+ - [Using the Pooler class](#using-the-pooler-class)
23
+ - [Example Projects](#example-projects)
24
+ - [Special thanks](#special-thanks)
11
25
 
12
26
  ## Install
13
27
 
14
28
  Grab the latest from ruby gems...
15
29
 
16
- ```
17
- $ gem install vmfloaty
18
- ...
19
- ...
20
- $ floaty --help
30
+ ```bash
31
+ gem install vmfloaty
21
32
  ```
22
33
 
23
34
  ## Usage
24
35
 
25
- ```
26
- delete Schedules the deletion of a host or hosts
27
- get Gets a vm or vms based on the os argument
28
- help Display global or [command] help documentation
29
- list Shows a list of available vms from the pooler or vms obtained with a token
30
- modify Modify a vms tags, time to live, and disk space
31
- query Get information about a given vm
32
- revert Reverts a vm to a specified snapshot
33
- snapshot Takes a snapshot of a given vm
34
- ssh Grabs a single vm and sshs into it
35
- status Prints the status of pools in vmpooler
36
- summary Prints a summary of vmpooler
37
- token Retrieves or deletes a token or checks token status
36
+ ```plain
37
+ $ floaty --help
38
+ NAME:
39
+
40
+ floaty
41
+
42
+ DESCRIPTION:
43
+
44
+ A CLI helper tool for Puppet's vmpooler to help you stay afloat
45
+
46
+ COMMANDS:
47
+
48
+ completion Outputs path to completion script
49
+ delete Schedules the deletion of a host or hosts
50
+ get Gets a vm or vms based on the os argument
51
+ help Display global or [command] help documentation
52
+ list Shows a list of available vms from the pooler or vms obtained with a token
53
+ modify Modify a VM's tags, time to live, disk space, or reservation reason
54
+ query Get information about a given vm
55
+ revert Reverts a vm to a specified snapshot
56
+ service Display information about floaty services and their configuration
57
+ snapshot Takes a snapshot of a given vm
58
+ ssh Grabs a single vm and sshs into it
59
+ status Prints the status of pools in the pooler service
60
+ summary Prints a summary of a pooler service
61
+ token Retrieves or deletes a token or checks token status
38
62
 
39
63
  GLOBAL OPTIONS:
40
64
 
@@ -52,7 +76,7 @@ $ floaty --help
52
76
 
53
77
  Grabbing a token for authenticated pooler requests:
54
78
 
55
- ```
79
+ ```bash
56
80
  floaty token get --user username --url https://vmpooler.example.net/api/v1
57
81
  ```
58
82
 
@@ -60,108 +84,54 @@ This command will then ask you to log in. If successful, it will return a token
60
84
 
61
85
  Grabbing vms:
62
86
 
63
- ```
87
+ ```bash
64
88
  floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring --url https://vmpooler.example.net/api/v1
65
89
  ```
66
90
 
67
91
  ### vmfloaty dotfile
68
92
 
69
- If you do not wish to continually specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example:
93
+ 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.
70
94
 
71
95
  #### Basic configuration
72
96
 
97
+ This is the simplest type of configuration where you only need a single service:
98
+
73
99
  ```yaml
74
- # file at /Users/me/.vmfloaty.yml
100
+ # file at ~/.vmfloaty.yml
75
101
  url: 'https://vmpooler.example.net/api/v1'
76
102
  user: 'brian'
77
103
  token: 'tokenstring'
78
104
  ```
79
105
 
80
- Now vmfloaty will use those config files if no flag was specified.
81
-
82
- #### Configuring multiple services
83
-
84
- Most commands allow you to specify a `--service <servicename>` option to allow the use of multiple vmpooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services.
106
+ Run `floaty service examples` to see additional configuration options
85
107
 
86
- To configure multiple services, you can set up your `~/.vmfloaty.yml` config file like this:
108
+ #### Using multiple services
87
109
 
88
- ```yaml
89
- # file at /Users/me/.vmfloaty.yml
90
- user: 'brian'
91
- services:
92
- main:
93
- url: 'https://vmpooler.example.net/api/v1'
94
- token: 'tokenstring'
95
- alternate:
96
- url: 'https://vmpooler.example.com/api/v1'
97
- token: 'alternate-tokenstring'
98
- ```
110
+ 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.
99
111
 
100
112
  - If you run `floaty` without a `--service <name>` option, vmfloaty will use the first configured service by default.
101
- With the config file above, the default would be to use the 'main' vmpooler instance.
102
113
  - If keys are missing for a configured service, vmfloaty will attempt to fall back to the top-level values.
103
- With the config file above, 'brian' will be used as the username for both configured services, since neither specifies a username.
114
+ This makes it so you can specify things like `user` once at the top of your `~/.vmfloaty.yml`.
104
115
 
105
- Examples using the above configuration:
116
+ #### Using backends besides VMPooler
106
117
 
107
- List available vm types from our main vmpooler instance:
108
- ```sh
109
- floaty list --service main
110
- # or, since the first configured service is used by default:
111
- floaty list
112
- ```
113
-
114
- List available vm types from our alternate vmpooler instance:
115
- ```sh
116
- floaty list --service alternate
117
- ```
118
-
119
- #### Using a Nonstandard Pooler service
120
-
121
- vmfloaty is capable of working with Puppet's [nonstandard pooler](https://github.com/puppetlabs/nspooler) in addition to the default vmpooler API. To add a nonstandard pooler service, specify an API `type` value in your service configuration, like this:
122
-
123
- ```yaml
124
- # file at /Users/me/.vmfloaty.yml
125
- user: 'brian'
126
- services:
127
- vm:
128
- url: 'https://vmpooler.example.net/api/v1'
129
- token: 'tokenstring'
130
- ns:
131
- url: 'https://nspooler.example.net/api/v1'
132
- token: 'nspooler-tokenstring'
133
- type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service
134
- abs:
135
- url: 'https://abs.example.net/'
136
- token: 'abs-tokenstring'
137
- type: 'abs' # <-- 'type' is necessary for any non-vmpooler service
138
-
139
- ```
140
-
141
- With this configuration, you could list available OS types from nspooler like this:
142
-
143
- ```sh
144
- floaty list --service ns
145
- ```
118
+ 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.
146
119
 
147
120
  #### Valid config keys
148
121
 
149
122
  Here are the keys that vmfloaty currently supports:
150
123
 
151
- - verbose
152
- + Boolean
153
- - token
154
- + String
155
- - user
156
- + String
157
- - url
158
- + String
159
- - services
160
- + Map
124
+ - verbose (Boolean)
125
+ - token (String)
126
+ - user (String)
127
+ - url (String)
128
+ - services (String)
129
+ - type (String)
130
+ - vmpooler_fallback (String)
161
131
 
162
132
  ### Tab Completion
163
133
 
164
- There is a basic completion script for Bash (and possibly other shells) included with the gem in the [extras/completions](https://github.com/briancain/vmfloaty/blob/master/extras/completions) folder. To activate, that file simply needs to be sourced somehow in your shell profile.
134
+ 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.
165
135
 
166
136
  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:
167
137
 
@@ -175,6 +145,12 @@ If you are running on macOS and use Homebrew's `bash-completion` formula, you ca
175
145
  ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty
176
146
  ```
177
147
 
148
+ There is also tab completion for zsh:
149
+
150
+ ```zsh
151
+ source $(floaty completion --shell zsh)
152
+ ```
153
+
178
154
  ## vmpooler API
179
155
 
180
156
  This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md).
@@ -186,6 +162,10 @@ vmfloaty providers a `Pooler` class that gives users the ability to make request
186
162
  ### Example Projects
187
163
 
188
164
  - [John McCabe: vmpooler-bitbar](https://github.com/johnmccabe/vmpooler-bitbar/)
189
- + vmpooler status and management in your menubar with bitbar
165
+ - vmpooler status and management in your menubar with bitbar
190
166
  - [Brian Cain: vagrant-vmpooler](https://github.com/briancain/vagrant-vmpooler)
191
- + Use Vagrant to manage your vmpooler instances
167
+ - Use Vagrant to manage your vmpooler instances
168
+
169
+ ## Special thanks
170
+
171
+ 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.
@@ -2,29 +2,37 @@
2
2
 
3
3
  _vmfloaty()
4
4
  {
5
- local cur prev subcommands template_subcommands hostname_subcommands
5
+ local cur prev commands template_arg_commands hostname_arg_commands service_subcommands
6
+
6
7
  COMPREPLY=()
7
8
  cur="${COMP_WORDS[COMP_CWORD]}"
8
9
  prev="${COMP_WORDS[COMP_CWORD-1]}"
9
10
 
10
- subcommands="delete get help list modify query revert snapshot ssh status summary token"
11
- template_subcommands="get ssh"
12
- hostname_subcommands="delete modify query revert snapshot"
11
+ commands="delete get help list modify query revert service snapshot ssh status summary token"
12
+ template_arg_commands="get ssh"
13
+ hostname_arg_commands="delete modify query revert snapshot"
14
+ service_subcommands="types examples"
13
15
 
14
16
  if [[ $cur == -* ]] ; then
15
17
  # TODO: option completion
16
18
  COMPREPLY=()
17
- elif [[ $template_subcommands =~ (^| )$prev($| ) ]] ; then
19
+ elif [[ $template_arg_commands =~ (^| )$prev($| ) ]] ; then
18
20
  if [[ -z "$_vmfloaty_avail_templates" ]] ; then
21
+ # TODO: need a --hostnameonly equivalent here because the section headers of
22
+ # `floaty list` are adding some spurious entries (including files in current
23
+ # directory because part of the headers is `**` which is getting expanded)
19
24
  _vmfloaty_avail_templates=$(floaty list 2>/dev/null)
20
25
  fi
21
26
 
22
27
  COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") )
23
- elif [[ $hostname_subcommands =~ (^| )$prev($| ) ]] ; then
24
- _vmfloaty_active_hostnames=$(floaty list --active 2>/dev/null | grep '^-' | cut -d' ' -f2)
28
+ elif [[ $hostname_arg_commands =~ (^| )$prev($| ) ]] ; then
29
+ _vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null)
25
30
  COMPREPLY=( $(compgen -W "${_vmfloaty_active_hostnames}" -- "${cur}") )
26
- else
27
- COMPREPLY=( $(compgen -W "${subcommands}" -- "${cur}") )
31
+ elif [[ "service" == $prev ]] ; then
32
+ COMPREPLY=( $(compgen -W "${service_subcommands}" -- "${cur}") )
33
+ elif [[ $1 == $prev ]] ; then
34
+ # only show top level commands we are at root
35
+ COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
28
36
  fi
29
37
  }
30
38
  complete -F _vmfloaty floaty
@@ -0,0 +1,43 @@
1
+ _floaty()
2
+ {
3
+ local line commands template_arg_commands hostname_arg_commands service_subcommands
4
+
5
+ commands="delete get help list modify query revert service snapshot ssh status summary token"
6
+
7
+ template_arg_commands=("get" "ssh")
8
+ hostname_arg_commands=("delete" "modify" "query" "revert" "snapshot")
9
+ service_subcommands=("types" "examples")
10
+
11
+ _arguments -C \
12
+ "1: :(${commands})" \
13
+ "*::arg:->args"
14
+
15
+ if ((template_arg_commands[(Ie)$line[1]])); then
16
+ _floaty_template_sub
17
+ elif ((hostname_arg_commands[(Ie)$line[1]])); then
18
+ _floaty_hostname_sub
19
+ elif [[ "service" == $line[1] ]]; then
20
+ _arguments "1: :(${service_subcommands})"
21
+ fi
22
+ }
23
+
24
+ _floaty_template_sub()
25
+ {
26
+ if [[ -z "$_vmfloaty_avail_templates" ]] ; then
27
+ # TODO: need a --hostnameonly equivalent here because the section headers of
28
+ # `floaty list` are adding some spurious entries (including files in current
29
+ # directory because part of the headers is `**` which is getting expanded)
30
+ _vmfloaty_avail_templates=$(floaty list 2>/dev/null)
31
+ fi
32
+
33
+ _arguments "1: :(${_vmfloaty_avail_templates})"
34
+ }
35
+
36
+ _floaty_hostname_sub()
37
+ {
38
+ _vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null)
39
+
40
+ _arguments "1: :(${_vmfloaty_active_hostnames})"
41
+ }
42
+
43
+ compdef _floaty floaty
@@ -13,13 +13,14 @@ require 'vmfloaty/conf'
13
13
  require 'vmfloaty/utils'
14
14
  require 'vmfloaty/service'
15
15
  require 'vmfloaty/ssh'
16
+ require 'vmfloaty/logger'
16
17
 
17
18
  class Vmfloaty
18
19
  include Commander::Methods
19
20
 
20
21
  def run # rubocop:disable Metrics/AbcSize
21
22
  program :version, Vmfloaty::VERSION
22
- program :description, 'A CLI helper tool for Puppet Labs VM poolers to help you stay afloat'
23
+ 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."
23
24
 
24
25
  config = Conf.read_config
25
26
 
@@ -37,6 +38,7 @@ class Vmfloaty
37
38
  c.option '--notoken', 'Makes a request without a token'
38
39
  c.option '--force', 'Forces vmfloaty to get requested vms'
39
40
  c.option '--json', 'Prints retrieved vms in JSON format'
41
+ c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID'
40
42
  c.action do |args, options|
41
43
  verbose = options.verbose || config['verbose']
42
44
  service = Service.new(options, config)
@@ -44,7 +46,7 @@ class Vmfloaty
44
46
  force = options.force
45
47
 
46
48
  if args.empty?
47
- STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
49
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
48
50
  exit 1
49
51
  end
50
52
 
@@ -53,19 +55,23 @@ class Vmfloaty
53
55
  max_pool_request = 5
54
56
  large_pool_requests = os_types.select { |_, v| v > max_pool_request }
55
57
  if !large_pool_requests.empty? && !force
56
- STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag."
57
- STDERR.puts 'Try again with `floaty get --force`'
58
+ FloatyLogger.error "Requesting vms over #{max_pool_request} requires a --force flag."
59
+ FloatyLogger.error 'Try again with `floaty get --force`'
58
60
  exit 1
59
61
  end
60
62
 
61
63
  if os_types.empty?
62
- STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
64
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
63
65
  exit 1
64
66
  end
65
67
 
66
- response = service.retrieve(verbose, os_types, use_token)
68
+ response = service.retrieve(verbose, os_types, use_token, options.ondemand)
69
+ request_id = response['request_id'] if options.ondemand
70
+ response = service.wait_for_request(verbose, request_id) if options.ondemand
71
+
67
72
  hosts = Utils.standardize_hostnames(response)
68
- if options.json
73
+
74
+ if options.json || options.ondemand
69
75
  puts JSON.pretty_generate(hosts)
70
76
  else
71
77
  puts Utils.format_host_output(hosts)
@@ -81,8 +87,11 @@ class Vmfloaty
81
87
  c.option '--verbose', 'Enables verbose output'
82
88
  c.option '--service STRING', String, 'Configured pooler service name'
83
89
  c.option '--active', 'Prints information about active vms for a given token'
90
+ c.option '--json', 'Prints information as JSON'
91
+ c.option '--hostnameonly', 'When listing active vms, prints only hostnames, one per line'
84
92
  c.option '--token STRING', String, 'Token for pooler service'
85
93
  c.option '--url STRING', String, 'URL of pooler service'
94
+ c.option '--user STRING', String, 'User to authenticate with'
86
95
  c.action do |args, options|
87
96
  verbose = options.verbose || config['verbose']
88
97
 
@@ -91,13 +100,30 @@ class Vmfloaty
91
100
 
92
101
  if options.active
93
102
  # list active vms
94
- running_vms = service.list_active(verbose)
103
+ if service.type == "ABS"
104
+ # this is actually job_ids
105
+ running_vms = service.list_active_job_ids(verbose, service.url, service.user)
106
+ else
107
+ running_vms = service.list_active(verbose)
108
+ end
95
109
  host = URI.parse(service.url).host
96
110
  if running_vms.empty?
97
- puts "You have no running VMs on #{host}"
111
+ if options.json
112
+ puts {}.to_json
113
+ else
114
+ FloatyLogger.info "You have no running VMs on #{host}"
115
+ end
98
116
  else
99
- puts "Your VMs on #{host}:"
100
- Utils.pretty_print_hosts(verbose, service, running_vms)
117
+ if options.json
118
+ puts Utils.get_host_data(verbose, service, running_vms).to_json
119
+ elsif options.hostnameonly
120
+ Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data|
121
+ Utils.print_fqdn_for_host(service, hostname, host_data)
122
+ end
123
+ else
124
+ puts "Your VMs on #{host}:"
125
+ Utils.pretty_print_hosts(verbose, service, running_vms)
126
+ end
101
127
  end
102
128
  else
103
129
  # list available vms from pooler
@@ -110,7 +136,7 @@ class Vmfloaty
110
136
  command :query do |c|
111
137
  c.syntax = 'floaty query hostname [options]'
112
138
  c.summary = 'Get information about a given vm'
113
- c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm.'
139
+ 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'
114
140
  c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com'
115
141
  c.option '--verbose', 'Enables verbose output'
116
142
  c.option '--service STRING', String, 'Configured pooler service name'
@@ -146,10 +172,15 @@ class Vmfloaty
146
172
  modify_all = options.all
147
173
 
148
174
  if hostname.nil? && !modify_all
149
- STDERR.puts 'ERROR: Provide a hostname or specify --all.'
175
+ FloatyLogger.error 'ERROR: Provide a hostname or specify --all.'
150
176
  exit 1
151
177
  end
152
- running_vms = modify_all ? service.list_active(verbose) : hostname.split(',')
178
+ running_vms =
179
+ if modify_all
180
+ service.list_active(verbose)
181
+ else
182
+ hostname.split(',')
183
+ end
153
184
 
154
185
  tags = options.tags ? JSON.parse(options.tags) : nil
155
186
  modify_hash = {
@@ -167,13 +198,13 @@ class Vmfloaty
167
198
  begin
168
199
  modified_hash[vm] = service.modify(verbose, vm, modify_hash)
169
200
  rescue ModifyError => e
170
- STDERR.puts e
201
+ FloatyLogger.error e
171
202
  ok = false
172
203
  end
173
204
  end
174
205
  if ok
175
206
  if modify_all
176
- puts 'Successfully modified all VMs.'
207
+ puts "Successfully modified all #{running_vms.count} VMs."
177
208
  else
178
209
  puts "Successfully modified VM #{hostname}."
179
210
  end
@@ -194,8 +225,10 @@ class Vmfloaty
194
225
  c.option '--service STRING', String, 'Configured pooler service name'
195
226
  c.option '--all', 'Deletes all vms acquired by a token'
196
227
  c.option '-f', 'Does not prompt user when deleting all vms'
228
+ c.option '--json', 'Outputs hosts scheduled for deletion as JSON'
197
229
  c.option '--token STRING', String, 'Token for pooler service'
198
230
  c.option '--url STRING', String, 'URL of pooler service'
231
+ c.option '--user STRING', String, 'User to authenticate with'
199
232
  c.action do |args, options|
200
233
  verbose = options.verbose || config['verbose']
201
234
  service = Service.new(options, config)
@@ -207,15 +240,25 @@ class Vmfloaty
207
240
  successes = []
208
241
 
209
242
  if delete_all
210
- running_vms = service.list_active(verbose)
243
+ if service.type == "ABS"
244
+ # this is actually job_ids
245
+ running_vms = service.list_active_job_ids(verbose, service.url, service.user)
246
+ else
247
+ running_vms = service.list_active(verbose)
248
+ end
211
249
  if running_vms.empty?
212
- STDERR.puts 'You have no running VMs.'
250
+ if options.json
251
+ puts {}.to_json
252
+ else
253
+ FloatyLogger.info "You have no running VMs."
254
+ end
213
255
  else
214
- Utils.pretty_print_hosts(verbose, service, running_vms)
215
- # Confirm deletion
216
- puts
217
256
  confirmed = true
218
- confirmed = agree('Delete all these VMs? [y/N]') unless force
257
+ unless force
258
+ Utils.pretty_print_hosts(verbose, service, running_vms, true)
259
+ # Confirm deletion
260
+ confirmed = agree('Delete all these VMs? [y/N]')
261
+ end
219
262
  if confirmed
220
263
  response = service.delete(verbose, running_vms)
221
264
  response.each do |hostname, result|
@@ -238,23 +281,28 @@ class Vmfloaty
238
281
  end
239
282
  end
240
283
  else
241
- STDERR.puts 'You did not provide any hosts to delete'
284
+ FloatyLogger.info 'You did not provide any hosts to delete'
242
285
  exit 1
243
286
  end
244
287
 
245
288
  unless failures.empty?
246
- STDERR.puts 'Unable to delete the following VMs:'
289
+ FloatyLogger.info 'Unable to delete the following VMs:'
247
290
  failures.each do |hostname|
248
- STDERR.puts "- #{hostname}"
291
+ FloatyLogger.info "- #{hostname}"
249
292
  end
250
- STDERR.puts 'Check `floaty list --active`; Do you need to specify a different service?'
293
+ FloatyLogger.info 'Check `floaty list --active`; Do you need to specify a different service?'
251
294
  end
252
295
 
253
296
  unless successes.empty?
254
- puts unless failures.empty?
255
- puts 'Scheduled the following VMs for deletion:'
256
- successes.each do |hostname|
257
- puts "- #{hostname}"
297
+ if options.json
298
+ puts successes.to_json
299
+ else
300
+ puts 'Scheduled the following VMs for deletion:'
301
+ output = ''
302
+ successes.each do |hostname|
303
+ output += "- #{hostname}\n"
304
+ end
305
+ puts output
258
306
  end
259
307
  end
260
308
 
@@ -279,7 +327,7 @@ class Vmfloaty
279
327
  begin
280
328
  snapshot_req = service.snapshot(verbose, hostname)
281
329
  rescue TokenError, ModifyError => e
282
- STDERR.puts e
330
+ FloatyLogger.error e
283
331
  exit 1
284
332
  end
285
333
 
@@ -304,12 +352,12 @@ class Vmfloaty
304
352
  hostname = args[0]
305
353
  snapshot_sha = args[1] || options.snapshot
306
354
 
307
- STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
355
+ FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
308
356
 
309
357
  begin
310
358
  revert_req = service.revert(verbose, hostname, snapshot_sha)
311
359
  rescue TokenError, ModifyError => e
312
- STDERR.puts e
360
+ FloatyLogger.error e
313
361
  exit 1
314
362
  end
315
363
 
@@ -384,14 +432,14 @@ class Vmfloaty
384
432
  status = service.token_status(verbose, token_value)
385
433
  puts status
386
434
  when nil
387
- STDERR.puts 'No action provided'
435
+ FloatyLogger.error 'No action provided'
388
436
  exit 1
389
437
  else
390
- STDERR.puts "Unknown action: #{action}"
438
+ FloatyLogger.error "Unknown action: #{action}"
391
439
  exit 1
392
440
  end
393
441
  rescue TokenError => e
394
- STDERR.puts e
442
+ FloatyLogger.error e
395
443
  exit 1
396
444
  end
397
445
  exit 0
@@ -415,13 +463,13 @@ class Vmfloaty
415
463
  use_token = !options.notoken
416
464
 
417
465
  if args.empty?
418
- STDERR.puts 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
466
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
419
467
  exit 1
420
468
  end
421
469
 
422
470
  host_os = args.first
423
471
 
424
- STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
472
+ FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
425
473
 
426
474
  service.ssh(verbose, host_os, use_token)
427
475
  exit 0
@@ -448,7 +496,71 @@ class Vmfloaty
448
496
  puts completion_file
449
497
  exit 0
450
498
  else
451
- STDERR.puts "Could not find completion file for '#{shell}': No such file #{completion_file}"
499
+ FloatyLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}"
500
+ exit 1
501
+ end
502
+ end
503
+ end
504
+
505
+ command :service do |c|
506
+ c.syntax = 'floaty service <types examples>'
507
+ c.summary = 'Display information about floaty services and their configuration'
508
+ c.description = 'Display information about floaty services to aid in setting up a configuration file.'
509
+ c.example 'Print a list of the valid service types', 'floaty service types'
510
+ c.example 'Print a sample config file with multiple services', 'floaty service examples'
511
+ c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod'
512
+ c.action do |args, options|
513
+ action = args.first
514
+
515
+ example_config = Utils.strip_heredoc(<<-CONFIG)
516
+ # Sample ~/.vmfloaty.yml with just vmpooler
517
+ user: 'jdoe'
518
+ url: 'https://vmpooler.example.net'
519
+ token: '456def789'
520
+
521
+ # Sample ~/.vmfloaty.yml with multiple services
522
+ # Note: when the --service is not specified on the command line,
523
+ # the first service listed here is selected automatically
524
+ user: 'jdoe'
525
+ services:
526
+ abs-prod:
527
+ type: 'abs'
528
+ url: 'https://abs.example.net/api/v2'
529
+ token: '123abc456'
530
+ vmpooler_fallback: 'vmpooler-prod'
531
+ nspooler-prod:
532
+ type: 'nspooler'
533
+ url: 'https://nspooler.example.net'
534
+ token: '789ghi012'
535
+ vmpooler-dev:
536
+ type: 'vmpooler'
537
+ url: 'https://vmpooler-dev.example.net'
538
+ token: '987dsa654'
539
+ vmpooler-prod:
540
+ type: 'vmpooler'
541
+ url: 'https://vmpooler.example.net'
542
+ token: '456def789'
543
+
544
+ CONFIG
545
+
546
+ types_output = Utils.strip_heredoc(<<-TYPES)
547
+ The values on the left below can be used in ~/.vmfloaty.yml as the value of type:
548
+
549
+ abs: Puppet's Always Be Scheduling
550
+ nspooler: Puppet's Non-standard Pooler, aka NSPooler
551
+ vmpooler: Puppet's VMPooler
552
+ TYPES
553
+
554
+ case action
555
+ when 'examples'
556
+ FloatyLogger.info example_config
557
+ when 'types'
558
+ FloatyLogger.info types_output
559
+ when nil
560
+ FloatyLogger.error 'No action provided'
561
+ exit 1
562
+ else
563
+ FloatyLogger.error "Unknown action: #{action}"
452
564
  exit 1
453
565
  end
454
566
  end