morpheus-cli 3.6.28 → 3.6.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/morpheus/api/api_client.rb +16 -0
- data/lib/morpheus/api/cloud_folders_interface.rb +47 -0
- data/lib/morpheus/api/cloud_resource_pools_interface.rb +47 -0
- data/lib/morpheus/api/network_types_interface.rb +26 -0
- data/lib/morpheus/api/reports_interface.rb +77 -0
- data/lib/morpheus/api/security_group_rules_interface.rb +6 -0
- data/lib/morpheus/api/security_groups_interface.rb +21 -15
- data/lib/morpheus/cli.rb +3 -0
- data/lib/morpheus/cli/accounts.rb +1 -1
- data/lib/morpheus/cli/apps.rb +2 -2
- data/lib/morpheus/cli/archives_command.rb +18 -18
- data/lib/morpheus/cli/blueprints_command.rb +1 -1
- data/lib/morpheus/cli/boot_scripts_command.rb +6 -6
- data/lib/morpheus/cli/cli_command.rb +4 -0
- data/lib/morpheus/cli/cloud_datastores_command.rb +58 -20
- data/lib/morpheus/cli/cloud_folders_command.rb +463 -0
- data/lib/morpheus/cli/cloud_resource_pools_command.rb +707 -0
- data/lib/morpheus/cli/clouds.rb +2 -0
- data/lib/morpheus/cli/hosts.rb +33 -8
- data/lib/morpheus/cli/instances.rb +79 -54
- data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
- data/lib/morpheus/cli/library_option_types_command.rb +1 -1
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +11 -2
- data/lib/morpheus/cli/monitoring_contacts_command.rb +1 -1
- data/lib/morpheus/cli/monitoring_incidents_command.rb +1 -1
- data/lib/morpheus/cli/network_services_command.rb +7 -3
- data/lib/morpheus/cli/networks_command.rb +164 -63
- data/lib/morpheus/cli/option_types.rb +16 -15
- data/lib/morpheus/cli/policies_command.rb +76 -9
- data/lib/morpheus/cli/preseed_scripts_command.rb +2 -2
- data/lib/morpheus/cli/remote.rb +26 -28
- data/lib/morpheus/cli/reports_command.rb +594 -0
- data/lib/morpheus/cli/security_group_rules.rb +5 -1
- data/lib/morpheus/cli/security_groups.rb +882 -45
- data/lib/morpheus/cli/tasks.rb +158 -23
- data/lib/morpheus/cli/tenants_command.rb +1 -1
- data/lib/morpheus/cli/users.rb +1 -1
- data/lib/morpheus/cli/version.rb +1 -1
- metadata +9 -2
data/lib/morpheus/cli/tasks.rb
CHANGED
@@ -128,7 +128,16 @@ class Morpheus::Cli::Tasks
|
|
128
128
|
description_cols = {
|
129
129
|
"ID" => 'id',
|
130
130
|
"Name" => 'name',
|
131
|
+
"Code" => 'code',
|
131
132
|
"Type" => lambda {|it| it['taskType']['name'] },
|
133
|
+
"Result Type" => 'resultType',
|
134
|
+
"Retryable" => lambda {|it|
|
135
|
+
if it['retryable']
|
136
|
+
format_boolean(it['retryable']).to_s + " Count: #{it['retryCount']}, Delay: #{it['retryDelaySeconds']}"
|
137
|
+
else
|
138
|
+
format_boolean(it['retryable'])
|
139
|
+
end
|
140
|
+
},
|
132
141
|
}
|
133
142
|
print_description_list(description_cols, task)
|
134
143
|
|
@@ -246,7 +255,7 @@ class Morpheus::Cli::Tasks
|
|
246
255
|
rows = task_types.collect do |task_type|
|
247
256
|
{name: task_type['name'], id: task_type['id'], code: task_type['code'], description: task_type['description']}
|
248
257
|
end
|
249
|
-
puts as_pretty_table(rows, [:id, :name, :code],
|
258
|
+
puts as_pretty_table(rows, [:id, :name, :code], options)
|
250
259
|
end
|
251
260
|
|
252
261
|
print reset,"\n"
|
@@ -259,8 +268,9 @@ class Morpheus::Cli::Tasks
|
|
259
268
|
|
260
269
|
def add(args)
|
261
270
|
params = {}
|
262
|
-
options = {}
|
271
|
+
options = {:options => {}}
|
263
272
|
task_name = nil
|
273
|
+
task_code = nil
|
264
274
|
task_type_name = nil
|
265
275
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
266
276
|
opts.banner = subcommand_usage("[name] -t TASK_TYPE")
|
@@ -270,6 +280,25 @@ class Morpheus::Cli::Tasks
|
|
270
280
|
opts.on('--name NAME', String, "Task Name" ) do |val|
|
271
281
|
task_name = val
|
272
282
|
end
|
283
|
+
opts.on('--code CODE', String, "Task Code" ) do |val|
|
284
|
+
task_code = val
|
285
|
+
end
|
286
|
+
opts.on('--result-type VALUE', String, "Result Type" ) do |val|
|
287
|
+
options[:options] ||= {}
|
288
|
+
options[:options]['resultType'] = val
|
289
|
+
end
|
290
|
+
opts.on('--retryable [on|off]', String, "Retryable" ) do |val|
|
291
|
+
options[:options] ||= {}
|
292
|
+
options[:options]['retryable'] = val.to_s == 'on' || val.to_s == 'true' || val == '' || val.nil?
|
293
|
+
end
|
294
|
+
opts.on('--retry-count COUNT', String, "Retry Count" ) do |val|
|
295
|
+
options[:options] ||= {}
|
296
|
+
options[:options]['retryCount'] = val.to_i
|
297
|
+
end
|
298
|
+
opts.on('--retry-delay SECONDS', String, "Retry Delay Seconds" ) do |val|
|
299
|
+
options[:options] ||= {}
|
300
|
+
options[:options]['retryDelaySeconds'] = val.to_i
|
301
|
+
end
|
273
302
|
opts.on('--file FILE', "File containing the script. This can be used instead of --O taskOptions.script" ) do |filename|
|
274
303
|
full_filename = File.expand_path(filename)
|
275
304
|
if File.exists?(full_filename)
|
@@ -282,38 +311,137 @@ class Morpheus::Cli::Tasks
|
|
282
311
|
exit 1
|
283
312
|
end
|
284
313
|
# use the filename as the name by default.
|
285
|
-
if !
|
314
|
+
if !options[:options]['name']
|
286
315
|
options[:options] ||= {}
|
287
|
-
options[:options]['
|
288
|
-
options[:options]['taskOptions']['script'] = File.read(full_filename)
|
289
|
-
params['name'] = File.basename(full_filename)
|
316
|
+
options[:options]['name'] = File.basename(full_filename)
|
290
317
|
end
|
291
318
|
end
|
292
319
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
293
320
|
end
|
294
321
|
optparse.parse!(args)
|
322
|
+
if args.count > 1
|
323
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
324
|
+
end
|
295
325
|
if args[0]
|
296
326
|
task_name = args[0]
|
297
327
|
end
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
end
|
328
|
+
# if task_name.nil? || task_type_name.nil?
|
329
|
+
# puts optparse
|
330
|
+
# exit 1
|
331
|
+
# end
|
303
332
|
connect(options)
|
304
333
|
begin
|
334
|
+
passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
|
335
|
+
if passed_options['type']
|
336
|
+
task_type_name = passed_options.delete('type')
|
337
|
+
end
|
305
338
|
payload = nil
|
339
|
+
|
306
340
|
if options[:payload]
|
307
341
|
payload = options[:payload]
|
342
|
+
payload.deep_merge!({'task' => passed_options}) unless passed_options.empty?
|
308
343
|
else
|
309
344
|
# construct payload
|
345
|
+
payload = {
|
346
|
+
"task" => {
|
347
|
+
#"name" => task_name,
|
348
|
+
#"code" => task_code,
|
349
|
+
#"taskType" {"id" => task_type['id'], "code" => task_type['code']},
|
350
|
+
#"taskOptions" => {}
|
351
|
+
}
|
352
|
+
}
|
353
|
+
payload.deep_merge!({'task' => passed_options}) unless passed_options.empty?
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
# Name
|
358
|
+
if task_name
|
359
|
+
payload['task']['name'] = task_name
|
360
|
+
else
|
361
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name'}], options[:options], @api_client)
|
362
|
+
payload['task']['name'] = v_prompt['name'] unless v_prompt['name'].to_s.empty?
|
363
|
+
end
|
364
|
+
|
365
|
+
# Code
|
366
|
+
if task_code
|
367
|
+
payload['task']['code'] = task_code
|
368
|
+
else
|
369
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'description' => 'Code'}], options[:options], @api_client)
|
370
|
+
payload['task']['code'] = v_prompt['code'] unless v_prompt['code'].to_s.empty?
|
371
|
+
end
|
372
|
+
|
373
|
+
# Task Type
|
374
|
+
@all_task_types ||= @tasks_interface.task_types({max:1000})['taskTypes']
|
375
|
+
task_types_dropdown = @all_task_types.collect {|it| {"name" => it["name"], "value" => it["code"]}}
|
376
|
+
|
377
|
+
if task_type_name
|
378
|
+
#payload['task']['taskType'] = task_code
|
379
|
+
else
|
380
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => task_types_dropdown}], options[:options], @api_client)
|
381
|
+
task_type_name = v_prompt['type']
|
382
|
+
end
|
383
|
+
|
310
384
|
task_type = find_task_type_by_name(task_type_name)
|
311
385
|
if task_type.nil?
|
312
|
-
|
386
|
+
print_red_alert "Task Type not found by code '#{task_type_name}'"
|
313
387
|
return 1
|
314
388
|
end
|
315
|
-
|
316
|
-
payload
|
389
|
+
|
390
|
+
payload['task']['taskType'] = {"id" => task_type['id'], "code" => task_type['code']}
|
391
|
+
|
392
|
+
|
393
|
+
# Result Type
|
394
|
+
if task_code
|
395
|
+
payload['task']['resultType'] = task_code
|
396
|
+
else
|
397
|
+
result_types_dropdown = [{"name" => "Value", "value" => "value"}, {"name" => "Exit Code", "value" => "exitCode"}, {"name" => "Key Value", "value" => "keyValue"}, {"name" => "JSON", "value" => "json"}]
|
398
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'resultType', 'fieldLabel' => 'Result Type', 'type' => 'select', 'selectOptions' => result_types_dropdown}], options[:options], @api_client)
|
399
|
+
payload['task']['resultType'] = v_prompt['resultType'] unless v_prompt['resultType'].to_s.empty?
|
400
|
+
end
|
401
|
+
|
402
|
+
# Task Type Option Types
|
403
|
+
|
404
|
+
# JD: uhh some of these are missing a fieldContext?
|
405
|
+
# containerScript just points to a library script via Id now??
|
406
|
+
task_option_types = task_type['optionTypes'] || []
|
407
|
+
task_option_types.each do |it|
|
408
|
+
if it['fieldContext'].nil? || it['fieldContext'] == ''
|
409
|
+
it['fieldContext'] = 'taskOptions'
|
410
|
+
end
|
411
|
+
end
|
412
|
+
input_options = Morpheus::Cli::OptionTypes.prompt(task_option_types, options[:options],@api_client, options[:params])
|
413
|
+
payload.deep_merge!({'task' => input_options}) unless input_options.empty?
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
# Retryable
|
418
|
+
if options[:options]['retryable'] != nil
|
419
|
+
payload['task']['retryable'] = options[:options]['retryable']
|
420
|
+
else
|
421
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'retryable', 'fieldLabel' => 'Retryable', 'type' => 'checkbox', 'defaultValue' => false}], options[:options], @api_client)
|
422
|
+
payload['task']['retryable'] = ['true','on'].include?(v_prompt['retryable'].to_s) unless v_prompt['retryable'].nil?
|
423
|
+
end
|
424
|
+
|
425
|
+
if payload['task']['retryable']
|
426
|
+
# Retry Count
|
427
|
+
if options[:options]['retryCount']
|
428
|
+
payload['task']['retryCount'] = options[:options]['retryCount'].to_i
|
429
|
+
else
|
430
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'retryCount', 'fieldLabel' => 'Retry Count', 'type' => 'number', 'defaultValue' => 5}], options[:options], @api_client)
|
431
|
+
payload['task']['retryCount'] = v_prompt['retryCount'].to_i unless v_prompt['retryCount'].nil?
|
432
|
+
end
|
433
|
+
# Retry Delay
|
434
|
+
if options[:options]['retryDelay']
|
435
|
+
payload['task']['retryDelay'] = options[:options]['retryDelay'].to_i
|
436
|
+
else
|
437
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'retryDelay', 'fieldLabel' => 'Retry Delay', 'type' => 'number', 'defaultValue' => 10}], options[:options], @api_client)
|
438
|
+
payload['task']['retryDelay'] = v_prompt['retryDelay'].to_i unless v_prompt['retryDelay'].nil?
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
|
443
|
+
|
444
|
+
|
317
445
|
end
|
318
446
|
@tasks_interface.setopts(options)
|
319
447
|
if options[:dry_run]
|
@@ -415,19 +543,26 @@ class Morpheus::Cli::Tasks
|
|
415
543
|
|
416
544
|
def find_task_type_by_name(val)
|
417
545
|
raise "find_task_type_by_name passed a bad name: #{val.inspect}" if val.to_s == ''
|
418
|
-
|
419
|
-
|
420
|
-
if
|
421
|
-
|
422
|
-
|
423
|
-
results = @tasks_interface.task_types(val.to_i)
|
424
|
-
result = results['taskType']
|
546
|
+
@all_task_types ||= @tasks_interface.task_types({max:1000})['taskTypes']
|
547
|
+
|
548
|
+
if @all_task_types.nil? && !@all_task_types.empty?
|
549
|
+
print_red_alert "No task types found"
|
550
|
+
return nil
|
425
551
|
end
|
426
|
-
|
552
|
+
matching_task_types = @all_task_types.select { |it| val && (it['name'] == val || it['code'] == val || it['id'].to_s == val.to_s) }
|
553
|
+
if matching_task_types.size == 1
|
554
|
+
return matching_task_types[0]
|
555
|
+
elsif matching_task_types.size == 0
|
427
556
|
print_red_alert "Task Type not found by '#{val}'"
|
557
|
+
else
|
558
|
+
print_red_alert "#{matching_task_types.size} task types found by name #{name}"
|
559
|
+
rows = matching_task_types.collect do |it|
|
560
|
+
{id: it['id'], name: it['name'], code: it['code']}
|
561
|
+
end
|
562
|
+
print "\n"
|
563
|
+
puts as_pretty_table(rows, [:name, :code], {color:red})
|
428
564
|
return nil
|
429
565
|
end
|
430
|
-
return result
|
431
566
|
end
|
432
567
|
|
433
568
|
def update_task_option_types(task_type)
|
data/lib/morpheus/cli/users.rb
CHANGED
@@ -346,7 +346,7 @@ class Morpheus::Cli::Users
|
|
346
346
|
# merge -O options into normally parsed options
|
347
347
|
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
348
348
|
# if params.empty?
|
349
|
-
# print_red_alert "Specify
|
349
|
+
# print_red_alert "Specify at least one option to update"
|
350
350
|
# puts optparse
|
351
351
|
# return 1
|
352
352
|
# end
|
data/lib/morpheus/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2019-
|
14
|
+
date: 2019-06-10 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -165,7 +165,9 @@ files:
|
|
165
165
|
- lib/morpheus/api/auth_interface.rb
|
166
166
|
- lib/morpheus/api/blueprints_interface.rb
|
167
167
|
- lib/morpheus/api/cloud_datastores_interface.rb
|
168
|
+
- lib/morpheus/api/cloud_folders_interface.rb
|
168
169
|
- lib/morpheus/api/cloud_policies_interface.rb
|
170
|
+
- lib/morpheus/api/cloud_resource_pools_interface.rb
|
169
171
|
- lib/morpheus/api/clouds_interface.rb
|
170
172
|
- lib/morpheus/api/containers_interface.rb
|
171
173
|
- lib/morpheus/api/custom_instance_types_interface.rb
|
@@ -206,6 +208,7 @@ files:
|
|
206
208
|
- lib/morpheus/api/network_pools_interface.rb
|
207
209
|
- lib/morpheus/api/network_proxies_interface.rb
|
208
210
|
- lib/morpheus/api/network_services_interface.rb
|
211
|
+
- lib/morpheus/api/network_types_interface.rb
|
209
212
|
- lib/morpheus/api/networks_interface.rb
|
210
213
|
- lib/morpheus/api/old_cypher_interface.rb
|
211
214
|
- lib/morpheus/api/option_type_lists_interface.rb
|
@@ -216,6 +219,7 @@ files:
|
|
216
219
|
- lib/morpheus/api/power_schedules_interface.rb
|
217
220
|
- lib/morpheus/api/processes_interface.rb
|
218
221
|
- lib/morpheus/api/provision_types_interface.rb
|
222
|
+
- lib/morpheus/api/reports_interface.rb
|
219
223
|
- lib/morpheus/api/roles_interface.rb
|
220
224
|
- lib/morpheus/api/security_group_rules_interface.rb
|
221
225
|
- lib/morpheus/api/security_groups_interface.rb
|
@@ -245,6 +249,8 @@ files:
|
|
245
249
|
- lib/morpheus/cli/cli_command.rb
|
246
250
|
- lib/morpheus/cli/cli_registry.rb
|
247
251
|
- lib/morpheus/cli/cloud_datastores_command.rb
|
252
|
+
- lib/morpheus/cli/cloud_folders_command.rb
|
253
|
+
- lib/morpheus/cli/cloud_resource_pools_command.rb
|
248
254
|
- lib/morpheus/cli/clouds.rb
|
249
255
|
- lib/morpheus/cli/command_error.rb
|
250
256
|
- lib/morpheus/cli/commands/standard/alias_command.rb
|
@@ -329,6 +335,7 @@ files:
|
|
329
335
|
- lib/morpheus/cli/processes_command.rb
|
330
336
|
- lib/morpheus/cli/recent_activity_command.rb
|
331
337
|
- lib/morpheus/cli/remote.rb
|
338
|
+
- lib/morpheus/cli/reports_command.rb
|
332
339
|
- lib/morpheus/cli/roles.rb
|
333
340
|
- lib/morpheus/cli/security_group_rules.rb
|
334
341
|
- lib/morpheus/cli/security_groups.rb
|