vmfloaty 0.10.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7789275b2b0b2a9a85ccf0c9c3820dd4bffd882b1567d2c8ed739eb937eab32
4
- data.tar.gz: cadb2bb55534f79a7fb3c6d06136b2993531958a9ffc269203bfcdeae8ee8361
3
+ metadata.gz: d229737ed9cb959ec725227d7c344ad56c1af7fcd7a53a59502fdb5bf7c0c696
4
+ data.tar.gz: 4625d46bc08dc61e806beff43237adac120d509ae704c437b47d56a4ef5413bf
5
5
  SHA512:
6
- metadata.gz: 5ebc7b72f2633318c51f29fefc26cd234d7666b731907ba27491c8592a3a068e3f0e25df2ce4c9cdbf05f404a6110ac6f4112250526473a25f771ed464b08a87
7
- data.tar.gz: 6a12342fde08a069f75ed3fa9fb6918a1f295622129f5685405b941196515c08b07c6125b1736904271ee791342412a28cd63ac5189e11611969f5dd192fbebb
6
+ metadata.gz: 8763f1c3849bfa0ab7ad2f45cae9737ab16c4f96c7aa9ff9545126979bc7ab611cc40db1c5ace88d812a1dc7004eafa8b27210df92cbe316aff07480db9fe80a
7
+ data.tar.gz: eb5691d5fc84dc667abb0609c6ed9ce1222838e07cc3a5818c5d7294c888e869d28b8fd89300787e4691cfbf691b12356d01c2528d6c2235d832e7245b220dc3
data/README.md CHANGED
@@ -14,9 +14,8 @@ A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler
14
14
  - [Example workflow](#example-workflow)
15
15
  - [vmfloaty dotfile](#vmfloaty-dotfile)
16
16
  - [Basic configuration](#basic-configuration)
17
- - [Default to Puppet's ABS instead of vmpooler](#default-to-puppets-abs-instead-of-vmpooler)
18
- - [Configuring multiple services](#configuring-multiple-services)
19
- - [Using a Nonstandard Pooler service](#using-a-nonstandard-pooler-service)
17
+ - [Using multiple services](#using-multiple-services)
18
+ - [Using backends besides VMPooler](#using-backends-besides-vmpooler)
20
19
  - [Valid config keys](#valid-config-keys)
21
20
  - [Tab Completion](#tab-completion)
22
21
  - [vmpooler API](#vmpooler-api)
@@ -54,6 +53,7 @@ $ floaty --help
54
53
  modify Modify a VM's tags, time to live, disk space, or reservation reason
55
54
  query Get information about a given vm
56
55
  revert Reverts a vm to a specified snapshot
56
+ service Display information about floaty services and their configuration
57
57
  snapshot Takes a snapshot of a given vm
58
58
  ssh Grabs a single vm and sshs into it
59
59
  status Prints the status of pools in the pooler service
@@ -90,95 +90,32 @@ floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring
90
90
 
91
91
  ### vmfloaty dotfile
92
92
 
93
- 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.
94
94
 
95
95
  #### Basic configuration
96
96
 
97
- ```yaml
98
- # file at ~/.vmfloaty.yml
99
- url: 'https://vmpooler.example.net/api/v1'
100
- user: 'brian'
101
- token: 'tokenstring'
102
- ```
103
-
104
- Now vmfloaty will use those config files if no flag was specified.
105
-
106
- #### Default to Puppet's ABS instead of vmpooler
97
+ This is the simplest type of configuration where you only need a single service:
107
98
 
108
99
  ```yaml
109
100
  # file at ~/.vmfloaty.yml
110
- url: 'https://abs.example.net'
101
+ url: 'https://vmpooler.example.net/api/v1'
111
102
  user: 'brian'
112
103
  token: 'tokenstring'
113
- type: 'abs'
114
104
  ```
115
105
 
116
- #### Configuring multiple services
106
+ Run `floaty service examples` to see additional configuration options
117
107
 
118
- 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.
108
+ #### Using multiple services
119
109
 
120
- To configure multiple services, you can set up your `~/.vmfloaty.yml` config file like this:
121
-
122
- ```yaml
123
- # file at /Users/me/.vmfloaty.yml
124
- user: 'brian'
125
- services:
126
- main:
127
- url: 'https://vmpooler.example.net/api/v1'
128
- token: 'tokenstring'
129
- alternate:
130
- url: 'https://vmpooler.example.com/api/v1'
131
- token: 'alternate-tokenstring'
132
- ```
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.
133
111
 
134
112
  - If you run `floaty` without a `--service <name>` option, vmfloaty will use the first configured service by default.
135
- With the config file above, the default would be to use the 'main' vmpooler instance.
136
113
  - If keys are missing for a configured service, vmfloaty will attempt to fall back to the top-level values.
137
- With the config file above, 'brian' will be used as the username for both configured services, since neither specifies a username.
138
-
139
- Examples using the above configuration:
140
-
141
- List available vm types from our main vmpooler instance:
142
-
143
- ```bash
144
- floaty list --service main
145
- # or, since the first configured service is used by default:
146
- floaty list
147
- ```
148
-
149
- List available vm types from our alternate vmpooler instance:
150
-
151
- ```bash
152
- floaty list --service alternate
153
- ```
114
+ This makes it so you can specify things like `user` once at the top of your `~/.vmfloaty.yml`.
154
115
 
155
- #### Using a Nonstandard Pooler service
116
+ #### Using backends besides VMPooler
156
117
 
157
- 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:
158
-
159
- ```yaml
160
- # file at /Users/me/.vmfloaty.yml
161
- user: 'brian'
162
- services:
163
- vm:
164
- url: 'https://vmpooler.example.net/api/v1'
165
- token: 'tokenstring'
166
- ns:
167
- url: 'https://nspooler.example.net/api/v1'
168
- token: 'nspooler-tokenstring'
169
- type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service
170
- abs:
171
- url: 'https://abs.example.net/'
172
- token: 'abs-tokenstring'
173
- type: 'abs' # <-- 'type' is necessary for any non-vmpooler service
174
-
175
- ```
176
-
177
- With this configuration, you could list available OS types from nspooler like this:
178
-
179
- ```bash
180
- floaty list --service ns
181
- ```
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.
182
119
 
183
120
  #### Valid config keys
184
121
 
@@ -190,6 +127,7 @@ Here are the keys that vmfloaty currently supports:
190
127
  - url (String)
191
128
  - services (String)
192
129
  - type (String)
130
+ - vmpooler_fallback (String)
193
131
 
194
132
  ### Tab Completion
195
133
 
@@ -207,6 +145,12 @@ If you are running on macOS and use Homebrew's `bash-completion` formula, you ca
207
145
  ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty
208
146
  ```
209
147
 
148
+ There is also tab completion for zsh:
149
+
150
+ ```zsh
151
+ source $(floaty completion --shell zsh)
152
+ ```
153
+
210
154
  ## vmpooler API
211
155
 
212
156
  This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md).
@@ -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
data/lib/vmfloaty.rb CHANGED
@@ -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's vmpooler 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
 
@@ -38,33 +39,38 @@ class Vmfloaty
38
39
  c.option '--force', 'Forces vmfloaty to get requested vms'
39
40
  c.option '--json', 'Prints retrieved vms in JSON format'
40
41
  c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID'
42
+ c.option '--continue STRING', String, 'resume polling ABS for job_id, for use when the cli was interrupted'
43
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
41
44
  c.action do |args, options|
42
45
  verbose = options.verbose || config['verbose']
46
+ if options.loglevel
47
+ FloatyLogger.setlevel = options.loglevel
48
+ end
43
49
  service = Service.new(options, config)
44
50
  use_token = !options.notoken
45
51
  force = options.force
46
52
 
47
53
  if args.empty?
48
- STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
54
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
49
55
  exit 1
50
56
  end
51
57
 
52
58
  os_types = Utils.generate_os_hash(args)
53
59
 
54
- max_pool_request = 5
55
- large_pool_requests = os_types.select { |_, v| v > max_pool_request }
56
- if !large_pool_requests.empty? && !force
57
- STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag."
58
- STDERR.puts 'Try again with `floaty get --force`'
60
+ if os_types.empty?
61
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
59
62
  exit 1
60
63
  end
61
64
 
62
- if os_types.empty?
63
- STDERR.puts 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
65
+ max_pool_request = 5
66
+ large_pool_requests = os_types.select { |_, v| v > max_pool_request }
67
+ if !large_pool_requests.empty? && !force
68
+ FloatyLogger.error "Requesting vms over #{max_pool_request} requires a --force flag."
69
+ FloatyLogger.error 'Try again with `floaty get --force`'
64
70
  exit 1
65
71
  end
66
72
 
67
- response = service.retrieve(verbose, os_types, use_token, options.ondemand)
73
+ response = service.retrieve(verbose, os_types, use_token, options.ondemand, options.continue)
68
74
  request_id = response['request_id'] if options.ondemand
69
75
  response = service.wait_for_request(verbose, request_id) if options.ondemand
70
76
 
@@ -86,23 +92,47 @@ class Vmfloaty
86
92
  c.option '--verbose', 'Enables verbose output'
87
93
  c.option '--service STRING', String, 'Configured pooler service name'
88
94
  c.option '--active', 'Prints information about active vms for a given token'
95
+ c.option '--json', 'Prints information as JSON'
96
+ c.option '--hostnameonly', 'When listing active vms, prints only hostnames, one per line'
89
97
  c.option '--token STRING', String, 'Token for pooler service'
90
98
  c.option '--url STRING', String, 'URL of pooler service'
99
+ c.option '--user STRING', String, 'User to authenticate with'
100
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
91
101
  c.action do |args, options|
92
102
  verbose = options.verbose || config['verbose']
103
+ if options.loglevel
104
+ FloatyLogger.setlevel = options.loglevel
105
+ end
93
106
 
94
107
  service = Service.new(options, config)
95
108
  filter = args[0]
96
109
 
97
110
  if options.active
98
111
  # list active vms
99
- running_vms = service.list_active(verbose)
112
+ if service.type == "ABS"
113
+ # this is actually job_ids
114
+ running_vms = service.list_active_job_ids(verbose, service.url, service.user)
115
+ else
116
+ running_vms = service.list_active(verbose)
117
+ end
100
118
  host = URI.parse(service.url).host
101
119
  if running_vms.empty?
102
- puts "You have no running VMs on #{host}"
120
+ if options.json
121
+ puts {}.to_json
122
+ else
123
+ FloatyLogger.info "You have no running VMs on #{host}"
124
+ end
103
125
  else
104
- puts "Your VMs on #{host}:"
105
- Utils.pretty_print_hosts(verbose, service, running_vms)
126
+ if options.json
127
+ puts Utils.get_host_data(verbose, service, running_vms).to_json
128
+ elsif options.hostnameonly
129
+ Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data|
130
+ Utils.print_fqdn_for_host(service, hostname, host_data)
131
+ end
132
+ else
133
+ puts "Your VMs on #{host}:"
134
+ Utils.pretty_print_hosts(verbose, service, running_vms)
135
+ end
106
136
  end
107
137
  else
108
138
  # list available vms from pooler
@@ -115,7 +145,7 @@ class Vmfloaty
115
145
  command :query do |c|
116
146
  c.syntax = 'floaty query hostname [options]'
117
147
  c.summary = 'Get information about a given vm'
118
- c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm.'
148
+ 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'
119
149
  c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com'
120
150
  c.option '--verbose', 'Enables verbose output'
121
151
  c.option '--service STRING', String, 'Configured pooler service name'
@@ -151,10 +181,15 @@ class Vmfloaty
151
181
  modify_all = options.all
152
182
 
153
183
  if hostname.nil? && !modify_all
154
- STDERR.puts 'ERROR: Provide a hostname or specify --all.'
184
+ FloatyLogger.error 'ERROR: Provide a hostname or specify --all.'
155
185
  exit 1
156
186
  end
157
- running_vms = modify_all ? service.list_active(verbose) : hostname.split(',')
187
+ running_vms =
188
+ if modify_all
189
+ service.list_active(verbose)
190
+ else
191
+ hostname.split(',')
192
+ end
158
193
 
159
194
  tags = options.tags ? JSON.parse(options.tags) : nil
160
195
  modify_hash = {
@@ -172,13 +207,13 @@ class Vmfloaty
172
207
  begin
173
208
  modified_hash[vm] = service.modify(verbose, vm, modify_hash)
174
209
  rescue ModifyError => e
175
- STDERR.puts e
210
+ FloatyLogger.error e
176
211
  ok = false
177
212
  end
178
213
  end
179
214
  if ok
180
215
  if modify_all
181
- puts 'Successfully modified all VMs.'
216
+ puts "Successfully modified all #{running_vms.count} VMs."
182
217
  else
183
218
  puts "Successfully modified VM #{hostname}."
184
219
  end
@@ -199,10 +234,17 @@ class Vmfloaty
199
234
  c.option '--service STRING', String, 'Configured pooler service name'
200
235
  c.option '--all', 'Deletes all vms acquired by a token'
201
236
  c.option '-f', 'Does not prompt user when deleting all vms'
237
+ c.option '--json', 'Outputs hosts scheduled for deletion as JSON'
202
238
  c.option '--token STRING', String, 'Token for pooler service'
203
239
  c.option '--url STRING', String, 'URL of pooler service'
240
+ c.option '--user STRING', String, 'User to authenticate with'
241
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
204
242
  c.action do |args, options|
205
243
  verbose = options.verbose || config['verbose']
244
+ if options.loglevel
245
+ FloatyLogger.setlevel = options.loglevel
246
+ end
247
+
206
248
  service = Service.new(options, config)
207
249
  hostnames = args[0]
208
250
  delete_all = options.all
@@ -212,15 +254,25 @@ class Vmfloaty
212
254
  successes = []
213
255
 
214
256
  if delete_all
215
- running_vms = service.list_active(verbose)
257
+ if service.type == "ABS"
258
+ # this is actually job_ids
259
+ running_vms = service.list_active_job_ids(verbose, service.url, service.user)
260
+ else
261
+ running_vms = service.list_active(verbose)
262
+ end
216
263
  if running_vms.empty?
217
- STDERR.puts 'You have no running VMs.'
264
+ if options.json
265
+ puts {}.to_json
266
+ else
267
+ FloatyLogger.info "You have no running VMs."
268
+ end
218
269
  else
219
- Utils.pretty_print_hosts(verbose, service, running_vms)
220
- # Confirm deletion
221
- puts
222
270
  confirmed = true
223
- confirmed = agree('Delete all these VMs? [y/N]') unless force
271
+ unless force
272
+ Utils.pretty_print_hosts(verbose, service, running_vms, true)
273
+ # Confirm deletion
274
+ confirmed = agree('Delete all these VMs? [y/N]')
275
+ end
224
276
  if confirmed
225
277
  response = service.delete(verbose, running_vms)
226
278
  response.each do |hostname, result|
@@ -243,23 +295,28 @@ class Vmfloaty
243
295
  end
244
296
  end
245
297
  else
246
- STDERR.puts 'You did not provide any hosts to delete'
298
+ FloatyLogger.info 'You did not provide any hosts to delete'
247
299
  exit 1
248
300
  end
249
301
 
250
302
  unless failures.empty?
251
- STDERR.puts 'Unable to delete the following VMs:'
303
+ FloatyLogger.info 'Unable to delete the following VMs:'
252
304
  failures.each do |hostname|
253
- STDERR.puts "- #{hostname}"
305
+ FloatyLogger.info "- #{hostname}"
254
306
  end
255
- STDERR.puts 'Check `floaty list --active`; Do you need to specify a different service?'
307
+ FloatyLogger.info 'Check `floaty list --active`; Do you need to specify a different service?'
256
308
  end
257
309
 
258
310
  unless successes.empty?
259
- puts unless failures.empty?
260
- puts 'Scheduled the following VMs for deletion:'
261
- successes.each do |hostname|
262
- puts "- #{hostname}"
311
+ if options.json
312
+ puts successes.to_json
313
+ else
314
+ puts 'Scheduled the following VMs for deletion:'
315
+ output = ''
316
+ successes.each do |hostname|
317
+ output += "- #{hostname}\n"
318
+ end
319
+ puts output
263
320
  end
264
321
  end
265
322
 
@@ -284,7 +341,7 @@ class Vmfloaty
284
341
  begin
285
342
  snapshot_req = service.snapshot(verbose, hostname)
286
343
  rescue TokenError, ModifyError => e
287
- STDERR.puts e
344
+ FloatyLogger.error e
288
345
  exit 1
289
346
  end
290
347
 
@@ -309,12 +366,12 @@ class Vmfloaty
309
366
  hostname = args[0]
310
367
  snapshot_sha = args[1] || options.snapshot
311
368
 
312
- STDERR.puts "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
369
+ FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
313
370
 
314
371
  begin
315
372
  revert_req = service.revert(verbose, hostname, snapshot_sha)
316
373
  rescue TokenError, ModifyError => e
317
- STDERR.puts e
374
+ FloatyLogger.error e
318
375
  exit 1
319
376
  end
320
377
 
@@ -331,8 +388,12 @@ class Vmfloaty
331
388
  c.option '--service STRING', String, 'Configured pooler service name'
332
389
  c.option '--url STRING', String, 'URL of pooler service'
333
390
  c.option '--json', 'Prints status in JSON format'
391
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
334
392
  c.action do |_, options|
335
393
  verbose = options.verbose || config['verbose']
394
+ if options.loglevel
395
+ FloatyLogger.setlevel = options.loglevel
396
+ end
336
397
  service = Service.new(options, config)
337
398
  if options.json
338
399
  pp service.status(verbose)
@@ -389,14 +450,14 @@ class Vmfloaty
389
450
  status = service.token_status(verbose, token_value)
390
451
  puts status
391
452
  when nil
392
- STDERR.puts 'No action provided'
453
+ FloatyLogger.error 'No action provided'
393
454
  exit 1
394
455
  else
395
- STDERR.puts "Unknown action: #{action}"
456
+ FloatyLogger.error "Unknown action: #{action}"
396
457
  exit 1
397
458
  end
398
459
  rescue TokenError => e
399
- STDERR.puts e
460
+ FloatyLogger.error e
400
461
  exit 1
401
462
  end
402
463
  exit 0
@@ -420,13 +481,13 @@ class Vmfloaty
420
481
  use_token = !options.notoken
421
482
 
422
483
  if args.empty?
423
- STDERR.puts 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
484
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
424
485
  exit 1
425
486
  end
426
487
 
427
488
  host_os = args.first
428
489
 
429
- STDERR.puts "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
490
+ FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
430
491
 
431
492
  service.ssh(verbose, host_os, use_token)
432
493
  exit 0
@@ -453,7 +514,71 @@ class Vmfloaty
453
514
  puts completion_file
454
515
  exit 0
455
516
  else
456
- STDERR.puts "Could not find completion file for '#{shell}': No such file #{completion_file}"
517
+ FloatyLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}"
518
+ exit 1
519
+ end
520
+ end
521
+ end
522
+
523
+ command :service do |c|
524
+ c.syntax = 'floaty service <types examples>'
525
+ c.summary = 'Display information about floaty services and their configuration'
526
+ c.description = 'Display information about floaty services to aid in setting up a configuration file.'
527
+ c.example 'Print a list of the valid service types', 'floaty service types'
528
+ c.example 'Print a sample config file with multiple services', 'floaty service examples'
529
+ c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod'
530
+ c.action do |args, options|
531
+ action = args.first
532
+
533
+ example_config = Utils.strip_heredoc(<<-CONFIG)
534
+ # Sample ~/.vmfloaty.yml with just vmpooler
535
+ user: 'jdoe'
536
+ url: 'https://vmpooler.example.net'
537
+ token: '456def789'
538
+
539
+ # Sample ~/.vmfloaty.yml with multiple services
540
+ # Note: when the --service is not specified on the command line,
541
+ # the first service listed here is selected automatically
542
+ user: 'jdoe'
543
+ services:
544
+ abs-prod:
545
+ type: 'abs'
546
+ url: 'https://abs.example.net/api/v2'
547
+ token: '123abc456'
548
+ vmpooler_fallback: 'vmpooler-prod'
549
+ nspooler-prod:
550
+ type: 'nspooler'
551
+ url: 'https://nspooler.example.net'
552
+ token: '789ghi012'
553
+ vmpooler-dev:
554
+ type: 'vmpooler'
555
+ url: 'https://vmpooler-dev.example.net'
556
+ token: '987dsa654'
557
+ vmpooler-prod:
558
+ type: 'vmpooler'
559
+ url: 'https://vmpooler.example.net'
560
+ token: '456def789'
561
+
562
+ CONFIG
563
+
564
+ types_output = Utils.strip_heredoc(<<-TYPES)
565
+ The values on the left below can be used in ~/.vmfloaty.yml as the value of type:
566
+
567
+ abs: Puppet's Always Be Scheduling
568
+ nspooler: Puppet's Non-standard Pooler, aka NSPooler
569
+ vmpooler: Puppet's VMPooler
570
+ TYPES
571
+
572
+ case action
573
+ when 'examples'
574
+ FloatyLogger.info example_config
575
+ when 'types'
576
+ FloatyLogger.info types_output
577
+ when nil
578
+ FloatyLogger.error 'No action provided'
579
+ exit 1
580
+ else
581
+ FloatyLogger.error "Unknown action: #{action}"
457
582
  exit 1
458
583
  end
459
584
  end