morpheus-cli 5.5.0 → 5.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +4 -0
  4. data/lib/morpheus/api/clusters_interface.rb +12 -0
  5. data/lib/morpheus/api/network_pool_servers_interface.rb +7 -0
  6. data/lib/morpheus/api/scale_thresholds_interface.rb +9 -0
  7. data/lib/morpheus/cli/cli_command.rb +39 -20
  8. data/lib/morpheus/cli/commands/apps.rb +1 -1
  9. data/lib/morpheus/cli/commands/cloud_resource_pools_command.rb +33 -2
  10. data/lib/morpheus/cli/commands/clouds.rb +12 -6
  11. data/lib/morpheus/cli/commands/clusters.rb +66 -5
  12. data/lib/morpheus/cli/commands/hosts.rb +5 -1
  13. data/lib/morpheus/cli/commands/instances.rb +1 -1
  14. data/lib/morpheus/cli/commands/integrations_command.rb +1 -1
  15. data/lib/morpheus/cli/commands/invoices_command.rb +8 -1
  16. data/lib/morpheus/cli/commands/jobs_command.rb +45 -225
  17. data/lib/morpheus/cli/commands/library_container_types_command.rb +52 -3
  18. data/lib/morpheus/cli/commands/library_option_types_command.rb +56 -62
  19. data/lib/morpheus/cli/commands/load_balancers.rb +11 -19
  20. data/lib/morpheus/cli/commands/network_pool_servers_command.rb +5 -2
  21. data/lib/morpheus/cli/commands/roles.rb +475 -70
  22. data/lib/morpheus/cli/commands/scale_thresholds.rb +103 -0
  23. data/lib/morpheus/cli/commands/tasks.rb +19 -12
  24. data/lib/morpheus/cli/commands/user_sources_command.rb +107 -39
  25. data/lib/morpheus/cli/commands/users.rb +10 -10
  26. data/lib/morpheus/cli/commands/view.rb +1 -0
  27. data/lib/morpheus/cli/commands/workflows.rb +21 -14
  28. data/lib/morpheus/cli/error_handler.rb +13 -4
  29. data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
  30. data/lib/morpheus/cli/mixins/execution_request_helper.rb +1 -1
  31. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +3 -3
  32. data/lib/morpheus/cli/mixins/jobs_helper.rb +173 -0
  33. data/lib/morpheus/cli/mixins/print_helper.rb +120 -38
  34. data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -3
  35. data/lib/morpheus/cli/mixins/rest_command.rb +41 -14
  36. data/lib/morpheus/cli/option_types.rb +68 -37
  37. data/lib/morpheus/cli/version.rb +1 -1
  38. data/lib/morpheus/logging.rb +6 -8
  39. metadata +6 -4
@@ -61,13 +61,24 @@ module Morpheus
61
61
  if option_type['fieldName'] == 'sshHosts'
62
62
  option_type['type'] = 'multiText'
63
63
  end
64
+ # swap types to multiSelect when flag is set..
65
+ if option_type["config"] && ["true","on"].include?(option_type["config"]["multiSelect"].to_s)
66
+ if option_type["type"] == "typeahead"
67
+ option_type["type"] = "multiTypeahead"
68
+ elsif option_type["type"] == "select"
69
+ option_type["type"] = "multiSelect"
70
+ elsif option_type["type"] == "textarea"
71
+ option_type["type"] = "multiText"
72
+ end
73
+ end
64
74
  end
65
- credential_option_types = {}
75
+
66
76
  # puts "Options Prompt #{options}"
67
77
  # Sort options by default, group, advanced
68
78
  cur_field_group = 'default'
69
- self.sorted_option_types(option_types).each do |option_type|
70
- next if option_type[:for_help_only] == true # hacky
79
+ prompt_local_credentials = true
80
+ self.sort_option_types(option_types.reject {|it| it[:for_help_only]}).each do |option_type|
81
+ next if option_type['localCredential'] && !prompt_local_credentials
71
82
  context_map = results
72
83
  value = nil
73
84
  value_found = false
@@ -147,28 +158,9 @@ module Morpheus
147
158
  next if !found_dep_value
148
159
  end
149
160
 
150
- # inject a Credentials prompt for optionTypes that have been replaced by credentials
151
- credential_code = option_type['credentialFieldContext']
152
- if !credential_code.to_s.empty?
153
- if !credential_option_types[credential_code]
154
- credential_option_type = {'code' => credential_code, 'fieldName' => credential_code, 'fieldLabel' => 'Credentials', 'type' => 'select', 'optionSource' => 'credentials', 'description' => 'Credential ID or use "local" to specify username and password', 'defaultValue' => "local", 'required' => true}
155
- credential_option_types[credential_code] = credential_option_type
156
- supported_credential_types = [option_type['credentialType'], option_type['credentialTypes']].compact.flatten.join(",").split(",").collect {|it| it.strip }
157
- credential_params = {"new" => false, "credentialTypes" => supported_credential_types}
158
- credential_value = select_prompt(credential_option_type, api_client, credential_params, no_prompt, options[credential_code])
159
- if !credential_value.to_s.empty?
160
- if credential_value == "local"
161
- context_map[credential_code] = {"type" => credential_value}
162
- elsif credential_value.to_s =~ /\A\d{1,}\Z/
163
- context_map[credential_code] = {"id" => credential_value.to_i}
164
- end
165
- end
166
- end
167
- # skip this option unless using local credentials
168
- if context_map[credential_code].is_a?(Hash) && context_map[credential_code]["type"] != "local"
169
- next
170
- end
171
- end
161
+ # build parameters for option source api request
162
+ option_params = (option_type['noParams'] ? {} : (api_params || {}).deep_merge(results))
163
+ option_params.merge!(option_type['optionParams']) if option_type['optionParams']
172
164
 
173
165
  cur_namespace = options
174
166
  parent_context_map = context_map
@@ -184,9 +176,26 @@ module Morpheus
184
176
  context_map = context_map[ns.to_s]
185
177
  end
186
178
 
187
- # build parameters for option source api request
188
- option_params = (option_type['noParams'] ? {} : (api_params || {}).deep_merge(results))
189
- option_params.merge!(option_type['optionParams']) if option_type['optionParams']
179
+ # credential type
180
+ handle_credential_type = -> {
181
+ credential_type = select_prompt(option_type.merge({'defaultValue' => value}), api_client, option_params.merge({'credentialTypes' => option_type['config']['credentialTypes']}), !value.nil?, nil, paging_enabled, ignore_empty)
182
+ # continue prompting for local creds
183
+ if credential_type == 'local'
184
+ parent_context_map.reject! {|k,v| k == 'credential'}
185
+ next
186
+ end
187
+ # hide local cred options
188
+ prompt_local_credentials = false
189
+ if credential_type.is_a?(Numeric)
190
+ # set as credential.id
191
+ credential = {'id' => credential_type}
192
+ else
193
+ # prompt credential type options
194
+ credential = prompt(api_client.credential_types.list({name:credential_type})['credentialTypes'][0]['optionTypes'], options, api_client, option_params, options[:no_prompt], paging_enabled, ignore_empty)['credential']
195
+ credential['type'] = credential_type
196
+ end
197
+ parent_context_map['credential'] = credential
198
+ }
190
199
 
191
200
  # use the value passed in the options map
192
201
  if cur_namespace.respond_to?('key?') && cur_namespace.key?(field_name)
@@ -219,6 +228,8 @@ module Morpheus
219
228
  select_value_list << typeahead_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, option_params, true)
220
229
  end
221
230
  value = select_value_list
231
+ elsif option_type['type'] == 'credential'
232
+ handle_credential_type.call
222
233
  end
223
234
  if options[:always_prompt] != true
224
235
  value_found = true
@@ -277,6 +288,9 @@ module Morpheus
277
288
  value = multiline_prompt(option_type)
278
289
  elsif option_type['type'] == 'code-editor'
279
290
  value = multiline_prompt(option_type)
291
+ elsif option_type['type'] == 'credential'
292
+ print "\nCREDENTIALS\n#{"=" * ("CREDENTIALS".length)}\n\n"
293
+ handle_credential_type.call
280
294
  elsif ['select', 'multiSelect'].include?(option_type['type'])
281
295
  # so, the /api/options/source is may need ALL the previously
282
296
  # selected values that are being accumulated in options
@@ -287,7 +301,8 @@ module Morpheus
287
301
  value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty)
288
302
  if value && option_type['type'] == 'multiSelect'
289
303
  value = [value]
290
- while self.confirm("Add another #{option_type['fieldLabel']}?", {:default => false}) do
304
+ recommended_count = (option_type['config'] || {})['recommendedCount'] || 0
305
+ while self.confirm("Add another #{option_type['fieldLabel']}?", {:default => recommended_count > value.count}) do
291
306
  if addn_value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty)
292
307
  value << addn_value
293
308
  else
@@ -391,7 +406,6 @@ module Morpheus
391
406
  return value
392
407
  end
393
408
 
394
-
395
409
  def self.set_last_select(obj)
396
410
  Thread.current[:_last_select] = obj
397
411
  end
@@ -766,15 +780,18 @@ module Morpheus
766
780
  help_prompt(option_type)
767
781
  next
768
782
  end
769
- if input.downcase == 'yes'
783
+ if input.downcase == 'yes' || input.downcase == 'y' || input.downcase == 'on'
770
784
  value_found = true
771
785
  value = 'on'
772
- elsif input.downcase == 'no'
786
+ elsif input.downcase == 'no' || input.downcase == 'n' || input.downcase == 'off'
773
787
  value_found = true
774
788
  value = 'off'
775
789
  elsif input == '' && has_default
776
790
  value_found = true
777
791
  value = default_yes ? 'on' : 'off'
792
+ elsif input != ""
793
+ puts "Invalid Option... Please try again."
794
+ next
778
795
  end
779
796
  if value.nil? && option_type['required']
780
797
  puts "Invalid Option... Please try again."
@@ -820,6 +837,20 @@ module Morpheus
820
837
  elsif !value.nil? || option_type['required'] != true
821
838
  value_found = true
822
839
  end
840
+ # attempt to parse Java regex and validate it
841
+ if option_type["verifyPattern"].to_s != "" && !(value.to_s == "" && option_type['required'])
842
+ begin
843
+ # pattern is matched on the entire string
844
+ verify_pattern = Regexp.compile("^" + option_type["verifyPattern"] + "$")
845
+ if !verify_pattern.match(value)
846
+ value_found = false
847
+ puts "Invalid Option. Value must match the pattern '#{option_type['verifyPattern']}'. Please try again."
848
+ next
849
+ end
850
+ rescue => regex_ex
851
+ puts "Failed to parse verifyPattern '#{option_type['verifyPattern']}' as a regular expression"
852
+ end
853
+ end
823
854
  end
824
855
  return value
825
856
  end
@@ -1083,10 +1114,10 @@ module Morpheus
1083
1114
  return out
1084
1115
  end
1085
1116
 
1086
- def self.sorted_option_types(option_types)
1087
- option_types.reject {|it| (it['fieldGroup'] || 'default') != 'default'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i} +
1088
- option_types.reject {|it| ['default', 'advanced'].include?(it['fieldGroup'] || 'default')}.sort{|a,b| a['displayOrder'] <=> b['displayOrder']}.group_by{|it| it['fieldGroup']}.values.collect { |it| it.sort{|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}}.flatten +
1089
- option_types.reject {|it| it['fieldGroup'] != 'advanced'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}
1117
+ def self.sort_option_types(option_types)
1118
+ option_types.select {|it| (it['fieldGroup'] || 'default').casecmp?('default')}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i} +
1119
+ option_types.reject {|it| ['default', 'advanced'].include?((it['fieldGroup'] || 'default').downcase)}.sort{|a,b| a['displayOrder'] <=> b['displayOrder']}.group_by{|it| it['fieldGroup']}.values.collect { |it| it.sort{|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}}.flatten +
1120
+ option_types.select {|it| 'advanced'.casecmp?(it['fieldGroup'])}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}
1090
1121
  end
1091
1122
 
1092
1123
  def self.display_select_options(opt, select_options = [], paging = nil)
@@ -1094,7 +1125,7 @@ module Morpheus
1094
1125
  end
1095
1126
 
1096
1127
  def self.format_option_types_help(option_types, opts={})
1097
- option_types = self.sorted_option_types(option_types).reject {|it| it['hidden']}
1128
+ option_types = self.sort_option_types(option_types).reject {|it| it['hidden']}
1098
1129
 
1099
1130
  if option_types.empty?
1100
1131
  "#{opts[:color]}#{opts[:title] || "Available Options:"}\nNone\n\n"
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "5.5.0"
4
+ VERSION = "5.5.1"
5
5
  end
6
6
  end
@@ -155,10 +155,9 @@ module Morpheus::Logging
155
155
 
156
156
  def print(*messages)
157
157
  if @io
158
- messages = messages.flatten.collect {|it| scrub_message(it) }
159
- print_with_color do
160
- messages.each do |msg|
161
- @io.print msg
158
+ print_with_color do
159
+ messages.flatten.each do |msg|
160
+ @io.print scrub_message(msg)
162
161
  end
163
162
  end
164
163
  end
@@ -166,10 +165,9 @@ module Morpheus::Logging
166
165
 
167
166
  def puts(*messages)
168
167
  if @io
169
- messages = messages.flatten.collect {|it| scrub_message(it) }
170
- print_with_color do
171
- messages.each do |msg|
172
- @io.puts msg
168
+ print_with_color do
169
+ messages.flatten.each do |msg|
170
+ @io.puts scrub_message(msg)
173
171
  end
174
172
  end
175
173
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.5.0
4
+ version: 5.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-05-13 00:00:00.000000000 Z
14
+ date: 2022-07-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -292,6 +292,7 @@ files:
292
292
  - lib/morpheus/api/reports_interface.rb
293
293
  - lib/morpheus/api/rest_interface.rb
294
294
  - lib/morpheus/api/roles_interface.rb
295
+ - lib/morpheus/api/scale_thresholds_interface.rb
295
296
  - lib/morpheus/api/search_interface.rb
296
297
  - lib/morpheus/api/secondary_read_interface.rb
297
298
  - lib/morpheus/api/secondary_rest_interface.rb
@@ -451,6 +452,7 @@ files:
451
452
  - lib/morpheus/cli/commands/reports_command.rb
452
453
  - lib/morpheus/cli/commands/rm_command.rb
453
454
  - lib/morpheus/cli/commands/roles.rb
455
+ - lib/morpheus/cli/commands/scale_thresholds.rb
454
456
  - lib/morpheus/cli/commands/search_command.rb
455
457
  - lib/morpheus/cli/commands/security_group_rules.rb
456
458
  - lib/morpheus/cli/commands/security_groups.rb
@@ -500,6 +502,7 @@ files:
500
502
  - lib/morpheus/cli/mixins/deployments_helper.rb
501
503
  - lib/morpheus/cli/mixins/execution_request_helper.rb
502
504
  - lib/morpheus/cli/mixins/infrastructure_helper.rb
505
+ - lib/morpheus/cli/mixins/jobs_helper.rb
503
506
  - lib/morpheus/cli/mixins/library_helper.rb
504
507
  - lib/morpheus/cli/mixins/load_balancers_helper.rb
505
508
  - lib/morpheus/cli/mixins/logs_helper.rb
@@ -550,8 +553,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
550
553
  - !ruby/object:Gem::Version
551
554
  version: '0'
552
555
  requirements: []
553
- rubyforge_project:
554
- rubygems_version: 2.7.6
556
+ rubygems_version: 3.1.6
555
557
  signing_key:
556
558
  specification_version: 4
557
559
  summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance