morpheus-cli 5.4.5 → 5.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) 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/prices_interface.rb +6 -0
  7. data/lib/morpheus/api/scale_thresholds_interface.rb +9 -0
  8. data/lib/morpheus/cli/cli_command.rb +55 -23
  9. data/lib/morpheus/cli/commands/apps.rb +2 -2
  10. data/lib/morpheus/cli/commands/cloud_resource_pools_command.rb +33 -2
  11. data/lib/morpheus/cli/commands/clouds.rb +61 -31
  12. data/lib/morpheus/cli/commands/clusters.rb +66 -5
  13. data/lib/morpheus/cli/commands/cypher_command.rb +22 -23
  14. data/lib/morpheus/cli/commands/hosts.rb +5 -1
  15. data/lib/morpheus/cli/commands/instances.rb +12 -12
  16. data/lib/morpheus/cli/commands/integrations_command.rb +1 -1
  17. data/lib/morpheus/cli/commands/invoices_command.rb +8 -1
  18. data/lib/morpheus/cli/commands/jobs_command.rb +45 -225
  19. data/lib/morpheus/cli/commands/library_container_types_command.rb +52 -3
  20. data/lib/morpheus/cli/commands/library_option_lists_command.rb +18 -8
  21. data/lib/morpheus/cli/commands/library_option_types_command.rb +56 -62
  22. data/lib/morpheus/cli/commands/load_balancers.rb +11 -19
  23. data/lib/morpheus/cli/commands/network_pool_servers_command.rb +5 -2
  24. data/lib/morpheus/cli/commands/prices_command.rb +25 -11
  25. data/lib/morpheus/cli/commands/roles.rb +475 -70
  26. data/lib/morpheus/cli/commands/scale_thresholds.rb +103 -0
  27. data/lib/morpheus/cli/commands/tasks.rb +64 -22
  28. data/lib/morpheus/cli/commands/user_sources_command.rb +107 -39
  29. data/lib/morpheus/cli/commands/users.rb +10 -10
  30. data/lib/morpheus/cli/commands/view.rb +1 -0
  31. data/lib/morpheus/cli/commands/workflows.rb +21 -14
  32. data/lib/morpheus/cli/error_handler.rb +13 -4
  33. data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
  34. data/lib/morpheus/cli/mixins/execution_request_helper.rb +1 -1
  35. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +3 -3
  36. data/lib/morpheus/cli/mixins/jobs_helper.rb +173 -0
  37. data/lib/morpheus/cli/mixins/print_helper.rb +120 -38
  38. data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -3
  39. data/lib/morpheus/cli/mixins/rest_command.rb +41 -14
  40. data/lib/morpheus/cli/option_types.rb +69 -13
  41. data/lib/morpheus/cli/version.rb +1 -1
  42. data/lib/morpheus/logging.rb +6 -8
  43. data/lib/morpheus/routes.rb +3 -5
  44. metadata +6 -4
@@ -61,11 +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
75
+
65
76
  # puts "Options Prompt #{options}"
66
77
  # Sort options by default, group, advanced
67
78
  cur_field_group = 'default'
68
- self.sorted_option_types(option_types).each do |option_type|
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
69
82
  context_map = results
70
83
  value = nil
71
84
  value_found = false
@@ -145,6 +158,10 @@ module Morpheus
145
158
  next if !found_dep_value
146
159
  end
147
160
 
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']
164
+
148
165
  cur_namespace = options
149
166
  parent_context_map = context_map
150
167
  parent_ns = field_name
@@ -159,9 +176,26 @@ module Morpheus
159
176
  context_map = context_map[ns.to_s]
160
177
  end
161
178
 
162
- # build parameters for option source api request
163
- option_params = (option_type['noParams'] ? {} : (api_params || {}).deep_merge(results))
164
- 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
+ }
165
199
 
166
200
  # use the value passed in the options map
167
201
  if cur_namespace.respond_to?('key?') && cur_namespace.key?(field_name)
@@ -194,6 +228,8 @@ module Morpheus
194
228
  select_value_list << typeahead_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, option_params, true)
195
229
  end
196
230
  value = select_value_list
231
+ elsif option_type['type'] == 'credential'
232
+ handle_credential_type.call
197
233
  end
198
234
  if options[:always_prompt] != true
199
235
  value_found = true
@@ -252,6 +288,9 @@ module Morpheus
252
288
  value = multiline_prompt(option_type)
253
289
  elsif option_type['type'] == 'code-editor'
254
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
255
294
  elsif ['select', 'multiSelect'].include?(option_type['type'])
256
295
  # so, the /api/options/source is may need ALL the previously
257
296
  # selected values that are being accumulated in options
@@ -262,7 +301,8 @@ module Morpheus
262
301
  value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty)
263
302
  if value && option_type['type'] == 'multiSelect'
264
303
  value = [value]
265
- 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
266
306
  if addn_value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty)
267
307
  value << addn_value
268
308
  else
@@ -366,7 +406,6 @@ module Morpheus
366
406
  return value
367
407
  end
368
408
 
369
-
370
409
  def self.set_last_select(obj)
371
410
  Thread.current[:_last_select] = obj
372
411
  end
@@ -741,15 +780,18 @@ module Morpheus
741
780
  help_prompt(option_type)
742
781
  next
743
782
  end
744
- if input.downcase == 'yes'
783
+ if input.downcase == 'yes' || input.downcase == 'y' || input.downcase == 'on'
745
784
  value_found = true
746
785
  value = 'on'
747
- elsif input.downcase == 'no'
786
+ elsif input.downcase == 'no' || input.downcase == 'n' || input.downcase == 'off'
748
787
  value_found = true
749
788
  value = 'off'
750
789
  elsif input == '' && has_default
751
790
  value_found = true
752
791
  value = default_yes ? 'on' : 'off'
792
+ elsif input != ""
793
+ puts "Invalid Option... Please try again."
794
+ next
753
795
  end
754
796
  if value.nil? && option_type['required']
755
797
  puts "Invalid Option... Please try again."
@@ -795,6 +837,20 @@ module Morpheus
795
837
  elsif !value.nil? || option_type['required'] != true
796
838
  value_found = true
797
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
798
854
  end
799
855
  return value
800
856
  end
@@ -1058,10 +1114,10 @@ module Morpheus
1058
1114
  return out
1059
1115
  end
1060
1116
 
1061
- def self.sorted_option_types(option_types)
1062
- option_types.reject {|it| (it['fieldGroup'] || 'default') != 'default'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i} +
1063
- 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 +
1064
- 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}
1065
1121
  end
1066
1122
 
1067
1123
  def self.display_select_options(opt, select_options = [], paging = nil)
@@ -1069,7 +1125,7 @@ module Morpheus
1069
1125
  end
1070
1126
 
1071
1127
  def self.format_option_types_help(option_types, opts={})
1072
- 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']}
1073
1129
 
1074
1130
  if option_types.empty?
1075
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.4.5"
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
@@ -16,11 +16,9 @@ module Morpheus::Routes
16
16
  analytics: {},
17
17
  guidance: {},
18
18
  wiki: {},
19
- costing: {
20
- budgets: {},
21
- invoices: {},
22
- usage: {},
23
- },
19
+ budgets: {},
20
+ invoices: {},
21
+ usage: {},
24
22
  approvals: {},
25
23
  activity: {},
26
24
  alarms: {},
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.4.5
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-04-14 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