morpheus-cli 2.12.5 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +5 -0
  3. data/lib/morpheus/api/api_client.rb +15 -30
  4. data/lib/morpheus/api/app_templates_interface.rb +34 -7
  5. data/lib/morpheus/api/apps_interface.rb +20 -1
  6. data/lib/morpheus/api/archive_buckets_interface.rb +124 -0
  7. data/lib/morpheus/api/archive_files_interface.rb +182 -0
  8. data/lib/morpheus/api/{network_pools_interface.rb → image_builder_boot_scripts_interface.rb} +6 -6
  9. data/lib/morpheus/api/{policies_interface.rb → image_builder_image_builds_interface.rb} +20 -15
  10. data/lib/morpheus/api/image_builder_interface.rb +26 -0
  11. data/lib/morpheus/api/{network_proxies_interface.rb → image_builder_preseed_scripts_interface.rb} +6 -6
  12. data/lib/morpheus/cli.rb +10 -9
  13. data/lib/morpheus/cli/alias_command.rb +10 -9
  14. data/lib/morpheus/cli/app_templates.rb +1566 -457
  15. data/lib/morpheus/cli/apps.rb +284 -108
  16. data/lib/morpheus/cli/archives_command.rb +2184 -0
  17. data/lib/morpheus/cli/boot_scripts_command.rb +382 -0
  18. data/lib/morpheus/cli/cli_command.rb +9 -35
  19. data/lib/morpheus/cli/error_handler.rb +2 -0
  20. data/lib/morpheus/cli/hosts.rb +15 -3
  21. data/lib/morpheus/cli/image_builder_command.rb +1208 -0
  22. data/lib/morpheus/cli/instances.rb +118 -47
  23. data/lib/morpheus/cli/man_command.rb +27 -24
  24. data/lib/morpheus/cli/mixins/print_helper.rb +19 -5
  25. data/lib/morpheus/cli/mixins/provisioning_helper.rb +20 -20
  26. data/lib/morpheus/cli/option_types.rb +45 -14
  27. data/lib/morpheus/cli/preseed_scripts_command.rb +381 -0
  28. data/lib/morpheus/cli/remote.rb +1 -0
  29. data/lib/morpheus/cli/roles.rb +2 -2
  30. data/lib/morpheus/cli/shell.rb +3 -2
  31. data/lib/morpheus/cli/version.rb +1 -1
  32. data/lib/morpheus/ext/hash.rb +22 -0
  33. data/lib/morpheus/formatters.rb +33 -0
  34. data/lib/morpheus/terminal.rb +1 -1
  35. metadata +13 -21
  36. data/lib/morpheus/api/cloud_policies_interface.rb +0 -47
  37. data/lib/morpheus/api/group_policies_interface.rb +0 -47
  38. data/lib/morpheus/api/network_domains_interface.rb +0 -47
  39. data/lib/morpheus/api/network_groups_interface.rb +0 -47
  40. data/lib/morpheus/api/network_pool_servers_interface.rb +0 -47
  41. data/lib/morpheus/api/network_services_interface.rb +0 -47
  42. data/lib/morpheus/api/networks_interface.rb +0 -54
  43. data/lib/morpheus/cli/network_domains_command.rb +0 -571
  44. data/lib/morpheus/cli/network_groups_command.rb +0 -602
  45. data/lib/morpheus/cli/network_pool_servers_command.rb +0 -430
  46. data/lib/morpheus/cli/network_pools_command.rb +0 -495
  47. data/lib/morpheus/cli/network_proxies_command.rb +0 -594
  48. data/lib/morpheus/cli/network_services_command.rb +0 -148
  49. data/lib/morpheus/cli/networks_command.rb +0 -855
  50. data/lib/morpheus/cli/policies_command.rb +0 -847
  51. 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
- type_payload = Morpheus::Cli::OptionTypes.prompt(layout['optionTypes'],options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
295
- payload.deep_merge!(type_payload)
296
- elsif !instance_type['optionTypes'].nil? && !instance_type['optionTypes'].empty?
297
- type_payload = Morpheus::Cli::OptionTypes.prompt(instance_type['optionTypes'],options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
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
- instance_type_option_types = layout['provisionType']['optionTypes']
303
- # remove volume options if volumes were configured
304
- if !payload['volumes'].empty?
305
- instance_type_option_types = reject_volume_option_types(instance_type_option_types)
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'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
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| select_options.clone.collect{|opt| opt['name']}.grep(/^#{Regexp.escape(s)}/)}
262
- input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
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'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
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'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''} [Type 'EOF' to stop input]: \n"
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'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}: "
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'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
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'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
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
- print Term::ANSIColor.green," * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
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
- puts "\nOptions"
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