vmfloaty 1.1.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,7 +39,10 @@ class Utils
39
39
  # "engine"=>"vmpooler"
40
40
  # }
41
41
 
42
- raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok')
42
+ unless response_body.delete('ok')
43
+ raise ArgumentError,
44
+ "Bad GET response passed to format_hosts: #{response_body.to_json}"
45
+ end
43
46
 
44
47
  # vmpooler reports the domain separately from the hostname
45
48
  domain = response_body.delete('domain')
@@ -50,7 +53,7 @@ class Utils
50
53
  abs_job_id = response_body.delete('job_id')
51
54
  result['job_id'] = abs_job_id unless abs_job_id.nil?
52
55
 
53
- filtered_response_body = response_body.reject { |key, _| key == 'request_id' || key == 'ready' }
56
+ filtered_response_body = response_body.reject { |key, _| %w[request_id ready].include?(key) }
54
57
  filtered_response_body.each do |os, value|
55
58
  hostnames = Array(value['hostname'])
56
59
  hostnames.map! { |host| "#{host}.#{domain}" } if domain
@@ -106,7 +109,7 @@ class Utils
106
109
  def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false, indent = 0)
107
110
  output_target = print_to_stderr ? $stderr : $stdout
108
111
 
109
- fetched_data = self.get_host_data(verbose, service, hostnames)
112
+ fetched_data = get_host_data(verbose, service, hostnames)
110
113
  fetched_data.each do |hostname, host_data|
111
114
  case service.type
112
115
  when 'ABS'
@@ -116,13 +119,14 @@ class Utils
116
119
 
117
120
  output_target.puts "- [JobID:#{host_data['request']['job']['id']}] <#{host_data['state']}>"
118
121
  host_data['allocated_resources'].each do |allocated_resources, _i|
119
- if allocated_resources['engine'] == "vmpooler" && service.config["vmpooler_fallback"]
122
+ if (allocated_resources['engine'] == 'vmpooler' || allocated_resources['engine'] == 'ondemand') && service.config['vmpooler_fallback']
120
123
  vmpooler_service = service.clone
121
124
  vmpooler_service.silent = true
122
125
  vmpooler_service.maybe_use_vmpooler
123
- self.pretty_print_hosts(verbose, vmpooler_service, allocated_resources['hostname'].split('.')[0], print_to_stderr, indent+2)
126
+ pretty_print_hosts(verbose, vmpooler_service, allocated_resources['hostname'].split('.')[0],
127
+ print_to_stderr, indent + 2)
124
128
  else
125
- #TODO we could add more specific metadata for the other services, nspooler and aws
129
+ # TODO: we could add more specific metadata for the other services, nspooler and aws
126
130
  output_target.puts " - #{allocated_resources['hostname']} (#{allocated_resources['type']})"
127
131
  end
128
132
  end
@@ -130,8 +134,13 @@ class Utils
130
134
  tag_pairs = []
131
135
  tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil?
132
136
  duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
133
- metadata = [host_data['template'], duration, *tag_pairs]
134
- output_target.puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent)
137
+ metadata = [host_data['state'], host_data['template'], duration, *tag_pairs]
138
+ message = "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})".gsub(/^/, ' ' * indent)
139
+ if host_data['state'] && host_data['state'] == 'destroyed'
140
+ output_target.puts message.colorize(:red)
141
+ else
142
+ output_target.puts message
143
+ end
135
144
  when 'NonstandardPooler'
136
145
  line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
137
146
  line += ", #{host_data['hours_left_on_reservation']}h remaining"
@@ -148,30 +157,26 @@ class Utils
148
157
  result = {}
149
158
  hostnames = [hostnames] unless hostnames.is_a? Array
150
159
  hostnames.each do |hostname|
151
- begin
152
- response = service.query(verbose, hostname)
153
- host_data = response[hostname]
154
- if block_given?
155
- yield host_data result
160
+ response = service.query(verbose, hostname)
161
+ host_data = response[hostname]
162
+ if block_given?
163
+ yield host_data result
164
+ else
165
+ case service.type
166
+ when 'ABS'
167
+ # For ABS, 'hostname' variable is the jobID
168
+ result[hostname] = host_data if host_data['state'] == 'allocated' || host_data['state'] == 'filled'
169
+ when 'Pooler'
170
+ result[hostname] = host_data
171
+ when 'NonstandardPooler'
172
+ result[hostname] = host_data
156
173
  else
157
- case service.type
158
- when 'ABS'
159
- # For ABS, 'hostname' variable is the jobID
160
- if host_data['state'] == 'allocated' || host_data['state'] == 'filled'
161
- result[hostname] = host_data
162
- end
163
- when 'Pooler'
164
- result[hostname] = host_data
165
- when 'NonstandardPooler'
166
- result[hostname] = host_data
167
- else
168
- raise "Invalid service type #{service.type}"
169
- end
174
+ raise "Invalid service type #{service.type}"
170
175
  end
171
- rescue StandardError => e
172
- FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:")
173
- FloatyLogger.error(e)
174
176
  end
177
+ rescue StandardError => e
178
+ FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:")
179
+ FloatyLogger.error(e)
175
180
  end
176
181
  result
177
182
  end
@@ -187,16 +192,14 @@ class Utils
187
192
 
188
193
  width = pools.keys.map(&:length).max
189
194
  pools.each do |name, pool|
190
- begin
191
- max = pool['max']
192
- ready = pool['ready']
193
- pending = pool['pending']
194
- missing = max - ready - pending
195
- char = 'o'
196
- puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
197
- rescue StandardError => e
198
- FloatyLogger.error "#{name.ljust(width)} #{e.red}"
199
- end
195
+ max = pool['max']
196
+ ready = pool['ready']
197
+ pending = pool['pending']
198
+ missing = max - ready - pending
199
+ char = 'o'
200
+ puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
201
+ rescue StandardError => e
202
+ FloatyLogger.error "#{name.ljust(width)} #{e.red}"
200
203
  end
201
204
  puts message.colorize(status_response['status']['ok'] ? :default : :red)
202
205
  when 'NonstandardPooler'
@@ -206,16 +209,14 @@ class Utils
206
209
 
207
210
  width = pools.keys.map(&:length).max
208
211
  pools.each do |name, pool|
209
- begin
210
- max = pool['total_hosts']
211
- ready = pool['available_hosts']
212
- pending = pool['pending'] || 0 # not available for nspooler
213
- missing = max - ready - pending
214
- char = 'o'
215
- puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
216
- rescue StandardError => e
217
- FloatyLogger.error "#{name.ljust(width)} #{e.red}"
218
- end
212
+ max = pool['total_hosts']
213
+ ready = pool['available_hosts']
214
+ pending = pool['pending'] || 0 # not available for nspooler
215
+ missing = max - ready - pending
216
+ char = 'o'
217
+ puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
218
+ rescue StandardError => e
219
+ FloatyLogger.error "#{name.ljust(width)} #{e.red}"
219
220
  end
220
221
  when 'ABS'
221
222
  FloatyLogger.error 'ABS Not OK' unless status_response
@@ -251,11 +252,11 @@ class Utils
251
252
  def self.get_service_config(config, options)
252
253
  # The top-level url, user, and token values in the config file are treated as defaults
253
254
  service_config = {
254
- 'url' => config['url'],
255
- 'user' => config['user'],
255
+ 'url' => config['url'],
256
+ 'user' => config['user'],
256
257
  'token' => config['token'],
257
258
  'vmpooler_fallback' => config['vmpooler_fallback'],
258
- 'type' => config['type'] || 'vmpooler',
259
+ 'type' => config['type'] || 'vmpooler'
259
260
  }
260
261
 
261
262
  if config['services']
@@ -266,7 +267,10 @@ class Utils
266
267
  service_config.merge! values
267
268
  else
268
269
  # If the user provided a service name at the command line, use that service if posible, or fail
269
- raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" unless config['services'][options.service]
270
+ unless config['services'][options.service]
271
+ raise ArgumentError,
272
+ "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml"
273
+ end
270
274
 
271
275
  # If the service is configured but some values are missing, use the top-level defaults to fill them in
272
276
  service_config.merge! config['services'][options.service]
@@ -290,22 +294,22 @@ class Utils
290
294
  config = Conf.read_config
291
295
  # The top-level url, user, and token values in the config file are treated as defaults
292
296
  service_config = {
293
- 'url' => config['url'],
294
- 'user' => config['user'],
295
- 'token' => config['token'],
296
- 'type' => 'vmpooler',
297
+ 'url' => config['url'],
298
+ 'user' => config['user'],
299
+ 'token' => config['token'],
300
+ 'type' => 'vmpooler'
297
301
  }
298
302
 
299
303
  # at a minimum, the url needs to be configured
300
304
  if config['services'] && config['services'][vmpooler_fallback] && config['services'][vmpooler_fallback]['url']
301
305
  # If the service is configured but some values are missing, use the top-level defaults to fill them in
302
306
  service_config.merge! config['services'][vmpooler_fallback]
307
+ elsif vmpooler_fallback.nil?
308
+ raise ArgumentError,
309
+ "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'"
303
310
  else
304
- if vmpooler_fallback.nil?
305
- 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'"
306
- else
307
- 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'"
308
- end
311
+ raise ArgumentError,
312
+ "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'"
309
313
  end
310
314
 
311
315
  service_config
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Vmfloaty
4
- VERSION = '1.1.1'
4
+ VERSION = '1.5.0'
5
5
  end
6
-
data/lib/vmfloaty.rb CHANGED
@@ -20,7 +20,8 @@ class Vmfloaty
20
20
 
21
21
  def run # rubocop:disable Metrics/AbcSize
22
22
  program :version, Vmfloaty::VERSION
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
+ program :description,
24
+ "A CLI helper tool for Puppet's vmpooler to help you stay afloat.\n\nConfiguration may be placed in a ~/.vmfloaty.yml file."
24
25
 
25
26
  config = Conf.read_config
26
27
 
@@ -39,8 +40,11 @@ class Vmfloaty
39
40
  c.option '--force', 'Forces vmfloaty to get requested vms'
40
41
  c.option '--json', 'Prints retrieved vms in JSON format'
41
42
  c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID'
43
+ c.option '--continue STRING', String, 'resume polling ABS for job_id, for use when the cli was interrupted'
44
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
42
45
  c.action do |args, options|
43
46
  verbose = options.verbose || config['verbose']
47
+ FloatyLogger.setlevel = options.loglevel if options.loglevel
44
48
  service = Service.new(options, config)
45
49
  use_token = !options.notoken
46
50
  force = options.force
@@ -52,6 +56,11 @@ class Vmfloaty
52
56
 
53
57
  os_types = Utils.generate_os_hash(args)
54
58
 
59
+ if os_types.empty?
60
+ FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
61
+ exit 1
62
+ end
63
+
55
64
  max_pool_request = 5
56
65
  large_pool_requests = os_types.select { |_, v| v > max_pool_request }
57
66
  if !large_pool_requests.empty? && !force
@@ -60,12 +69,7 @@ class Vmfloaty
60
69
  exit 1
61
70
  end
62
71
 
63
- if os_types.empty?
64
- FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
65
- exit 1
66
- end
67
-
68
- response = service.retrieve(verbose, os_types, use_token, options.ondemand)
72
+ response = service.retrieve(verbose, os_types, use_token, options.ondemand, options.continue)
69
73
  request_id = response['request_id'] if options.ondemand
70
74
  response = service.wait_for_request(verbose, request_id) if options.ondemand
71
75
 
@@ -92,20 +96,22 @@ class Vmfloaty
92
96
  c.option '--token STRING', String, 'Token for pooler service'
93
97
  c.option '--url STRING', String, 'URL of pooler service'
94
98
  c.option '--user STRING', String, 'User to authenticate with'
99
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
95
100
  c.action do |args, options|
96
101
  verbose = options.verbose || config['verbose']
102
+ FloatyLogger.setlevel = options.loglevel if options.loglevel
97
103
 
98
104
  service = Service.new(options, config)
99
105
  filter = args[0]
100
106
 
101
107
  if options.active
102
108
  # list active vms
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
109
+ running_vms = if service.type == 'ABS'
110
+ # this is actually job_ids
111
+ service.list_active_job_ids(verbose, service.url, service.user)
112
+ else
113
+ service.list_active(verbose)
114
+ end
109
115
  host = URI.parse(service.url).host
110
116
  if running_vms.empty?
111
117
  if options.json
@@ -113,17 +119,15 @@ class Vmfloaty
113
119
  else
114
120
  FloatyLogger.info "You have no running VMs on #{host}"
115
121
  end
116
- else
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)
122
+ elsif options.json
123
+ puts Utils.get_host_data(verbose, service, running_vms).to_json
124
+ elsif options.hostnameonly
125
+ Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data|
126
+ Utils.print_fqdn_for_host(service, hostname, host_data)
126
127
  end
128
+ else
129
+ puts "Your VMs on #{host}:"
130
+ Utils.pretty_print_hosts(verbose, service, running_vms)
127
131
  end
128
132
  else
129
133
  # list available vms from pooler
@@ -155,7 +159,8 @@ class Vmfloaty
155
159
  c.syntax = 'floaty modify hostname [options]'
156
160
  c.summary = 'Modify a VM\'s tags, time to live, disk space, or reservation reason'
157
161
  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.'
158
- 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"}\''
162
+ c.example 'Modifies myhost1 to have a TTL of 12 hours and adds a custom tag',
163
+ 'floaty modify myhost1 --lifetime 12 --url https://myurl --token mytokenstring --tags \'{"tag":"myvalue"}\''
159
164
  c.option '--verbose', 'Enables verbose output'
160
165
  c.option '--service STRING', String, 'Configured pooler service name'
161
166
  c.option '--url STRING', String, 'URL of pooler service'
@@ -176,18 +181,18 @@ class Vmfloaty
176
181
  exit 1
177
182
  end
178
183
  running_vms =
179
- if modify_all
180
- service.list_active(verbose)
181
- else
182
- hostname.split(',')
183
- end
184
+ if modify_all
185
+ service.list_active(verbose)
186
+ else
187
+ hostname.split(',')
188
+ end
184
189
 
185
190
  tags = options.tags ? JSON.parse(options.tags) : nil
186
191
  modify_hash = {
187
- :lifetime => options.lifetime,
188
- :disk => options.disk,
189
- :tags => tags,
190
- :reason => options.reason,
192
+ lifetime: options.lifetime,
193
+ disk: options.disk,
194
+ tags: tags,
195
+ reason: options.reason
191
196
  }
192
197
  modify_hash.delete_if { |_, value| value.nil? }
193
198
 
@@ -195,12 +200,10 @@ class Vmfloaty
195
200
  ok = true
196
201
  modified_hash = {}
197
202
  running_vms.each do |vm|
198
- begin
199
- modified_hash[vm] = service.modify(verbose, vm, modify_hash)
200
- rescue ModifyError => e
201
- FloatyLogger.error e
202
- ok = false
203
- end
203
+ modified_hash[vm] = service.modify(verbose, vm, modify_hash)
204
+ rescue ModifyError => e
205
+ FloatyLogger.error e
206
+ ok = false
204
207
  end
205
208
  if ok
206
209
  if modify_all
@@ -229,8 +232,11 @@ class Vmfloaty
229
232
  c.option '--token STRING', String, 'Token for pooler service'
230
233
  c.option '--url STRING', String, 'URL of pooler service'
231
234
  c.option '--user STRING', String, 'User to authenticate with'
235
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
232
236
  c.action do |args, options|
233
237
  verbose = options.verbose || config['verbose']
238
+ FloatyLogger.setlevel = options.loglevel if options.loglevel
239
+
234
240
  service = Service.new(options, config)
235
241
  hostnames = args[0]
236
242
  delete_all = options.all
@@ -240,17 +246,17 @@ class Vmfloaty
240
246
  successes = []
241
247
 
242
248
  if delete_all
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
249
+ running_vms = if service.type == 'ABS'
250
+ # this is actually job_ids
251
+ service.list_active_job_ids(verbose, service.url, service.user)
252
+ else
253
+ service.list_active(verbose)
254
+ end
249
255
  if running_vms.empty?
250
256
  if options.json
251
257
  puts {}.to_json
252
258
  else
253
- FloatyLogger.info "You have no running VMs."
259
+ FloatyLogger.info 'You have no running VMs.'
254
260
  end
255
261
  else
256
262
  confirmed = true
@@ -314,7 +320,8 @@ class Vmfloaty
314
320
  c.syntax = 'floaty snapshot hostname [options]'
315
321
  c.summary = 'Takes a snapshot of a given vm'
316
322
  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.'
317
- c.example 'Takes a snapshot for a given host', 'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
323
+ c.example 'Takes a snapshot for a given host',
324
+ 'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
318
325
  c.option '--verbose', 'Enables verbose output'
319
326
  c.option '--service STRING', String, 'Configured pooler service name'
320
327
  c.option '--url STRING', String, 'URL of pooler service'
@@ -340,7 +347,8 @@ class Vmfloaty
340
347
  c.syntax = 'floaty revert hostname snapshot [options]'
341
348
  c.summary = 'Reverts a vm to a specified snapshot'
342
349
  c.description = 'Given a snapshot SHA, vmfloaty will request a revert to the pooler service to go back to a previous snapshot.'
343
- c.example 'Reverts to a snapshot for a given host', 'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
350
+ c.example 'Reverts to a snapshot for a given host',
351
+ 'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
344
352
  c.option '--verbose', 'Enables verbose output'
345
353
  c.option '--service STRING', String, 'Configured pooler service name'
346
354
  c.option '--url STRING', String, 'URL of pooler service'
@@ -352,7 +360,9 @@ class Vmfloaty
352
360
  hostname = args[0]
353
361
  snapshot_sha = args[1] || options.snapshot
354
362
 
355
- FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
363
+ if args[1] && options.snapshot
364
+ FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}"
365
+ end
356
366
 
357
367
  begin
358
368
  revert_req = service.revert(verbose, hostname, snapshot_sha)
@@ -374,8 +384,10 @@ class Vmfloaty
374
384
  c.option '--service STRING', String, 'Configured pooler service name'
375
385
  c.option '--url STRING', String, 'URL of pooler service'
376
386
  c.option '--json', 'Prints status in JSON format'
387
+ c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
377
388
  c.action do |_, options|
378
389
  verbose = options.verbose || config['verbose']
390
+ FloatyLogger.setlevel = options.loglevel if options.loglevel
379
391
  service = Service.new(options, config)
380
392
  if options.json
381
393
  pp service.status(verbose)
@@ -457,6 +469,8 @@ class Vmfloaty
457
469
  c.option '--user STRING', String, 'User to authenticate with'
458
470
  c.option '--token STRING', String, 'Token for pooler service'
459
471
  c.option '--notoken', 'Makes a request without a token'
472
+ c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))'
473
+ c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID'
460
474
  c.action do |args, options|
461
475
  verbose = options.verbose || config['verbose']
462
476
  service = Service.new(options, config)
@@ -509,7 +523,7 @@ class Vmfloaty
509
523
  c.example 'Print a list of the valid service types', 'floaty service types'
510
524
  c.example 'Print a sample config file with multiple services', 'floaty service examples'
511
525
  c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod'
512
- c.action do |args, options|
526
+ c.action do |args, _options|
513
527
  action = args.first
514
528
 
515
529
  example_config = Utils.strip_heredoc(<<-CONFIG)
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'simplecov'
4
- require 'coveralls'
4
+ require 'simplecov-lcov'
5
+ require 'base64'
6
+
7
+ SimpleCov::Formatter::LcovFormatter.config do |c|
8
+ c.report_with_single_file = true
9
+ c.single_report_path = 'coverage/lcov.info'
10
+ end
11
+
12
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
13
+ [
14
+ SimpleCov::Formatter::HTMLFormatter,
15
+ SimpleCov::Formatter::LcovFormatter
16
+ ]
17
+ )
5
18
 
6
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
7
- SimpleCov::Formatter::HTMLFormatter,
8
- Coveralls::SimpleCov::Formatter
9
- ])
10
19
  SimpleCov.start do
11
20
  add_filter %r{^/spec/}
12
21
  end
@@ -26,3 +35,19 @@ RSpec.configure do |config|
26
35
  config.tty = true
27
36
  config.formatter = :documentation
28
37
  end
38
+
39
+ def get_headers(username: nil, password: nil, token: nil, content_type: nil, content_length: nil)
40
+ headers = {
41
+ 'Accept' => '*/*',
42
+ 'Accept-Encoding' => /gzip/,
43
+ 'User-Agent' => /Faraday/,
44
+ }
45
+ if username && password
46
+ auth = Base64.encode64("#{username}:#{password}").chomp
47
+ headers['Authorization'] = "Basic #{auth}"
48
+ end
49
+ headers['X-Auth-Token'] = token if token
50
+ headers['Content-Type'] = content_type if content_type
51
+ headers['Content-Length'] = content_length.to_s if content_length
52
+ headers
53
+ end
@@ -3,7 +3,11 @@
3
3
  require 'spec_helper'
4
4
  require_relative '../../../lib/vmfloaty/auth'
5
5
 
6
+ user = 'first.last'
7
+ pass = 'password'
8
+
6
9
  describe Pooler do
10
+
7
11
  before :each do
8
12
  @abs_url = 'https://abs.example.com/api/v2'
9
13
  end
@@ -15,18 +19,20 @@ describe Pooler do
15
19
  end
16
20
 
17
21
  it 'returns a token from abs' do
18
- stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token')
19
- .to_return(:status => 200, :body => @get_token_response, :headers => {})
22
+ stub_request(:post, 'https://abs.example.com/api/v2/token')
23
+ .with(headers: get_headers(username: user, password: pass, content_length: 0))
24
+ .to_return(status: 200, body: @get_token_response, headers: {})
20
25
 
21
- token = Auth.get_token(false, @abs_url, 'first.last', 'password')
26
+ token = Auth.get_token(false, @abs_url, user, pass)
22
27
  expect(token).to eq @token
23
28
  end
24
29
 
25
30
  it 'raises a token error if something goes wrong' do
26
- stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token')
27
- .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
31
+ stub_request(:post, 'https://abs.example.com/api/v2/token')
32
+ .with(headers: get_headers(username: user, password: pass, content_length: 0))
33
+ .to_return(status: 500, body: '{"ok":false}', headers: {})
28
34
 
29
- expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError)
35
+ expect { Auth.get_token(false, @abs_url, user, pass) }.to raise_error(TokenError)
30
36
  end
31
37
  end
32
38
 
@@ -37,21 +43,24 @@ describe Pooler do
37
43
  end
38
44
 
39
45
  it 'deletes the specified token' do
40
- stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
41
- .to_return(:status => 200, :body => @delete_token_response, :headers => {})
46
+ stub_request(:delete, 'https://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
47
+ .with(headers: get_headers(username: user, password: pass))
48
+ .to_return(status: 200, body: @delete_token_response, headers: {})
42
49
 
43
- expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response)
50
+ expect(Auth.delete_token(false, @abs_url, user, pass,
51
+ @token)).to eq JSON.parse(@delete_token_response)
44
52
  end
45
53
 
46
54
  it 'raises a token error if something goes wrong' do
47
- stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
48
- .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
55
+ stub_request(:delete, 'https://abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
56
+ .with(headers: get_headers(username: user, password: pass))
57
+ .to_return(status: 500, body: '{"ok":false}', headers: {})
49
58
 
50
- expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
59
+ expect { Auth.delete_token(false, @abs_url, user, pass, @token) }.to raise_error(TokenError)
51
60
  end
52
61
 
53
62
  it 'raises a token error if no token provided' do
54
- expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', nil) }.to raise_error(TokenError)
63
+ expect { Auth.delete_token(false, @abs_url, user, pass, nil) }.to raise_error(TokenError)
55
64
  end
56
65
  end
57
66
 
@@ -63,16 +72,16 @@ describe Pooler do
63
72
 
64
73
  it 'checks the status of a token' do
65
74
  stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
66
- .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
67
- .to_return(:status => 200, :body => @token_status_response, :headers => {})
75
+ .with(headers: get_headers)
76
+ .to_return(status: 200, body: @token_status_response, headers: {})
68
77
 
69
78
  expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response)
70
79
  end
71
80
 
72
81
  it 'raises a token error if something goes wrong' do
73
82
  stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
74
- .with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
75
- .to_return(:status => 500, :body => '{"ok":false}', :headers => {})
83
+ .with(headers: get_headers)
84
+ .to_return(status: 500, body: '{"ok":false}', headers: {})
76
85
 
77
86
  expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError)
78
87
  end