morpheus-cli 2.10.1 → 2.10.2

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.
@@ -11,7 +11,7 @@ class Morpheus::Cli::Instances
11
11
  include Morpheus::Cli::CliCommand
12
12
  include Morpheus::Cli::ProvisioningHelper
13
13
 
14
- register_subcommands :list, :get, :add, :update, :remove, :stats, :stop, :start, :restart, :suspend, :eject, :backup, :backups, :stop_service, :start_service, :restart_service, :resize, :upgrade, :clone, :envs, :setenv, :delenv, :security_groups, :apply_security_groups, :firewall_enable, :firewall_disable, :run_workflow, :import_snapshot, :console, :status_check
14
+ register_subcommands :list, :get, :add, :update, :remove, :stats, :stop, :start, :restart, :suspend, :eject, :backup, :backups, :stop_service, :start_service, :restart_service, :resize, :clone, :envs, :setenv, :delenv, :security_groups, :apply_security_groups, :firewall_enable, :firewall_disable, :run_workflow, :import_snapshot, :console, :status_check
15
15
  alias_subcommand :details, :get
16
16
  set_default_subcommand :list
17
17
 
@@ -446,6 +446,67 @@ class Morpheus::Cli::Instances
446
446
  end
447
447
  end
448
448
 
449
+ def clone(args)
450
+ options = {}
451
+ optparse = OptionParser.new do|opts|
452
+ opts.banner = subcommand_usage("[name] -g GROUP")
453
+ build_option_type_options(opts, options, clone_instance_option_types(false))
454
+ opts.on( '-g', '--group GROUP', "Group Name or ID for the new instance" ) do |val|
455
+ options[:group] = val
456
+ end
457
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
458
+ end
459
+ optparse.parse!(args)
460
+ if args.count < 1
461
+ puts optparse
462
+ exit 1
463
+ end
464
+ if !options[:group]
465
+ print_red_alert "GROUP is required."
466
+ puts optparse
467
+ exit 1
468
+ end
469
+ connect(options)
470
+ begin
471
+ options[:options] ||= {}
472
+ # use the -g GROUP or active group by default
473
+ options[:options]['group'] ||= options[:group] # || @active_group_id # always choose a group for now?
474
+ # support [new-name]
475
+ # if args[1]
476
+ # options[:options]['name'] = args[1]
477
+ # end
478
+ payload = {
479
+
480
+ }
481
+ params = Morpheus::Cli::OptionTypes.prompt(clone_instance_option_types, options[:options], @api_client, options[:params])
482
+ group = find_group_by_name_or_id_for_provisioning(params.delete('group'))
483
+ payload.merge!(params)
484
+ payload['group'] = {id: group['id']}
485
+
486
+ instance = find_instance_by_name_or_id(args[0])
487
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to clone the instance '#{instance['name']}'?", options)
488
+ exit 1
489
+ end
490
+
491
+ if options[:dry_run]
492
+ print_dry_run @instances_interface.dry.clone(instance['id'], payload)
493
+ return
494
+ end
495
+ json_response = @instances_interface.clone(instance['id'], payload)
496
+ if options[:json]
497
+ print JSON.pretty_generate(json_response)
498
+ print "\n"
499
+ else
500
+ print_green_success "Cloning instance #{instance['name']} to '#{payload['name']}'"
501
+ end
502
+ return
503
+ rescue RestClient::Exception => e
504
+ print_rest_exception(e, options)
505
+ exit 1
506
+ end
507
+ end
508
+
509
+
449
510
  def envs(args)
450
511
  options = {}
451
512
  optparse = OptionParser.new do|opts|
@@ -904,11 +965,11 @@ class Morpheus::Cli::Instances
904
965
  opts.banner = subcommand_usage("[name]")
905
966
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
906
967
  end
968
+ optparse.parse!(args)
907
969
  if args.count < 1
908
970
  puts optparse
909
971
  exit 1
910
972
  end
911
- optparse.parse!(args)
912
973
  connect(options)
913
974
  begin
914
975
  instance = find_instance_by_name_or_id(args[0])
@@ -1017,11 +1078,11 @@ class Morpheus::Cli::Instances
1017
1078
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
1018
1079
 
1019
1080
  end
1081
+ optparse.parse!(args)
1020
1082
  if args.count < 1
1021
1083
  puts "\n#{optparse}\n\n"
1022
1084
  exit 1
1023
1085
  end
1024
- optparse.parse!(args)
1025
1086
  connect(options)
1026
1087
  begin
1027
1088
  instance = find_instance_by_name_or_id(args[0])
@@ -1051,11 +1112,11 @@ class Morpheus::Cli::Instances
1051
1112
  opts.banner = subcommand_usage("[name]")
1052
1113
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
1053
1114
  end
1115
+ optparse.parse!(args)
1054
1116
  if args.count < 1
1055
1117
  puts optparse
1056
1118
  exit 1
1057
1119
  end
1058
- optparse.parse!(args)
1059
1120
  connect(options)
1060
1121
  begin
1061
1122
  instance = find_instance_by_name_or_id(args[0])
@@ -1082,11 +1143,11 @@ class Morpheus::Cli::Instances
1082
1143
  opts.banner = subcommand_usage("[name]")
1083
1144
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
1084
1145
  end
1146
+ optparse.parse!(args)
1085
1147
  if args.count < 1
1086
1148
  puts optparse
1087
1149
  exit 1
1088
1150
  end
1089
- optparse.parse!(args)
1090
1151
  connect(options)
1091
1152
  begin
1092
1153
  instance = find_instance_by_name_or_id(args[0])
@@ -1113,11 +1174,11 @@ class Morpheus::Cli::Instances
1113
1174
  opts.banner = subcommand_usage("[name]")
1114
1175
  build_common_options(opts, options, [:json, :dry_run, :remote])
1115
1176
  end
1177
+ optparse.parse!(args)
1116
1178
  if args.count < 1
1117
1179
  puts optparse
1118
1180
  exit 1
1119
1181
  end
1120
- optparse.parse!(args)
1121
1182
  connect(options)
1122
1183
  begin
1123
1184
  instance = find_instance_by_name_or_id(args[0])
@@ -1204,11 +1265,11 @@ class Morpheus::Cli::Instances
1204
1265
  opts.banner = subcommand_usage("[name] [workflow] [options]")
1205
1266
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
1206
1267
  end
1268
+ optparse.parse!(args)
1207
1269
  if args.count < 2
1208
1270
  puts "\n#{optparse}\n\n"
1209
1271
  exit 1
1210
1272
  end
1211
- optparse.parse!(args)
1212
1273
  connect(options)
1213
1274
  instance = find_instance_by_name_or_id(args[0])
1214
1275
  workflow = find_workflow_by_name(args[1])
@@ -1263,11 +1324,11 @@ class Morpheus::Cli::Instances
1263
1324
  end
1264
1325
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
1265
1326
  end
1327
+ optparse.parse!(args)
1266
1328
  if args.count < 1
1267
1329
  puts optparse
1268
1330
  exit 1
1269
1331
  end
1270
- optparse.parse!(args)
1271
1332
  connect(options)
1272
1333
  begin
1273
1334
  instance = find_instance_by_name_or_id(args[0])
@@ -1383,4 +1444,11 @@ class Morpheus::Cli::Instances
1383
1444
  end
1384
1445
  out
1385
1446
  end
1447
+
1448
+ def clone_instance_option_types(connected=true)
1449
+ [
1450
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for the new instance'},
1451
+ {'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'selectOptions' => (connected ? get_available_groups() : []), 'required' => true},
1452
+ ]
1453
+ end
1386
1454
  end
@@ -0,0 +1,51 @@
1
+ require 'optparse'
2
+ require 'morpheus/cli/cli_command'
3
+ require 'json'
4
+
5
+ class Morpheus::Cli::LogLevelCommand
6
+ include Morpheus::Cli::CliCommand
7
+ set_command_name :'log-level' # :log_level
8
+ set_command_hidden
9
+
10
+ def handle(args)
11
+ options = {}
12
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
13
+ opts.banner = "Usage: morpheus #{command_name} [debug|info|0|1]"
14
+ #build_common_options(opts, options, [])
15
+ opts.on('-h', '--help', "Prints this help" ) do
16
+ puts opts
17
+ exit
18
+ end
19
+ opts.footer = <<-EOT
20
+ This is intended for use in your morpheus scripts.
21
+ It allows you to set the global logging level.
22
+ The only available levels right now are debug [0] and info [1].
23
+ The default is info [1].
24
+ EOT
25
+ end
26
+ optparse.parse!(args)
27
+ if args.count == 0
28
+ puts "#{Morpheus::Logging.log_level}"
29
+ return true
30
+ end
31
+ if args.count > 1
32
+ puts optparse
33
+ return false
34
+ end
35
+ if ["debug", "0"].include?(args[0].to_s.strip.downcase)
36
+ Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
37
+ ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
38
+ elsif ["info", "1"].include?(args[0].to_s.strip.downcase)
39
+ Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::INFO)
40
+ ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
41
+ elsif args[0].to_i < 6
42
+ Morpheus::Logging.set_log_level(args[0].to_i)
43
+ ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
44
+ else
45
+ puts optparse
46
+ return false
47
+ end
48
+ return true
49
+ end
50
+
51
+ end
@@ -7,12 +7,8 @@ module Morpheus
7
7
  # not used yet, maybe ever =o
8
8
  class Morpheus::Cli::OptionParser < OptionParser
9
9
 
10
- attr_reader :footer
10
+ attr_accessor :footer
11
11
 
12
- def footer=(msg)
13
- @footer = msg
14
- end
15
-
16
12
  alias :original_to_s :to_s
17
13
 
18
14
  def to_s
@@ -21,10 +17,20 @@ module Morpheus
21
17
 
22
18
  def full_help_message
23
19
  out = ""
24
- out << original_to_s
20
+ #out << original_to_s
21
+ if banner
22
+ out << "#{banner}".sub(/\n?\z/, "\n")
23
+ end
24
+ if !self.to_a.empty?
25
+ #out << "Options:\n"
26
+ out << summarize().join("")
27
+ end
25
28
  if footer
26
- out << footer.to_s.strip
29
+ # nice_footer = footer.split("\n").collect {|line| "#{summary_indent}#{line}" }.join("\n")
30
+ nice_footer = footer
27
31
  out << "\n"
32
+ out << "#{nice_footer}".sub(/\n?\z/, "\n")
33
+ # out << "\n"
28
34
  end
29
35
  out
30
36
  end
@@ -13,358 +13,378 @@ module Morpheus
13
13
  default_value = options[:default]
14
14
  value_found = false
15
15
  while value_found == false do
16
- if default_value.nil?
17
- print "#{message} (yes/no): "
18
- else
19
- print "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
20
- end
21
- input = $stdin.gets.chomp!
22
- if input.empty? && !default_value.nil?
23
- return !!default_value
24
- end
25
- if input.downcase == 'yes' || input.downcase == 'y'
26
- return true
27
- elsif input.downcase == 'no' || input.downcase == 'n'
28
- return false
29
- else
30
- puts "Invalid Option... Please try again."
31
- end
16
+ if default_value.nil?
17
+ print "#{message} (yes/no): "
18
+ else
19
+ print "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
20
+ end
21
+ input = $stdin.gets.chomp!
22
+ if input.empty? && !default_value.nil?
23
+ return !!default_value
24
+ end
25
+ if input.downcase == 'yes' || input.downcase == 'y'
26
+ return true
27
+ elsif input.downcase == 'no' || input.downcase == 'n'
28
+ return false
29
+ else
30
+ puts "Invalid Option... Please try again."
32
31
  end
33
32
  end
33
+ end
34
34
 
35
- def self.prompt(option_types, options={}, api_client=nil,api_params={}, no_prompt=false)
36
- results = {}
37
- options = options || {}
38
- # puts "Options Prompt #{options}"
39
- option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i }.each do |option_type|
40
- context_map = results
41
- value = nil
42
- value_found=false
43
- if option_type['fieldContext']
44
- results[option_type['fieldContext']] ||= {}
45
- context_map = results[option_type['fieldContext']]
46
- if options[option_type['fieldContext']] and options[option_type['fieldContext']].key?(option_type['fieldName'])
47
- value = options[option_type['fieldContext']][option_type['fieldName']]
48
- if option_type['type'] == 'number'
49
- value = value.to_i
50
- end
51
- value_found = true
52
- end
53
- end
54
-
55
- if value_found == false && options.key?(option_type['fieldName'])
56
- value = options[option_type['fieldName']]
35
+ def self.prompt(option_types, options={}, api_client=nil,api_params={}, no_prompt=false)
36
+ results = {}
37
+ options = options || {}
38
+ # puts "Options Prompt #{options}"
39
+ option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i }.each do |option_type|
40
+ context_map = results
41
+ value = nil
42
+ value_found=false
43
+ if option_type['fieldContext']
44
+ results[option_type['fieldContext']] ||= {}
45
+ context_map = results[option_type['fieldContext']]
46
+ if options[option_type['fieldContext']] and options[option_type['fieldContext']].key?(option_type['fieldName'])
47
+ value = options[option_type['fieldContext']][option_type['fieldName']]
57
48
  if option_type['type'] == 'number'
58
49
  value = value.to_i
59
50
  end
60
51
  value_found = true
61
52
  end
62
-
63
- # no_prompt means skip prompting and instead
64
- # use default value or error if a required option is not present
65
- no_prompt = no_prompt || options[:no_prompt]
66
- if no_prompt
67
- if !value_found
68
- if option_type['defaultValue']
69
- value = option_type['defaultValue']
70
- value_found = true
71
- end
72
- if !value_found
73
- # select type is special because it supports skipSingleOption
74
- # and prints the available options on error
75
- if option_type['type'] == 'select'
76
- value = select_prompt(option_type, api_client, api_params, true)
77
- value_found = !!value
78
- end
79
- if !value_found
80
- if option_type['required']
81
- print Term::ANSIColor.red, "\nMissing Required Option\n\n"
82
- print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
83
- print "\n"
84
- exit 1
85
- else
86
- next
87
- end
88
- end
89
- end
90
- end
91
- end
92
-
93
- if !value_found
94
- if option_type['type'] == 'number'
95
- value = number_prompt(option_type)
96
- elsif option_type['type'] == 'password'
97
- value = password_prompt(option_type)
98
- elsif option_type['type'] == 'checkbox'
99
- value = checkbox_prompt(option_type)
100
- elsif option_type['type'] == 'radio'
101
- value = radio_prompt(option_type)
102
- elsif option_type['type'] == 'textarea'
103
- value = multiline_prompt(option_type)
104
- elsif option_type['type'] == 'code-editor'
105
- value = multiline_prompt(option_type)
106
- elsif option_type['type'] == 'select'
107
- value = select_prompt(option_type,api_client, api_params)
108
- elsif option_type['type'] == 'hidden'
109
- value = option_type['defaultValue']
110
- input = value
111
- elsif option_type['type'] == 'file'
112
- value = file_prompt(option_type)
113
- else
114
- value = generic_prompt(option_type)
115
- end
116
- end
117
- context_map[option_type['fieldName']] = value
118
53
  end
119
54
 
120
- return results
121
- end
122
-
123
-
124
- def self.radio_prompt(option_type)
125
- value_found = false
126
- value = nil
127
- options = []
128
- if option_type['config'] and option_type['config']['radioOptions']
129
- option_type['config']['radioOptions'].each do |radio_option|
130
- options << {key: radio_option['key'], checked: radio_option['checked']}
131
- end
132
- end
133
- optionString = options.collect{ |b| b[:checked] ? "(#{b[:key]})" : b[:key]}.join(', ')
134
- while !value_found do
135
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }[#{optionString}]: "
136
- input = $stdin.gets.chomp!
137
- if input == '?'
138
- help_prompt(option_type)
139
- else
140
- if input.nil? || input.empty?
141
- selectedOption = options.find{|o| o[:checked] == true}
142
- else
143
- selectedOption = options.find{|o| o[:key].downcase == input.downcase}
144
- end
145
- if selectedOption
146
- value = selectedOption[:key]
147
- else
148
- puts "Invalid Option. Please select from #{optionString}."
149
- end
150
- if !value.nil? || option_type['required'] != true
151
- value_found = true
152
- end
153
- end
55
+ if value_found == false && options.key?(option_type['fieldName'])
56
+ value = options[option_type['fieldName']]
57
+ if option_type['type'] == 'number'
58
+ value = value.to_i
154
59
  end
155
- return value
60
+ value_found = true
156
61
  end
157
62
 
158
- def self.number_prompt(option_type)
159
- value_found = false
160
- value = nil
161
- while !value_found do
162
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
163
- input = $stdin.gets.chomp!
164
- value = input.empty? ? option_type['defaultValue'] : input.to_i
165
- if input == '?'
166
- help_prompt(option_type)
167
- elsif !value.nil? || option_type['required'] != true
168
- value_found = true
169
- end
170
- end
171
- return value
172
- end
173
-
174
- def self.select_prompt(option_type,api_client, api_params={}, no_prompt=false)
175
- value_found = false
176
- value = nil
177
- if option_type['selectOptions']
178
- select_options = option_type['selectOptions']
179
- elsif option_type['optionSource']
180
- select_options = load_source_options(option_type['optionSource'],api_client,api_params)
181
- else
182
- raise "select_prompt() requires selectOptions or optionSource!"
183
- end
184
- if !select_options.nil? && select_options.count == 1 && option_type['skipSingleOption'] == true
63
+ # no_prompt means skip prompting and instead
64
+ # use default value or error if a required option is not present
65
+ no_prompt = no_prompt || options[:no_prompt]
66
+ if no_prompt
67
+ if !value_found
68
+ if option_type['defaultValue']
69
+ value = option_type['defaultValue']
185
70
  value_found = true
186
- value = select_options[0]['value']
187
71
  end
188
- if no_prompt
72
+ if !value_found
73
+ # select type is special because it supports skipSingleOption
74
+ # and prints the available options on error
75
+ if option_type['type'] == 'select'
76
+ value = select_prompt(option_type, api_client, api_params, true)
77
+ value_found = !!value
78
+ end
189
79
  if !value_found
190
80
  if option_type['required']
191
81
  print Term::ANSIColor.red, "\nMissing Required Option\n\n"
192
82
  print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
193
- display_select_options(select_options)
194
83
  print "\n"
195
84
  exit 1
196
85
  else
197
- return nil
86
+ next
198
87
  end
199
88
  end
200
89
  end
201
- while !value_found do
202
- Readline.completion_append_character = ""
203
- Readline.basic_word_break_characters = ''
204
- Readline.completion_proc = proc {|s| select_options.clone.collect{|opt| opt['name']}.grep(/^#{Regexp.escape(s)}/)}
205
- input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
206
- input = input.chomp.strip
207
- if input.empty?
208
- value = option_type['defaultValue']
209
- else
210
- select_option = select_options.find{|b| b['name'] == input || (!b['value'].nil? && b['value'].to_s == input) || (b['value'].nil? && input.empty?)}
211
- if select_option
212
- value = select_option['value']
213
- elsif !input.nil? && !input.empty?
214
- input = '?'
215
- end
216
- end
217
- if input == '?'
218
- help_prompt(option_type)
219
- display_select_options(select_options)
220
- elsif !value.nil? || option_type['required'] != true
221
- value_found = true
222
- end
90
+ end
91
+ end
92
+
93
+ if !value_found
94
+ if option_type['type'] == 'number'
95
+ value = number_prompt(option_type)
96
+ elsif option_type['type'] == 'password'
97
+ value = password_prompt(option_type)
98
+ elsif option_type['type'] == 'checkbox'
99
+ value = checkbox_prompt(option_type)
100
+ elsif option_type['type'] == 'radio'
101
+ value = radio_prompt(option_type)
102
+ elsif option_type['type'] == 'textarea'
103
+ value = multiline_prompt(option_type)
104
+ elsif option_type['type'] == 'code-editor'
105
+ value = multiline_prompt(option_type)
106
+ elsif option_type['type'] == 'select'
107
+ # so, the /api/options/source is may need ALL the previously
108
+ # selected values that are being accumulated in options
109
+ # api_params is just extra params to always send
110
+ # I suppose the entered value should take precedence
111
+ # api_params = api_params.merge(options) # this might be good enough
112
+ # dup it
113
+ select_api_params = {}.merge(api_params || {})
114
+ results.each do |k,v|
115
+ if v.is_a?(Hash)
116
+ # grailsify params k.k2, otherwise you'll get bracked param names like k[k2]
117
+ v.each {|k2, v2|
118
+ select_api_params["#{k}.#{k2}"] = v2
119
+ }
120
+ else
121
+ # could be String/Symbol duplication issues here.
122
+ select_api_params.delete(k.to_sym)
123
+ select_api_params[k.to_s] = v
223
124
  end
224
- return value
225
125
  end
126
+ value = select_prompt(option_type,api_client, select_api_params)
127
+ elsif option_type['type'] == 'hidden'
128
+ value = option_type['defaultValue']
129
+ input = value
130
+ elsif option_type['type'] == 'file'
131
+ value = file_prompt(option_type)
132
+ else
133
+ value = generic_prompt(option_type)
134
+ end
135
+ end
136
+ context_map[option_type['fieldName']] = value
137
+ end
226
138
 
227
- def self.checkbox_prompt(option_type)
228
- value_found = false
229
- value = nil
230
- while !value_found do
231
- print "#{option_type['fieldLabel']} (yes/no) [#{option_type['defaultValue'] == 'on' ? 'yes' : 'no'}]: "
232
- input = $stdin.gets.chomp!
233
- if input.downcase == 'yes'
234
- value = 'on'
235
- elsif input.downcase == 'no'
236
- value = 'off'
237
- else
238
- value = option_type['defaultValue']
239
- end
240
- if input == '?'
241
- help_prompt(option_type)
242
- elsif !value.nil? || option_type['required'] != true
243
- value_found = true
244
- end
245
- end
246
- return value
247
- end
139
+ return results
140
+ end
248
141
 
249
- def self.generic_prompt(option_type)
250
- value_found = false
251
- value = nil
252
- while !value_found do
253
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
254
- input = $stdin.gets.chomp!
255
- value = input.empty? ? option_type['defaultValue'] : input
256
- if input == '?'
257
- help_prompt(option_type)
258
- elsif !value.nil? || option_type['required'] != true
259
- value_found = true
260
- end
261
- end
262
- return value
263
- end
264
142
 
265
- def self.multiline_prompt(option_type)
266
- value_found = false
267
- value = nil
268
- while !value_found do
269
- if value.nil?
270
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''} [Type 'EOF' to stop input]: \n"
271
- end
272
- input = $stdin.gets.chomp!
273
- # value = input.empty? ? option_type['defaultValue'] : input
274
- if input == '?' && value.nil?
275
- help_prompt(option_type)
276
- elsif (!value.nil? || option_type['required'] != true) && input.chomp == 'EOF'
277
- value_found = true
278
- else
279
- if value.nil?
280
- value = ''
281
- end
282
- value << input + "\n"
283
- end
284
- end
285
- return value
286
- end
143
+ def self.radio_prompt(option_type)
144
+ value_found = false
145
+ value = nil
146
+ options = []
147
+ if option_type['config'] and option_type['config']['radioOptions']
148
+ option_type['config']['radioOptions'].each do |radio_option|
149
+ options << {key: radio_option['key'], checked: radio_option['checked']}
150
+ end
151
+ end
152
+ optionString = options.collect{ |b| b[:checked] ? "(#{b[:key]})" : b[:key]}.join(', ')
153
+ while !value_found do
154
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }[#{optionString}]: "
155
+ input = $stdin.gets.chomp!
156
+ if input == '?'
157
+ help_prompt(option_type)
158
+ else
159
+ if input.nil? || input.empty?
160
+ selectedOption = options.find{|o| o[:checked] == true}
161
+ else
162
+ selectedOption = options.find{|o| o[:key].downcase == input.downcase}
163
+ end
164
+ if selectedOption
165
+ value = selectedOption[:key]
166
+ else
167
+ puts "Invalid Option. Please select from #{optionString}."
168
+ end
169
+ if !value.nil? || option_type['required'] != true
170
+ value_found = true
171
+ end
172
+ end
173
+ end
174
+ return value
175
+ end
176
+
177
+ def self.number_prompt(option_type)
178
+ value_found = false
179
+ value = nil
180
+ while !value_found do
181
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
182
+ input = $stdin.gets.chomp!
183
+ value = input.empty? ? option_type['defaultValue'] : input.to_i
184
+ if input == '?'
185
+ help_prompt(option_type)
186
+ elsif !value.nil? || option_type['required'] != true
187
+ value_found = true
188
+ end
189
+ end
190
+ return value
191
+ end
192
+
193
+ def self.select_prompt(option_type,api_client, api_params={}, no_prompt=false)
194
+ value_found = false
195
+ value = nil
196
+ if option_type['selectOptions']
197
+ select_options = option_type['selectOptions']
198
+ elsif option_type['optionSource']
199
+ select_options = load_source_options(option_type['optionSource'],api_client,api_params)
200
+ else
201
+ raise "select_prompt() requires selectOptions or optionSource!"
202
+ end
203
+ if !select_options.nil? && select_options.count == 1 && option_type['skipSingleOption'] == true
204
+ value_found = true
205
+ value = select_options[0]['value']
206
+ end
207
+ if no_prompt
208
+ if !value_found
209
+ if option_type['required']
210
+ print Term::ANSIColor.red, "\nMissing Required Option\n\n"
211
+ print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
212
+ display_select_options(select_options)
213
+ print "\n"
214
+ exit 1
215
+ else
216
+ return nil
217
+ end
218
+ end
219
+ end
220
+ while !value_found do
221
+ Readline.completion_append_character = ""
222
+ Readline.basic_word_break_characters = ''
223
+ Readline.completion_proc = proc {|s| select_options.clone.collect{|opt| opt['name']}.grep(/^#{Regexp.escape(s)}/)}
224
+ input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
225
+ input = input.chomp.strip
226
+ if input.empty?
227
+ value = option_type['defaultValue']
228
+ else
229
+ select_option = select_options.find{|b| b['name'] == input || (!b['value'].nil? && b['value'].to_s == input) || (b['value'].nil? && input.empty?)}
230
+ if select_option
231
+ value = select_option['value']
232
+ elsif !input.nil? && !input.empty?
233
+ input = '?'
234
+ end
235
+ end
236
+ if input == '?'
237
+ help_prompt(option_type)
238
+ display_select_options(select_options)
239
+ elsif !value.nil? || option_type['required'] != true
240
+ value_found = true
241
+ end
242
+ end
243
+ return value
244
+ end
245
+
246
+ def self.checkbox_prompt(option_type)
247
+ value_found = false
248
+ value = nil
249
+ while !value_found do
250
+ print "#{option_type['fieldLabel']} (yes/no) [#{option_type['defaultValue'] == 'on' ? 'yes' : 'no'}]: "
251
+ input = $stdin.gets.chomp!
252
+ if input.downcase == 'yes'
253
+ value = 'on'
254
+ elsif input.downcase == 'no'
255
+ value = 'off'
256
+ else
257
+ value = option_type['defaultValue']
258
+ end
259
+ if input == '?'
260
+ help_prompt(option_type)
261
+ elsif !value.nil? || option_type['required'] != true
262
+ value_found = true
263
+ end
264
+ end
265
+ return value
266
+ end
267
+
268
+ def self.generic_prompt(option_type)
269
+ value_found = false
270
+ value = nil
271
+ while !value_found do
272
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
273
+ input = $stdin.gets.chomp!
274
+ value = input.empty? ? option_type['defaultValue'] : input
275
+ if input == '?'
276
+ help_prompt(option_type)
277
+ elsif !value.nil? || option_type['required'] != true
278
+ value_found = true
279
+ end
280
+ end
281
+ return value
282
+ end
283
+
284
+ def self.multiline_prompt(option_type)
285
+ value_found = false
286
+ value = nil
287
+ while !value_found do
288
+ if value.nil?
289
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''} [Type 'EOF' to stop input]: \n"
290
+ end
291
+ input = $stdin.gets.chomp!
292
+ # value = input.empty? ? option_type['defaultValue'] : input
293
+ if input == '?' && value.nil?
294
+ help_prompt(option_type)
295
+ elsif (!value.nil? || option_type['required'] != true) && input.chomp == 'EOF'
296
+ value_found = true
297
+ else
298
+ if value.nil?
299
+ value = ''
300
+ end
301
+ value << input + "\n"
302
+ end
303
+ end
304
+ return value
305
+ end
287
306
 
288
- def self.password_prompt(option_type)
289
- value_found = false
290
- while !value_found do
291
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}: "
292
- input = $stdin.noecho(&:gets).chomp!
293
- value = input
294
- print "\n"
295
- if input == '?'
296
- help_prompt(option_type)
297
- elsif !value.empty? || option_type['required'] != true
298
- value_found = true
299
- end
300
- end
301
- return value
302
- end
307
+ def self.password_prompt(option_type)
308
+ value_found = false
309
+ while !value_found do
310
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}: "
311
+ input = $stdin.noecho(&:gets).chomp!
312
+ value = input
313
+ print "\n"
314
+ if input == '?'
315
+ help_prompt(option_type)
316
+ elsif !value.empty? || option_type['required'] != true
317
+ value_found = true
318
+ end
319
+ end
320
+ return value
321
+ end
303
322
 
304
- def self.file_prompt(option_type)
305
- value_found = false
306
- value = nil
307
- while !value_found do
308
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
309
- Readline.completion_append_character = ""
310
- Readline.basic_word_break_characters = ''
311
- Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
312
- input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
313
- input = input.chomp.strip
314
- #input = $stdin.gets.chomp!
315
- value = input.empty? ? option_type['defaultValue'] : input.to_s
316
- if input == '?'
317
- help_prompt(option_type)
318
- elsif value.empty? && option_type['required'] != true
319
- value = nil
320
- value_found = true
321
- elsif value
322
- filename = File.expand_path(value)
323
- if !File.exists?(filename)
324
- # print_red_alert "File not found: #{filename}"
325
- # exit 1
326
- print Term::ANSIColor.red," File not found: #{filename}",Term::ANSIColor.reset, "\n"
327
- elsif !File.file?(filename)
328
- print Term::ANSIColor.red," Argument is not a file: #{filename}",Term::ANSIColor.reset, "\n"
329
- else
330
- value = filename
331
- value_found = true
332
- end
333
- end
334
- end
335
- return value
336
- end
323
+ def self.file_prompt(option_type)
324
+ value_found = false
325
+ value = nil
326
+ while !value_found do
327
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
328
+ Readline.completion_append_character = ""
329
+ Readline.basic_word_break_characters = ''
330
+ Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
331
+ input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
332
+ input = input.chomp.strip
333
+ #input = $stdin.gets.chomp!
334
+ value = input.empty? ? option_type['defaultValue'] : input.to_s
335
+ if input == '?'
336
+ help_prompt(option_type)
337
+ elsif value.empty? && option_type['required'] != true
338
+ value = nil
339
+ value_found = true
340
+ elsif value
341
+ filename = File.expand_path(value)
342
+ if !File.exists?(filename)
343
+ # print_red_alert "File not found: #{filename}"
344
+ # exit 1
345
+ print Term::ANSIColor.red," File not found: #{filename}",Term::ANSIColor.reset, "\n"
346
+ elsif !File.file?(filename)
347
+ print Term::ANSIColor.red," Argument is not a file: #{filename}",Term::ANSIColor.reset, "\n"
348
+ else
349
+ value = filename
350
+ value_found = true
351
+ end
352
+ end
353
+ end
354
+ return value
355
+ end
337
356
 
338
- def self.help_prompt(option_type)
339
- print Term::ANSIColor.green," * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
340
- end
357
+ def self.help_prompt(option_type)
358
+ print Term::ANSIColor.green," * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
359
+ end
341
360
 
342
361
 
343
- def self.load_source_options(source,api_client,params)
344
- api_client.options.options_for_source(source,params)['data']
345
- end
362
+ def self.load_source_options(source,api_client,params)
363
+ api_client.options.options_for_source(source,params)['data']
364
+ end
346
365
 
347
- def self.display_select_options(select_options = [])
348
- puts "\nOptions"
349
- puts "==============="
350
- select_options.each do |option|
351
- puts " * #{option['name']} [#{option['value']}]"
352
- end
353
- puts "\n\n"
354
- end
366
+ def self.display_select_options(select_options = [])
367
+ puts "\nOptions"
368
+ puts "==============="
369
+ select_options.each do |option|
370
+ puts " * #{option['name']} [#{option['value']}]"
371
+ end
372
+ puts "\n\n"
373
+ end
355
374
 
356
- def self.format_option_types_help(option_types)
357
- if option_types.empty?
358
- "Available Options:\nNone\n\n"
359
- else
360
- option_lines = option_types.collect {|it| " -O #{it['fieldName']}=\"value\"" }.join("\n")
361
- "Available Options:\n#{option_lines}\n\n"
362
- end
363
- end
364
- def self.display_option_types_help(option_types)
365
- puts self.format_option_types_help(option_types)
366
- end
375
+ def self.format_option_types_help(option_types)
376
+ if option_types.empty?
377
+ "Available Options:\nNone\n\n"
378
+ else
379
+ option_lines = option_types.collect {|it| " -O #{it['fieldName']}=\"value\"" }.join("\n")
380
+ "Available Options:\n#{option_lines}\n\n"
381
+ end
382
+ end
383
+
384
+ def self.display_option_types_help(option_types)
385
+ puts self.format_option_types_help(option_types)
386
+ end
367
387
 
368
- end
369
- end
370
- end
388
+ end
389
+ end
390
+ end