morpheus-cli 6.2.3 → 6.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5930c4f23cd2074b678db885c77f067ca32b305371cb93875a372b22a91fd18
4
- data.tar.gz: 036f912c60e1f86ba302dc240cc1a485722ef0716752d934a352e54d797fd5d4
3
+ metadata.gz: 8acef874a37276edc6d53f64e243ca01c0e0d30e49dea166502058da2f01350d
4
+ data.tar.gz: f0f9022abbb5b04c526cf992c95cacee2927ce5fb2e27027b19dc624abe454be
5
5
  SHA512:
6
- metadata.gz: c93378cfb509b11873be3d183f69bc5662fd5afb6888ea759271347e84f87443a73c9eb80a12572b1c196f1afe8ebf40068d00290053ebad398df5ee320d8446
7
- data.tar.gz: 1c277dd0ff9b918b3c2dfd9fc7bc0c4ed662e59ba3fa10a4abf3d037ffc08211e0f0c7a040917ca1322dbc06610391f676560ec195ddd794ff50d2098658235b
6
+ metadata.gz: ab4f224e431ff217ea24591b385d76f1a6370626770e8eb9f8ae8291c6d6681e3a29c58c6c220fea85510819da0df901e3816e37f4937ad2b04c4322a5eae0b2
7
+ data.tar.gz: 27976146b5f086f41968860c7eb210fdbc7cf8ac6667b55e1318e88f9fae938c33699b05a14a1cdba91bfcde0635b01113bc61c3c1e21ade5e2a7bea719cee66
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.7.5
2
2
 
3
- RUN gem install morpheus-cli -v 6.2.3
3
+ RUN gem install morpheus-cli -v 6.3.1
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
data/README.md CHANGED
@@ -55,7 +55,7 @@ New CLI commands get added under the library directory: `lib/morpheus/cli/comman
55
55
  While developing, you can quickly reload your code changes in a morpheus shell while developing:
56
56
 
57
57
  ```shell
58
- morpheus shell
58
+ bundle exec morpheus shell —debug
59
59
  ```
60
60
 
61
61
  Then to reload changes without restarting the morpheus shell (and the ruby process), use:
@@ -66,6 +66,9 @@ reload
66
66
 
67
67
  Don't forget to add unit tests for your new commands under the directory: `test/`.
68
68
 
69
+
70
+
71
+
69
72
  ## Testing
70
73
 
71
74
  To run the CLI unit tests, first create a `test_config.yaml` and then run `rake test`.
@@ -600,6 +600,10 @@ class Morpheus::APIClient
600
600
  Morpheus::OptionTypeListsInterface.new(common_interface_options).setopts(@options)
601
601
  end
602
602
 
603
+ def option_type_forms
604
+ Morpheus::OptionTypeFormsInterface.new(common_interface_options).setopts(@options)
605
+ end
606
+
603
607
  def scale_thresholds
604
608
  Morpheus::ScaleThresholdsInterface.new(common_interface_options).setopts(@options)
605
609
  end
@@ -766,6 +770,10 @@ class Morpheus::APIClient
766
770
  Morpheus::LibraryClusterLayoutsInterface.new(common_interface_options).setopts(@options)
767
771
  end
768
772
 
773
+ def library_cluster_packages
774
+ Morpheus::LibraryClusterPackagesInterface.new(common_interface_options).setopts(@options)
775
+ end
776
+
769
777
  def library_spec_templates
770
778
  Morpheus::LibrarySpecTemplatesInterface.new(common_interface_options).setopts(@options)
771
779
  end
@@ -0,0 +1,41 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::LibraryClusterPackagesInterface < Morpheus::APIClient
4
+
5
+ def list(params={})
6
+ url = "#{@base_url}/api/library/cluster-packages"
7
+ params['sort'] = 'name'
8
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
9
+ opts = {method: :get, url: url, headers: headers}
10
+ execute(opts)
11
+ end
12
+
13
+ def get(id, params={})
14
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
15
+ url = "#{@base_url}/api/library/cluster-packages/#{id}"
16
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
17
+ opts = {method: :get, url: url, headers: headers}
18
+ execute(opts)
19
+ end
20
+
21
+ def create(payload)
22
+ url = "#{@base_url}/api/library/cluster-packages"
23
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
24
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
25
+ execute(opts)
26
+ end
27
+
28
+ def update(id, payload)
29
+ url = "#{@base_url}/api/library/cluster-packages/#{id}"
30
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
31
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
32
+ execute(opts)
33
+ end
34
+
35
+ def destroy(id, payload={})
36
+ url = "#{@base_url}/api/library/cluster-packages/#{id}"
37
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
38
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
39
+ execute(opts)
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/rest_interface'
2
+
3
+ class Morpheus::OptionTypeFormsInterface < Morpheus::RestInterface
4
+
5
+ def base_path
6
+ "/api/library/option-type-forms"
7
+ end
8
+
9
+ end
@@ -268,7 +268,6 @@ module Morpheus
268
268
  build_standard_post_options(opts, options, includes, excludes)
269
269
  end
270
270
 
271
- # todo: this can go away once every command is using execute_api()
272
271
  def build_standard_add_many_options(opts, options, includes=[], excludes=[])
273
272
  build_standard_post_options(opts, options, includes + [:payloads], excludes)
274
273
  end
@@ -1579,6 +1578,9 @@ module Morpheus
1579
1578
  # could use parse_passed_options() here to support exclusion of certain options
1580
1579
  #passed_options = parse_passed_options(options, options[:apply_options] || {})
1581
1580
  passed_options = options[:options].reject {|k,v| k.is_a?(Symbol)}
1581
+ if options[:apply_options_exclude]
1582
+ passed_options = options[:options].reject {|k,v| options[:skip_apply_options].include?(k.to_s) || options[:skip_apply_options].include?(k.to_sym) }
1583
+ end
1582
1584
  if object_key
1583
1585
  payload.deep_merge!({object_key => passed_options})
1584
1586
  else
@@ -95,12 +95,10 @@ module Morpheus
95
95
  suggestions = find_command_suggestions(command_name)
96
96
  if suggestions && suggestions.size == 1
97
97
  msg += "\nThe most similar command is:\n"
98
- suggestions.first(5).each do |suggestion|
99
- msg += "\t" + suggestion + "\n"
100
- end
98
+ msg += "\t" + suggestions.first + "\n"
101
99
  elsif suggestions && suggestions.size > 1
102
100
  msg += "\nThe most similar commands are:\n"
103
- suggestions.first(5).each do |suggestion|
101
+ suggestions.first(50).each do |suggestion|
104
102
  msg += "\t" + suggestion + "\n"
105
103
  end
106
104
  end
@@ -283,7 +283,7 @@ EOT
283
283
  return 1 if backup.nil?
284
284
  parse_options(options, params)
285
285
  confirm!("Are you sure you want to delete the backup #{backup['name']}?", options)
286
- execute_api(@backups_interface, :destroy, [backup['id']], options, 'backup') do |json_response|
286
+ execute_api(@backups_interface, :destroy, [backup['id']], options) do |json_response|
287
287
  print_green_success "Removed backup #{backup['name']}"
288
288
  end
289
289
  end
@@ -1,16 +1,15 @@
1
1
  require 'morpheus/cli/cli_command'
2
2
 
3
- # CLI command self service
4
- # UI is Tools: Self Service - Catalog
5
- # API is /catalog-item-types and returns catalogItemTypes
3
+ # CLI command Catalog Item Types
4
+ # UI is Library > Blueprints > Catalog Items
5
+ # API is /api/catalog-item-types and returns catalogItemTypes
6
6
  class Morpheus::Cli::CatalogItemTypesCommand
7
7
  include Morpheus::Cli::CliCommand
8
8
  include Morpheus::Cli::LibraryHelper
9
9
  include Morpheus::Cli::OptionSourceHelper
10
10
 
11
- # set_command_name :'catalog-types'
12
- set_command_name :'self-service'
13
- set_command_description "Self Service: View and manage catalog item types"
11
+ set_command_name :'catalog-item-types'
12
+ set_command_description "View and manage catalog item types"
14
13
 
15
14
  register_subcommands :list, :get, :add, :update, :remove
16
15
  register_subcommands({:'update-logo' => :update_logo, :'update-dark-logo' => :update_dark_logo})
@@ -152,13 +151,28 @@ EOT
152
151
  print_h1 "Catalog Item Type Details", [], options
153
152
  print cyan
154
153
  show_columns = catalog_item_type_column_definitions
154
+ show_columns.delete("Form") unless catalog_item_type['form']
155
155
  show_columns.delete("Blueprint") unless catalog_item_type['blueprint']
156
156
  show_columns.delete("Workflow") unless catalog_item_type['workflow']
157
157
  show_columns.delete("Context") unless catalog_item_type['context'] # workflow context
158
158
  print_description_list(show_columns, catalog_item_type)
159
159
 
160
+ option_type_form = catalog_item_type['form']
161
+ if option_type_form
162
+ print_h2 "Form Inputs"
163
+ form_inputs = (option_type_form['options'] || [])
164
+ if option_type_form['fieldGroups']
165
+ option_type_form['fieldGroups'].each { |field_group| form_inputs += (field_group['options'] || []) }
166
+ end
167
+ # print format_simple_option_types_table(form_inputs, options)
168
+ print format_option_types_table(form_inputs, options, 'config.customOptions')
169
+ print reset,"\n"
170
+ else
171
+ # print cyan,"No form inputs found for this catalog item.","\n",reset
172
+ end
173
+
160
174
  if catalog_item_type['optionTypes'] && catalog_item_type['optionTypes'].size > 0
161
- print_h2 "Option Types"
175
+ print_h2 "Inputs"
162
176
  opt_columns = [
163
177
  {"ID" => lambda {|it| it['id'] } },
164
178
  {"NAME" => lambda {|it| it['name'] } },
@@ -313,7 +327,13 @@ EOT
313
327
  options[:options]['config'] = params['config'] # or file_content
314
328
  end
315
329
  end
316
- opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
330
+ opts.on('--form-type form|optionTypes', String, "Form Type determines if input comes from a Form or list of Option Types") do |val|
331
+ params['formType'] = val
332
+ end
333
+ opts.on('--form FORM', String, "Form Name or ID") do |val|
334
+ params['form'] = val
335
+ end
336
+ opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |val|
317
337
  if list.nil?
318
338
  params['optionTypes'] = []
319
339
  else
@@ -379,11 +399,24 @@ EOT
379
399
  # massage association params a bit
380
400
  params['workflow'] = {'id' => params['workflow']} if params['workflow'] && !params['workflow'].is_a?(Hash)
381
401
  params['blueprint'] = {'id' => params['blueprint']} if params['blueprint'] && !params['blueprint'].is_a?(Hash)
382
- prompt_results = prompt_for_option_types(params, options, @api_client)
383
- if prompt_results[:success]
384
- params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
402
+ if params['formType'].to_s.empty?
403
+ params['formType'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'formType', 'fieldLabel' => 'Form Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Form', 'value' => 'form'}, {'name' => 'Inputs', 'value' => 'optionTypes'}], 'defaultValue' => 'optionTypes', 'required' => true}], options[:options], @api_client, options[:params])['formType']
404
+ end
405
+ if params['formType'] == 'form'
406
+ # using formType = 'form'
407
+ # prompt for Form
408
+ options[:options]['form'] = params['form'] if params['form']
409
+ form_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'form', 'fieldLabel' => 'Form', 'type' => 'select', 'optionSource' => 'forms', 'required' => true}], options[:options], @api_client, options[:params])['form']
410
+ params['form'] = {'id' => form_id}
385
411
  else
386
- return 1, "failed to parse optionTypes"
412
+ # using formType = 'optionTypes'
413
+ # prompt for Option Types
414
+ prompt_results = prompt_for_option_types(params, options, @api_client)
415
+ if prompt_results[:success]
416
+ params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
417
+ else
418
+ return 1, "failed to parse optionTypes"
419
+ end
387
420
  end
388
421
  payload[catalog_item_type_object_key].deep_merge!(params)
389
422
  end
@@ -470,6 +503,12 @@ EOT
470
503
  options[:options]['config'] = params['config'] # or file_content
471
504
  end
472
505
  end
506
+ opts.on('--form-type form|optionTypes', String, "Form Type determines if input comes from a Form or list of Option Types") do |val|
507
+ params['formType'] = val
508
+ end
509
+ opts.on('--form FORM', String, "Form Name or ID") do |val|
510
+ params['form'] = val
511
+ end
473
512
  opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
474
513
  if list.nil?
475
514
  params['optionTypes'] = []
@@ -693,6 +732,7 @@ EOT
693
732
  "Workflow" => lambda {|it| it['workflow'] ? it['workflow']['name'] : nil },
694
733
  "Context" => lambda {|it| it['context'] },
695
734
  # "Content" => lambda {|it| it['content'] },
735
+ "Form Type" => lambda {|it| it['formType'] == 'form' ? "Form" : "Inputs" },
696
736
  "Enabled" => lambda {|it| format_boolean(it['enabled']) },
697
737
  "Featured" => lambda {|it| format_boolean(it['featured']) },
698
738
  #"Config" => lambda {|it| it['config'] },
@@ -716,6 +756,8 @@ EOT
716
756
  "Workflow" => lambda {|it| it['workflow'] ? it['workflow']['name'] : nil },
717
757
  "Context" => lambda {|it| it['context'] },
718
758
  # "Content" => lambda {|it| it['content'] },
759
+ "Form Type" => lambda {|it| it['formType'] == 'form' ? "Form" : "Inputs" },
760
+ "Form" => lambda {|it| it['form'] ? it['form']['name'] : nil },
719
761
  "Enabled" => lambda {|it| format_boolean(it['enabled']) },
720
762
  "Featured" => lambda {|it| format_boolean(it['featured']) },
721
763
  "Allow Quantity" => lambda {|it| format_boolean(it['allowQuantity']) },
@@ -175,7 +175,7 @@ EOT
175
175
  end
176
176
  # reject hardcoded optionTypes
177
177
  config_option_types = config_option_types.reject {|it| it['fieldName'] == 'name' || it['fieldName'] == 'description' || it['fieldName'] == 'domainName' }
178
- config_prompt = Morpheus::Cli::OptionTypes.prompt(config_option_types, options[:options], @api_client, options[:params])
178
+ config_prompt = Morpheus::Cli::OptionTypes.prompt(config_option_types, options[:options], @api_client, {certType: certificate_type['id']})
179
179
  config_prompt.deep_compact!
180
180
  params.deep_merge!(config_prompt)
181
181
  end
@@ -730,14 +730,13 @@ class Morpheus::Cli::Clusters
730
730
  server_payload['hostname'] = options[:hostname] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hostname', 'fieldLabel' => 'Hostname', 'type' => 'text', 'required' => true, 'description' => 'Hostname', 'defaultValue' => resourceName}], options[:options], @api_client, api_params)['hostname']
731
731
 
732
732
  # Kube Default Repo
733
- if cluster_payload['type'] == 'kubernetes-cluster' && (layout['clusterVersion'] == '1.28.x' || layout['clusterVersion'] == '1.27.x')
733
+ if cluster_payload['type'] == 'kubernetes-cluster'
734
734
  default_repo = options[:default_repo] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultRepoAccount', 'fieldLabel' => 'Cluster Repo Account', 'type' => 'select', 'required' => false, 'optionSource' => 'dockerHubRegistries'}], options[:options], @api_client, api_params)['defaultRepoAccount']
735
735
  if default_repo != ""
736
736
  server_payload['config']['defaultRepoAccount'] = default_repo
737
737
  end
738
738
  end
739
739
 
740
-
741
740
  # Workflow / Automation
742
741
  if provision_type['code'] != 'manual' && controller_type && controller_type['hasAutomation']
743
742
  task_set_id = options[:taskSetId] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'taskSet', 'fieldLabel' => 'Workflow', 'type' => 'select', 'required' => false, 'optionSource' => 'taskSets'}], options[:options], @api_client, api_params.merge({'phase' => 'postProvision'}))['taskSet']