vmfloaty 0.10.0 → 1.2.0

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: 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