morpheus-cli 2.12.5 → 3.1.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 +4 -4
- data/Dockerfile +5 -0
- data/lib/morpheus/api/api_client.rb +15 -30
- data/lib/morpheus/api/app_templates_interface.rb +34 -7
- data/lib/morpheus/api/apps_interface.rb +20 -1
- data/lib/morpheus/api/archive_buckets_interface.rb +124 -0
- data/lib/morpheus/api/archive_files_interface.rb +182 -0
- data/lib/morpheus/api/{network_pools_interface.rb → image_builder_boot_scripts_interface.rb} +6 -6
- data/lib/morpheus/api/{policies_interface.rb → image_builder_image_builds_interface.rb} +20 -15
- data/lib/morpheus/api/image_builder_interface.rb +26 -0
- data/lib/morpheus/api/{network_proxies_interface.rb → image_builder_preseed_scripts_interface.rb} +6 -6
- data/lib/morpheus/cli.rb +10 -9
- data/lib/morpheus/cli/alias_command.rb +10 -9
- data/lib/morpheus/cli/app_templates.rb +1566 -457
- data/lib/morpheus/cli/apps.rb +284 -108
- data/lib/morpheus/cli/archives_command.rb +2184 -0
- data/lib/morpheus/cli/boot_scripts_command.rb +382 -0
- data/lib/morpheus/cli/cli_command.rb +9 -35
- data/lib/morpheus/cli/error_handler.rb +2 -0
- data/lib/morpheus/cli/hosts.rb +15 -3
- data/lib/morpheus/cli/image_builder_command.rb +1208 -0
- data/lib/morpheus/cli/instances.rb +118 -47
- data/lib/morpheus/cli/man_command.rb +27 -24
- data/lib/morpheus/cli/mixins/print_helper.rb +19 -5
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +20 -20
- data/lib/morpheus/cli/option_types.rb +45 -14
- data/lib/morpheus/cli/preseed_scripts_command.rb +381 -0
- data/lib/morpheus/cli/remote.rb +1 -0
- data/lib/morpheus/cli/roles.rb +2 -2
- data/lib/morpheus/cli/shell.rb +3 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/ext/hash.rb +22 -0
- data/lib/morpheus/formatters.rb +33 -0
- data/lib/morpheus/terminal.rb +1 -1
- metadata +13 -21
- data/lib/morpheus/api/cloud_policies_interface.rb +0 -47
- data/lib/morpheus/api/group_policies_interface.rb +0 -47
- data/lib/morpheus/api/network_domains_interface.rb +0 -47
- data/lib/morpheus/api/network_groups_interface.rb +0 -47
- data/lib/morpheus/api/network_pool_servers_interface.rb +0 -47
- data/lib/morpheus/api/network_services_interface.rb +0 -47
- data/lib/morpheus/api/networks_interface.rb +0 -54
- data/lib/morpheus/cli/network_domains_command.rb +0 -571
- data/lib/morpheus/cli/network_groups_command.rb +0 -602
- data/lib/morpheus/cli/network_pool_servers_command.rb +0 -430
- data/lib/morpheus/cli/network_pools_command.rb +0 -495
- data/lib/morpheus/cli/network_proxies_command.rb +0 -594
- data/lib/morpheus/cli/network_services_command.rb +0 -148
- data/lib/morpheus/cli/networks_command.rb +0 -855
- data/lib/morpheus/cli/policies_command.rb +0 -847
- data/scripts/generate_morpheus_commands_help.morpheus +0 -1313
@@ -218,11 +218,13 @@ module Morpheus::Cli::ProvisioningHelper
|
|
218
218
|
|
219
219
|
payload = {
|
220
220
|
'zoneId' => cloud_id,
|
221
|
+
# 'siteId' => siteId,
|
221
222
|
'instance' => {
|
222
223
|
'name' => instance_name,
|
223
224
|
'site' => {
|
224
225
|
'id' => group_id
|
225
226
|
},
|
227
|
+
'type' => instance_type_code,
|
226
228
|
'instanceType' => {
|
227
229
|
'code' => instance_type_code
|
228
230
|
}
|
@@ -263,7 +265,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
263
265
|
payload['instance']['layout'] = {'id' => layout['id']}
|
264
266
|
|
265
267
|
# prompt for service plan
|
266
|
-
service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout_id})
|
268
|
+
service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout_id, siteId: group_id})
|
267
269
|
service_plans = service_plans_json["plans"]
|
268
270
|
service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"]} } # already sorted
|
269
271
|
plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance'}],options[:options])
|
@@ -289,29 +291,27 @@ module Morpheus::Cli::ProvisioningHelper
|
|
289
291
|
end
|
290
292
|
end
|
291
293
|
|
292
|
-
|
294
|
+
# build option types
|
295
|
+
option_type_list = []
|
293
296
|
if !layout['optionTypes'].nil? && !layout['optionTypes'].empty?
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
payload.deep_merge!(type_payload)
|
297
|
+
option_type_list += layout['optionTypes']
|
298
|
+
end
|
299
|
+
if !instance_type['optionTypes'].nil? && !instance_type['optionTypes'].empty?
|
300
|
+
option_type_list += instance_type['optionTypes']
|
299
301
|
end
|
300
|
-
|
301
302
|
if !layout['provisionType'].nil? && !layout['provisionType']['optionTypes'].nil? && !layout['provisionType']['optionTypes'].empty?
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
end
|
307
|
-
# remove networkId option if networks were configured above
|
308
|
-
if !payload['networkInterfaces'].empty?
|
309
|
-
instance_type_option_types = reject_networking_option_types(instance_type_option_types)
|
310
|
-
end
|
311
|
-
#print "#{dark} #=> gathering instance type option types for layout provision type...#{reset}\n" if Morpheus::Logging.debug?
|
312
|
-
provision_payload = Morpheus::Cli::OptionTypes.prompt(instance_type_option_types,options[:options],api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
|
313
|
-
payload.deep_merge!(provision_payload)
|
303
|
+
option_type_list += layout['provisionType']['optionTypes']
|
304
|
+
end
|
305
|
+
if !payload['volumes'].empty?
|
306
|
+
option_type_list = reject_volume_option_types(option_type_list)
|
314
307
|
end
|
308
|
+
# remove networkId option if networks were configured above
|
309
|
+
if !payload['networkInterfaces'].empty?
|
310
|
+
option_type_list = reject_networking_option_types(option_type_list)
|
311
|
+
end
|
312
|
+
|
313
|
+
instance_config_payload = Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, {groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
|
314
|
+
payload.deep_merge!(instance_config_payload)
|
315
315
|
|
316
316
|
## Advanced Options
|
317
317
|
|
@@ -194,7 +194,7 @@ module Morpheus
|
|
194
194
|
value_found = false
|
195
195
|
value = nil
|
196
196
|
while !value_found do
|
197
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{
|
197
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
198
198
|
input = $stdin.gets.chomp!
|
199
199
|
value = input.empty? ? option_type['defaultValue'] : input
|
200
200
|
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
@@ -233,7 +233,7 @@ module Morpheus
|
|
233
233
|
else
|
234
234
|
print Term::ANSIColor.red, "\nInvalid Option #{option_type['fieldLabel']}: [#{use_value}]\n\n", Term::ANSIColor.reset
|
235
235
|
print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
|
236
|
-
display_select_options(select_options)
|
236
|
+
display_select_options(opt, select_options)
|
237
237
|
print "\n"
|
238
238
|
exit 1
|
239
239
|
end
|
@@ -247,7 +247,7 @@ module Morpheus
|
|
247
247
|
if option_type['required']
|
248
248
|
print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
|
249
249
|
print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
|
250
|
-
display_select_options(select_options)
|
250
|
+
display_select_options(option_type, select_options)
|
251
251
|
print "\n"
|
252
252
|
exit 1
|
253
253
|
else
|
@@ -258,8 +258,20 @@ module Morpheus
|
|
258
258
|
while !value_found do
|
259
259
|
Readline.completion_append_character = ""
|
260
260
|
Readline.basic_word_break_characters = ''
|
261
|
-
Readline.completion_proc = proc {|s|
|
262
|
-
|
261
|
+
Readline.completion_proc = proc {|s|
|
262
|
+
matches = []
|
263
|
+
available_options = (select_options || [])
|
264
|
+
available_options.each{|option|
|
265
|
+
if option['name'] && option['name'] =~ /^#{Regexp.escape(s)}/
|
266
|
+
matches << option['name']
|
267
|
+
# elsif option['id'] && option['id'].to_s =~ /^#{Regexp.escape(s)}/
|
268
|
+
elsif option['value'] && option['value'].to_s == s
|
269
|
+
matches << option['name']
|
270
|
+
end
|
271
|
+
}
|
272
|
+
matches
|
273
|
+
}
|
274
|
+
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
|
263
275
|
input = input.chomp.strip
|
264
276
|
if input.empty?
|
265
277
|
value = option_type['defaultValue']
|
@@ -273,7 +285,7 @@ module Morpheus
|
|
273
285
|
end
|
274
286
|
if input == '?'
|
275
287
|
help_prompt(option_type)
|
276
|
-
display_select_options(select_options)
|
288
|
+
display_select_options(option_type, select_options)
|
277
289
|
elsif !value.nil? || option_type['required'] != true
|
278
290
|
value_found = true
|
279
291
|
end
|
@@ -323,7 +335,7 @@ module Morpheus
|
|
323
335
|
value_found = false
|
324
336
|
value = nil
|
325
337
|
while !value_found do
|
326
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{
|
338
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
327
339
|
input = $stdin.gets.chomp!
|
328
340
|
value = input.empty? ? option_type['defaultValue'] : input
|
329
341
|
if input == '?'
|
@@ -340,7 +352,7 @@ module Morpheus
|
|
340
352
|
value = nil
|
341
353
|
while !value_found do
|
342
354
|
if value.nil?
|
343
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{
|
355
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)} [Type 'EOF' to stop input]: \n"
|
344
356
|
end
|
345
357
|
input = $stdin.gets.chomp!
|
346
358
|
# value = input.empty? ? option_type['defaultValue'] : input
|
@@ -361,12 +373,15 @@ module Morpheus
|
|
361
373
|
def self.password_prompt(option_type)
|
362
374
|
value_found = false
|
363
375
|
while !value_found do
|
364
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{
|
376
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
365
377
|
input = $stdin.noecho(&:gets).chomp!
|
366
378
|
value = input
|
367
379
|
print "\n"
|
368
380
|
if input == '?'
|
369
381
|
help_prompt(option_type)
|
382
|
+
elsif input == "" && option_type['defaultValue'] != nil
|
383
|
+
value = option_type['defaultValue'].to_s
|
384
|
+
value_found = true
|
370
385
|
elsif !value.empty? || option_type['required'] != true
|
371
386
|
value_found = true
|
372
387
|
end
|
@@ -378,11 +393,11 @@ module Morpheus
|
|
378
393
|
value_found = false
|
379
394
|
value = nil
|
380
395
|
while !value_found do
|
381
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{
|
396
|
+
#print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
382
397
|
Readline.completion_append_character = ""
|
383
398
|
Readline.basic_word_break_characters = ''
|
384
399
|
Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
|
385
|
-
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{
|
400
|
+
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
|
386
401
|
input = input.chomp.strip
|
387
402
|
#input = $stdin.gets.chomp!
|
388
403
|
value = input.empty? ? option_type['defaultValue'] : input.to_s
|
@@ -409,7 +424,14 @@ module Morpheus
|
|
409
424
|
end
|
410
425
|
|
411
426
|
def self.help_prompt(option_type)
|
412
|
-
|
427
|
+
full_field_name = option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''
|
428
|
+
full_field_name << option_type['fieldName'].to_s
|
429
|
+
# an attempt at prompting help for natural options without the -O switch
|
430
|
+
if option_type[:fmt] == :natural
|
431
|
+
print Term::ANSIColor.green," * #{option_type['fieldLabel']} [--#{full_field_name}=] ", Term::ANSIColor.reset , "#{option_type['description']}\n"
|
432
|
+
else
|
433
|
+
print Term::ANSIColor.green," * #{option_type['fieldLabel']} [-O #{full_field_name}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
|
434
|
+
end
|
413
435
|
end
|
414
436
|
|
415
437
|
|
@@ -417,8 +439,9 @@ module Morpheus
|
|
417
439
|
api_client.options.options_for_source(source,params)['data']
|
418
440
|
end
|
419
441
|
|
420
|
-
def self.display_select_options(select_options = [])
|
421
|
-
|
442
|
+
def self.display_select_options(opt, select_options = [])
|
443
|
+
header = opt['fieldLabel'] ? "#{opt['fieldLabel']} Options" : "Options"
|
444
|
+
puts "\n#{header}"
|
422
445
|
puts "==============="
|
423
446
|
select_options.each do |option|
|
424
447
|
puts " * #{option['name']} [#{option['value']}]"
|
@@ -438,6 +461,14 @@ module Morpheus
|
|
438
461
|
puts self.format_option_types_help(option_types)
|
439
462
|
end
|
440
463
|
|
464
|
+
def self.optional_label(option_type)
|
465
|
+
# removing this for now, for the sake of providing less to look at
|
466
|
+
if option_type[:fmt] == :natural # || true
|
467
|
+
return ""
|
468
|
+
else
|
469
|
+
return option_type['required'] ? '' : ' (optional)'
|
470
|
+
end
|
471
|
+
end
|
441
472
|
end
|
442
473
|
end
|
443
474
|
end
|
@@ -0,0 +1,381 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'optparse'
|
3
|
+
require 'filesize'
|
4
|
+
require 'table_print'
|
5
|
+
require 'morpheus/cli/cli_command'
|
6
|
+
|
7
|
+
class Morpheus::Cli::PreseedScriptsCommand
|
8
|
+
include Morpheus::Cli::CliCommand
|
9
|
+
|
10
|
+
#set_command_name :'preseed-scripts'
|
11
|
+
# lives under image-builder domain right now
|
12
|
+
set_command_hidden
|
13
|
+
def command_name
|
14
|
+
"image-builder preseed-scripts"
|
15
|
+
end
|
16
|
+
|
17
|
+
register_subcommands :list, :get, :add, :update, :remove
|
18
|
+
|
19
|
+
# set_default_subcommand :list
|
20
|
+
|
21
|
+
def initialize()
|
22
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
23
|
+
end
|
24
|
+
|
25
|
+
def connect(opts)
|
26
|
+
@api_client = establish_remote_appliance_connection(opts)
|
27
|
+
@image_builder_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).image_builder
|
28
|
+
@preseed_scripts_interface = @image_builder_interface.preseed_scripts
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle(args)
|
32
|
+
handle_subcommand(args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def list(args)
|
36
|
+
options = {}
|
37
|
+
optparse = OptionParser.new do|opts|
|
38
|
+
opts.banner = subcommand_usage()
|
39
|
+
build_common_options(opts, options, [:list, :json, :dry_run])
|
40
|
+
end
|
41
|
+
optparse.parse!(args)
|
42
|
+
connect(options)
|
43
|
+
begin
|
44
|
+
params = {}
|
45
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
46
|
+
params[k] = options[k] unless options[k].nil?
|
47
|
+
end
|
48
|
+
|
49
|
+
if options[:dry_run]
|
50
|
+
print_dry_run @preseed_scripts_interface.dry.list(params)
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
json_response = @preseed_scripts_interface.list(params)
|
55
|
+
if options[:json]
|
56
|
+
print JSON.pretty_generate(json_response)
|
57
|
+
print "\n"
|
58
|
+
return
|
59
|
+
end
|
60
|
+
preseed_scripts = json_response['preseedScripts']
|
61
|
+
title = "Morpheus Preseed Scripts"
|
62
|
+
subtitles = []
|
63
|
+
if params[:phrase]
|
64
|
+
subtitles << "Search: #{params[:phrase]}".strip
|
65
|
+
end
|
66
|
+
print_h1 title, subtitles
|
67
|
+
if preseed_scripts.empty?
|
68
|
+
print cyan,"No preseed scripts found.",reset,"\n"
|
69
|
+
else
|
70
|
+
rows = preseed_scripts.collect {|preseed_script|
|
71
|
+
row = {
|
72
|
+
id: preseed_script['id'],
|
73
|
+
name: preseed_script['fileName']
|
74
|
+
}
|
75
|
+
row
|
76
|
+
}
|
77
|
+
columns = [:id, :name]
|
78
|
+
if options[:include_fields]
|
79
|
+
columns = options[:include_fields]
|
80
|
+
end
|
81
|
+
print cyan
|
82
|
+
print as_pretty_table(rows, columns, options)
|
83
|
+
print reset
|
84
|
+
print_results_pagination(json_response)
|
85
|
+
end
|
86
|
+
print reset,"\n"
|
87
|
+
rescue RestClient::Exception => e
|
88
|
+
print_rest_exception(e, options)
|
89
|
+
exit 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get(args)
|
94
|
+
options = {}
|
95
|
+
optparse = OptionParser.new do|opts|
|
96
|
+
opts.banner = subcommand_usage("[preseed-script]")
|
97
|
+
build_common_options(opts, options, [:json, :dry_run])
|
98
|
+
end
|
99
|
+
optparse.parse!(args)
|
100
|
+
if args.count < 1
|
101
|
+
print_error Morpheus::Terminal.angry_prompt
|
102
|
+
puts_error "#{command_name} missing argument: [preseed-script]\n#{optparse}"
|
103
|
+
return 1
|
104
|
+
end
|
105
|
+
connect(options)
|
106
|
+
begin
|
107
|
+
if options[:dry_run]
|
108
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
109
|
+
print_dry_run @preseed_scripts_interface.dry.get(args[0].to_i)
|
110
|
+
else
|
111
|
+
print_dry_run @preseed_scripts_interface.dry.list({name:args[0]})
|
112
|
+
end
|
113
|
+
return
|
114
|
+
end
|
115
|
+
preseed_script = find_preseed_script_by_name_or_id(args[0])
|
116
|
+
return 1 if preseed_script.nil?
|
117
|
+
json_response = {'preseedScript' => preseed_script} # skip redundant request
|
118
|
+
# json_response = @preseed_scripts_interface.get(preseed_script['id'])
|
119
|
+
preseed_script = json_response['preseedScript']
|
120
|
+
if options[:json]
|
121
|
+
print JSON.pretty_generate(json_response)
|
122
|
+
return
|
123
|
+
end
|
124
|
+
print_h1 "Preseed Script Details"
|
125
|
+
print cyan
|
126
|
+
description_cols = {
|
127
|
+
"ID" => 'id',
|
128
|
+
"Name" => 'fileName',
|
129
|
+
# "Description" => 'description',
|
130
|
+
# "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
131
|
+
# "Visibility" => lambda {|it| it['visibility'] ? it['visibility'].capitalize() : 'Private' },
|
132
|
+
}
|
133
|
+
print_description_list(description_cols, preseed_script)
|
134
|
+
|
135
|
+
print_h2 "Script"
|
136
|
+
print cyan
|
137
|
+
puts preseed_script['content']
|
138
|
+
|
139
|
+
print reset,"\n"
|
140
|
+
|
141
|
+
rescue RestClient::Exception => e
|
142
|
+
print_rest_exception(e, options)
|
143
|
+
return 1
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def add(args)
|
148
|
+
options = {}
|
149
|
+
optparse = OptionParser.new do|opts|
|
150
|
+
opts.banner = subcommand_usage("[fileName]")
|
151
|
+
build_option_type_options(opts, options, add_preseed_script_option_types(false))
|
152
|
+
build_common_options(opts, options, [:options, :json, :dry_run, :quiet])
|
153
|
+
end
|
154
|
+
optparse.parse!(args)
|
155
|
+
connect(options)
|
156
|
+
begin
|
157
|
+
options[:options] ||= {}
|
158
|
+
# support [preseed-script] as first argument still
|
159
|
+
if args[0]
|
160
|
+
options[:options]['fileName'] = args[0]
|
161
|
+
end
|
162
|
+
|
163
|
+
payload = {
|
164
|
+
'preseedScript' => {}
|
165
|
+
}
|
166
|
+
# prompt for Script Content unless --file is passed.
|
167
|
+
my_options = add_preseed_script_option_types()
|
168
|
+
if options[:options]['file']
|
169
|
+
my_options = my_options.reject {|it| it['fieldName'] == 'content' }
|
170
|
+
# elsif options[:options]['content']
|
171
|
+
# my_options = my_options.reject {|it| it['fieldName'] == 'file' }
|
172
|
+
else
|
173
|
+
my_options = my_options.reject {|it| it['fieldName'] == 'file' }
|
174
|
+
end
|
175
|
+
params = Morpheus::Cli::OptionTypes.prompt(my_options, options[:options], @api_client, options[:params])
|
176
|
+
script_file = params.delete('file')
|
177
|
+
if script_file
|
178
|
+
if !File.exists?(script_file)
|
179
|
+
print_red_alert "File not found: #{script_file}"
|
180
|
+
return 1
|
181
|
+
end
|
182
|
+
payload['preseedScript']['content'] = File.read(script_file)
|
183
|
+
end
|
184
|
+
payload['preseedScript'].merge!(params)
|
185
|
+
if options[:dry_run]
|
186
|
+
print_dry_run @preseed_scripts_interface.dry.create(payload)
|
187
|
+
return
|
188
|
+
end
|
189
|
+
json_response = @preseed_scripts_interface.create(payload)
|
190
|
+
if options[:json]
|
191
|
+
print JSON.pretty_generate(json_response)
|
192
|
+
print "\n"
|
193
|
+
elsif !options[:quiet]
|
194
|
+
print_green_success "Added image build #{payload['preseedScript']['fileName']}"
|
195
|
+
# list([])
|
196
|
+
preseed_script = json_response['preseedScript']
|
197
|
+
get([preseed_script['id']])
|
198
|
+
end
|
199
|
+
|
200
|
+
rescue RestClient::Exception => e
|
201
|
+
print_rest_exception(e, options)
|
202
|
+
exit 1
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def update(args)
|
207
|
+
options = {}
|
208
|
+
optparse = OptionParser.new do|opts|
|
209
|
+
opts.banner = subcommand_usage("[preseed-script] [options]")
|
210
|
+
build_option_type_options(opts, options, update_preseed_script_option_types(false))
|
211
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
212
|
+
end
|
213
|
+
optparse.parse!(args)
|
214
|
+
if args.count < 1
|
215
|
+
puts optparse
|
216
|
+
return 1
|
217
|
+
end
|
218
|
+
connect(options)
|
219
|
+
|
220
|
+
begin
|
221
|
+
preseed_script = find_preseed_script_by_name_or_id(args[0])
|
222
|
+
|
223
|
+
payload = {
|
224
|
+
'preseedScript' => {id: preseed_script["id"]}
|
225
|
+
}
|
226
|
+
|
227
|
+
params = options[:options] || {}
|
228
|
+
#puts "parsed params is : #{params.inspect}"
|
229
|
+
params = params.select {|k,v| params[k].to_s != "" }
|
230
|
+
if params.empty?
|
231
|
+
print_red_alert "Specify atleast one option to update"
|
232
|
+
puts optparse
|
233
|
+
return 1
|
234
|
+
end
|
235
|
+
|
236
|
+
# prompt for Script Content unless --file is passed.
|
237
|
+
# my_options = add_preseed_script_option_types()
|
238
|
+
# if options[:options]['file']
|
239
|
+
# my_options = my_options.reject {|it| it['fieldName'] == 'content' }
|
240
|
+
# # elsif options[:options]['content']
|
241
|
+
# # my_options = my_options.reject {|it| it['fieldName'] == 'file' }
|
242
|
+
# else
|
243
|
+
# my_options = my_options.reject {|it| it['fieldName'] == 'file' }
|
244
|
+
# end
|
245
|
+
# params = Morpheus::Cli::OptionTypes.prompt(my_options, options[:options], @api_client, options[:params])
|
246
|
+
script_file = params.delete('file')
|
247
|
+
if script_file
|
248
|
+
if !File.exists?(script_file)
|
249
|
+
print_red_alert "File not found: #{script_file}"
|
250
|
+
return 1
|
251
|
+
end
|
252
|
+
payload['preseedScript']['content'] = File.read(script_file)
|
253
|
+
end
|
254
|
+
payload['preseedScript'].merge!(params)
|
255
|
+
|
256
|
+
if options[:dry_run]
|
257
|
+
print_dry_run @preseed_scripts_interface.dry.update(preseed_script["id"], payload)
|
258
|
+
return
|
259
|
+
end
|
260
|
+
|
261
|
+
json_response = @preseed_scripts_interface.update(preseed_script["id"], payload)
|
262
|
+
if options[:json]
|
263
|
+
print JSON.pretty_generate(json_response)
|
264
|
+
print "\n"
|
265
|
+
else
|
266
|
+
print_green_success "Updated preseed script #{preseed_script['fileName']}"
|
267
|
+
get([preseed_script['id']])
|
268
|
+
end
|
269
|
+
return 0
|
270
|
+
rescue RestClient::Exception => e
|
271
|
+
print_rest_exception(e, options)
|
272
|
+
return 1
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def remove(args)
|
277
|
+
options = {}
|
278
|
+
optparse = OptionParser.new do|opts|
|
279
|
+
opts.banner = subcommand_usage("[preseed-script]")
|
280
|
+
build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run])
|
281
|
+
end
|
282
|
+
optparse.parse!(args)
|
283
|
+
|
284
|
+
if args.count < 1
|
285
|
+
print_error Morpheus::Terminal.angry_prompt
|
286
|
+
puts_error "#{command_name} missing argument: [preseed-script]\n#{optparse}"
|
287
|
+
return 1
|
288
|
+
end
|
289
|
+
|
290
|
+
connect(options)
|
291
|
+
begin
|
292
|
+
preseed_script = find_preseed_script_by_name_or_id(args[0])
|
293
|
+
return 1 if preseed_script.nil?
|
294
|
+
|
295
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the preseed script: #{preseed_script['fileName']}?")
|
296
|
+
return 9, "aborted command"
|
297
|
+
end
|
298
|
+
if options[:dry_run]
|
299
|
+
print_dry_run @preseed_scripts_interface.dry.destroy(preseed_script['id'])
|
300
|
+
return 0
|
301
|
+
end
|
302
|
+
json_response = @preseed_scripts_interface.destroy(preseed_script['id'])
|
303
|
+
if options[:json]
|
304
|
+
print JSON.pretty_generate(json_response)
|
305
|
+
print "\n"
|
306
|
+
else
|
307
|
+
print_green_success "Removed preseed script #{preseed_script['fileName']}"
|
308
|
+
# list([])
|
309
|
+
end
|
310
|
+
return 0
|
311
|
+
rescue RestClient::Exception => e
|
312
|
+
print_rest_exception(e, options)
|
313
|
+
return 1
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
private
|
318
|
+
|
319
|
+
def get_available_preseed_script_types()
|
320
|
+
[{'name' => 'VMware', 'value' => 'vmware'}]
|
321
|
+
end
|
322
|
+
|
323
|
+
def add_preseed_script_option_types(connected=true)
|
324
|
+
[
|
325
|
+
{'fieldName' => 'fileName', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for this script.'},
|
326
|
+
# {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false},
|
327
|
+
{'fieldName' => 'file', 'fieldLabel' => 'Script File', 'type' => 'file', 'required' => false, 'description' => 'Set script contents to that of a local file.'},
|
328
|
+
{'fieldName' => 'content', 'fieldLabel' => 'Script', 'type' => 'code-editor', 'required' => true},
|
329
|
+
]
|
330
|
+
end
|
331
|
+
|
332
|
+
def update_preseed_script_option_types(connected=true)
|
333
|
+
list = add_preseed_script_option_types(connected)
|
334
|
+
# list = list.reject {|it| ["group"].include? it['fieldName'] }
|
335
|
+
list.each {|it| it['required'] = false }
|
336
|
+
list
|
337
|
+
end
|
338
|
+
|
339
|
+
def find_preseed_script_by_name_or_id(val)
|
340
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
341
|
+
return find_preseed_script_by_id(val)
|
342
|
+
else
|
343
|
+
return find_preseed_script_by_name(val)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def find_preseed_script_by_id(id)
|
348
|
+
begin
|
349
|
+
json_response = @preseed_scripts_interface.get(id.to_i)
|
350
|
+
return json_response['preseedScript']
|
351
|
+
rescue RestClient::Exception => e
|
352
|
+
if e.response && e.response.code == 404
|
353
|
+
print_red_alert "Preseed Script not found by id #{id}"
|
354
|
+
return nil
|
355
|
+
else
|
356
|
+
raise e
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def find_preseed_script_by_name(name)
|
362
|
+
preseed_scripts = @preseed_scripts_interface.list({name: name.to_s})['preseedScripts']
|
363
|
+
if preseed_scripts.empty?
|
364
|
+
print_red_alert "Preseed Script not found by name #{name}"
|
365
|
+
return nil
|
366
|
+
elsif preseed_scripts.size > 1
|
367
|
+
print_red_alert "#{preseed_scripts.size} preseed scripts found by name #{name}"
|
368
|
+
# print_preseed_scripts_table(preseed_scripts, {color: red})
|
369
|
+
rows = preseed_scripts.collect do |preseed_script|
|
370
|
+
{id: it['id'], name: it['fileName']}
|
371
|
+
end
|
372
|
+
print red
|
373
|
+
tp rows, [:id, :name]
|
374
|
+
print reset,"\n"
|
375
|
+
return nil
|
376
|
+
else
|
377
|
+
return preseed_scripts[0]
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
end
|