morpheus-cli 5.4.5 → 5.5.1

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.
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