morpheus-cli 5.0.2 → 5.2.0

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: 25ca8fc7cabb51b4042eb212172b60191d6863cf9310ffce4e386d016692f7f1
4
- data.tar.gz: d1183424bef986bb22123d60b45e97ed077c8ea30c5bfd249f8bf503c0a22d13
3
+ metadata.gz: 4f4b5a29dcfa1a915ab2d3fed9ad07197d2a760758b2bc3b76e72cf6899c4372
4
+ data.tar.gz: 59c981a5aede057b69e08f5c717d27c884bdd64aed84fb81361b35291b3aaf72
5
5
  SHA512:
6
- metadata.gz: d006acc9447822675c3593de443679ac2eee514bf1ffe041ddfa5ddc44223e8edfbbeee9393056c59fb98c14d4beb240b0ce9725a3bcc56eb5e1095066d15d1c
7
- data.tar.gz: ca41986fc3561f562b799971514b92dfe08027e06ad5443b0e116713fee9132d62b84905c929209be03a7dc0f3855e97adf7fe053e64832067addca692ef4268
6
+ metadata.gz: 678ff7f73923c9883968ee8bba29b8d75d5464a4899ca812477ce943b25f758c74f187a481c781500928206c4d540d5153f858ee4e2242cfb24cc2604be1602d
7
+ data.tar.gz: c27881081abb71b05eceb4857280f51a4f838e9a568658baa34385afe7fc2b86be61eb31a070a4e3a9381000337ceb9b11f58fe8572fff8066882225133742ba
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.5.1
2
2
 
3
- RUN gem install morpheus-cli -v 5.0.2
3
+ RUN gem install morpheus-cli -v 5.2.0
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -776,6 +776,10 @@ class Morpheus::APIClient
776
776
  Morpheus::CatalogItemTypesInterface.new(common_interface_options).setopts(@options)
777
777
  end
778
778
 
779
+ def catalog
780
+ Morpheus::ServiceCatalogInterface.new(common_interface_options).setopts(@options)
781
+ end
782
+
779
783
  def usage
780
784
  Morpheus::UsageInterface.new(common_interface_options).setopts(@options)
781
785
  end
@@ -169,10 +169,10 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
169
169
  execute(opts)
170
170
  end
171
171
 
172
- def backup(id,server=true)
172
+ def backup(id, payload={})
173
173
  url = "#{@base_url}/api/instances/#{id}/backup"
174
174
  headers = {:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
175
- opts = {method: :put, url: url, headers: headers}
175
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
176
176
  execute(opts)
177
177
  end
178
178
 
@@ -218,6 +218,13 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
218
218
  execute(opts)
219
219
  end
220
220
 
221
+ def snapshot(id, payload={})
222
+ url = "#{@base_url}/api/instances/#{id}/snapshot"
223
+ headers = {:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
224
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
225
+ execute(opts)
226
+ end
227
+
221
228
  def snapshots(instance_id, params={})
222
229
  url = "#{@base_url}/api/instances/#{instance_id}/snapshots"
223
230
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -176,4 +176,11 @@ class Morpheus::ServersInterface < Morpheus::APIClient
176
176
  execute(opts)
177
177
  end
178
178
 
179
+ def software(id, params={})
180
+ url = "#{@base_url}/api/servers/#{id}/software"
181
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
182
+ opts = {method: :get, url: url, headers: headers}
183
+ execute(opts)
184
+ end
185
+
179
186
  end
@@ -0,0 +1,89 @@
1
+ require 'morpheus/api/api_client'
2
+ # Service Catalog Persona interface
3
+ class Morpheus::ServiceCatalogInterface < Morpheus::APIClient
4
+
5
+ def base_path
6
+ # "/api/service-catalog"
7
+ "/api/catalog"
8
+ end
9
+
10
+ # dashboard
11
+ def dashboard(params={})
12
+ execute(method: :get, url: "#{base_path}/dashboard", params: params)
13
+ end
14
+
15
+ # list catalog types available for ordering
16
+ def list_types(params={})
17
+ execute(method: :get, url: "#{base_path}/types", params: params)
18
+ end
19
+
20
+ # get specific catalog type
21
+ def get_type(id, params={})
22
+ validate_id!(id)
23
+ execute(method: :get, url: "#{base_path}/types/#{id}", params: params)
24
+ end
25
+
26
+ # list catalog inventory (items)
27
+ def list_inventory(params={})
28
+ execute(method: :get, url: "#{base_path}/items", params: params)
29
+ end
30
+
31
+ # get catalog inventory item
32
+ def get_inventory(id, params={})
33
+ validate_id!(id)
34
+ execute(method: :get, url: "#{base_path}/items/#{id}", params: params)
35
+ end
36
+
37
+ # delete a catalog inventory item
38
+ def destroy_inventory(id, params = {})
39
+ validate_id!(id)
40
+ execute(method: :delete, url: "#{base_path}/items/#{id}", params: params)
41
+ end
42
+
43
+ # get cart (one per user)
44
+ def get_cart(params={})
45
+ execute(method: :get, url: "#{base_path}/cart", params: params)
46
+ end
47
+
48
+ # update cart (set cart name)
49
+ def update_cart(payload, params={})
50
+ execute(method: :put, url: "#{base_path}/cart", params: params, payload: payload.to_json)
51
+ end
52
+
53
+ # validate a new item, can be used before before adding it
54
+ def validate_cart_item(payload, params={})
55
+ execute(method: :post, url: "#{base_path}/cart/items/validate", params: params, payload: payload.to_json)
56
+ end
57
+
58
+ # add item to cart
59
+ def create_cart_item(payload, params={})
60
+ execute(method: :post, url: "#{base_path}/cart/items", params: params, payload: payload.to_json)
61
+ end
62
+
63
+ # update item in the cart
64
+ def update_cart_item(id, payload, params={})
65
+ validate_id!(id)
66
+ execute(method: :put, url: "#{base_path}/cart/items/#{id}", params: params, payload: payload.to_json)
67
+ end
68
+
69
+ # remove item from the cart
70
+ def destroy_cart_item(id, params={})
71
+ validate_id!(id)
72
+ execute(method: :delete, url: "#{base_path}/cart/items/#{id}", params: params)
73
+ end
74
+
75
+ # place order with cart
76
+ def checkout(payload, params={})
77
+ execute(method: :post, url: "#{base_path}/checkout", params: params, payload: payload.to_json)
78
+ end
79
+
80
+ # remove all items from cart and reset name
81
+ def clear_cart(params={})
82
+ execute(method: :delete, url: "#{base_path}/cart", params: params)
83
+ end
84
+
85
+ # create an order from scratch, without using a cart
86
+ def create_order(payload, params={})
87
+ execute(method: :post, url: "#{base_path}/orders", params: params, payload: payload.to_json)
88
+ end
89
+ end
@@ -175,7 +175,8 @@ module Morpheus
175
175
  load 'morpheus/cli/projects_command.rb'
176
176
  load 'morpheus/cli/backups_command.rb'
177
177
  load 'morpheus/cli/backup_jobs_command.rb'
178
- load 'morpheus/cli/catalog_command.rb'
178
+ load 'morpheus/cli/catalog_item_types_command.rb' # catalog-types
179
+ load 'morpheus/cli/service_catalog_command.rb' # catalog
179
180
  load 'morpheus/cli/usage_command.rb'
180
181
  # add new commands here...
181
182
 
@@ -72,9 +72,6 @@ class Morpheus::Cli::Apps
72
72
  options[:owner] = val
73
73
  end
74
74
  opts.add_hidden_option('--created-by')
75
- opts.on('--details', "Display more details: memory and storage usage used / max values." ) do
76
- options[:details] = true
77
- end
78
75
  opts.on('--pending-removal', "Include apps pending removal.") do
79
76
  options[:showDeleted] = true
80
77
  end
@@ -88,6 +85,9 @@ class Morpheus::Cli::Apps
88
85
  opts.on('--status STATUS', "Filter by status.") do |val|
89
86
  params['status'] = (params['status'] || []) + val.to_s.split(',').collect {|s| s.strip }.select {|s| s != "" }
90
87
  end
88
+ opts.on('-a', '--details', "Display all details: memory and storage usage used / max values." ) do
89
+ options[:details] = true
90
+ end
91
91
  build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
92
92
  opts.footer = "List apps."
93
93
  end
@@ -2185,26 +2185,6 @@ EOT
2185
2185
  print reset
2186
2186
  end
2187
2187
 
2188
- def format_app_status(app, return_color=cyan)
2189
- out = ""
2190
- status_string = app['status'] || app['appStatus'] || ''
2191
- if status_string == 'running'
2192
- out = "#{green}#{status_string.upcase}#{return_color}"
2193
- elsif status_string == 'provisioning'
2194
- out = "#{cyan}#{status_string.upcase}#{cyan}"
2195
- elsif status_string == 'stopped' or status_string == 'failed'
2196
- out = "#{red}#{status_string.upcase}#{return_color}"
2197
- elsif status_string == 'unknown'
2198
- out = "#{yellow}#{status_string.upcase}#{return_color}"
2199
- elsif status_string == 'warning' && app['instanceCount'].to_i == 0
2200
- # show this instead of WARNING
2201
- out = "#{cyan}EMPTY#{return_color}"
2202
- else
2203
- out = "#{yellow}#{status_string.upcase}#{return_color}"
2204
- end
2205
- out
2206
- end
2207
-
2208
2188
  def format_app_tiers(app)
2209
2189
  out = ""
2210
2190
  begin
@@ -1,17 +1,16 @@
1
1
  require 'morpheus/cli/cli_command'
2
2
 
3
3
  # CLI command self service
4
- # UI is Tools: Self Service - Catalog Items
4
+ # UI is Tools: Self Service - Catalog
5
5
  # API is /catalog-item-types and returns catalogItemTypes
6
- class Morpheus::Cli::CatalogCommand
6
+ class Morpheus::Cli::CatalogItemTypesCommand
7
7
  include Morpheus::Cli::CliCommand
8
- include Morpheus::Cli::CatalogHelper
9
8
  include Morpheus::Cli::LibraryHelper
10
9
  include Morpheus::Cli::OptionSourceHelper
11
10
 
12
- # hide until 5.1 when update api is fixed and service-catalog endpoints are available
13
- set_command_hidden
14
- set_command_name :'catalog'
11
+ # set_command_name :'catalog-types'
12
+ set_command_name :'self-service'
13
+ set_command_description "Self Service: View and manage catalog item types"
15
14
 
16
15
  register_subcommands :list, :get, :add, :update, :remove
17
16
 
@@ -38,7 +37,7 @@ class Morpheus::Cli::CatalogCommand
38
37
  params['featured'] = (val.to_s != 'false' && val.to_s != 'off')
39
38
  end
40
39
  build_standard_list_options(opts, options)
41
- opts.footer = "List catalog items."
40
+ opts.footer = "List catalog item types."
42
41
  end
43
42
  optparse.parse!(args)
44
43
  connect(options)
@@ -55,11 +54,14 @@ class Morpheus::Cli::CatalogCommand
55
54
  json_response = @catalog_item_types_interface.list(params)
56
55
  catalog_item_types = json_response[catalog_item_type_list_key]
57
56
  render_response(json_response, options, catalog_item_type_list_key) do
58
- print_h1 "Morpheus Catalog Items", parse_list_subtitles(options), options
57
+ print_h1 "Morpheus Catalog Item Types", parse_list_subtitles(options), options
59
58
  if catalog_item_types.empty?
60
- print cyan,"No catalog items found.",reset,"\n"
59
+ print cyan,"No catalog item types found.",reset,"\n"
61
60
  else
62
61
  list_columns = catalog_item_type_column_definitions.upcase_keys!
62
+ list_columns.delete("Blueprint")
63
+ list_columns.delete("Workflow")
64
+ list_columns.delete("Context")
63
65
  #list_columns["Config"] = lambda {|it| truncate_string(it['config'], 100) }
64
66
  print as_pretty_table(catalog_item_types, list_columns.upcase_keys!, options)
65
67
  print_results_pagination(json_response)
@@ -67,7 +69,7 @@ class Morpheus::Cli::CatalogCommand
67
69
  print reset,"\n"
68
70
  end
69
71
  if catalog_item_types.empty?
70
- return 1, "no catalog items found"
72
+ return 1, "no catalog item types found"
71
73
  else
72
74
  return 0, nil
73
75
  end
@@ -77,17 +79,20 @@ class Morpheus::Cli::CatalogCommand
77
79
  params = {}
78
80
  options = {}
79
81
  optparse = Morpheus::Cli::OptionParser.new do |opts|
80
- opts.banner = subcommand_usage("[catalog item type]")
82
+ opts.banner = subcommand_usage("[type]")
81
83
  opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
82
84
  options[:show_config] = true
83
85
  end
84
- # opts.on('--no-config', "Do not display config content." ) do
86
+ # opts.on('--no-config', "Do not display Config YAML." ) do
85
87
  # options[:no_config] = true
86
88
  # end
89
+ opts.on('--no-content', "Do not display Content." ) do
90
+ options[:no_content] = true
91
+ end
87
92
  build_standard_get_options(opts, options)
88
93
  opts.footer = <<-EOT
89
94
  Get details about a specific catalog item type.
90
- [catalog item type] is required. This is the name or id of a catalog item type.
95
+ [type] is required. This is the name or id of a catalog item type.
91
96
  EOT
92
97
  end
93
98
  optparse.parse!(args)
@@ -131,6 +136,8 @@ EOT
131
136
  print cyan
132
137
  show_columns = catalog_item_type_column_definitions
133
138
  show_columns.delete("Blueprint") unless catalog_item_type['blueprint']
139
+ show_columns.delete("Workflow") unless catalog_item_type['workflow']
140
+ show_columns.delete("Context") unless catalog_item_type['context'] # workflow context
134
141
  print_description_list(show_columns, catalog_item_type)
135
142
 
136
143
  if catalog_item_type['optionTypes'] && catalog_item_type['optionTypes'].size > 0
@@ -149,25 +156,62 @@ EOT
149
156
  # print cyan,"No option types found for this catalog item.","\n",reset
150
157
  end
151
158
 
152
- if config && options[:no_config] != true
153
- print_h2 "Config YAML"
154
- #print reset,(JSON.pretty_generate(config) rescue config),"\n",reset
155
- #print reset,(as_yaml(config, options) rescue config),"\n",reset
156
- config_string = as_yaml(config, options) rescue config
157
- config_lines = config_string.split("\n")
158
- config_line_count = config_lines.size
159
- max_lines = 10
160
- if config_lines.size > max_lines
161
- config_string = config_lines.first(max_lines).join("\n")
162
- config_string << "\n\n"
163
- config_string << "(#{(config_line_count - max_lines)} more lines were not shown, use -c to show the config)"
164
- #config_string << "\n"
165
- end
166
- # strip --- yaml header
167
- if config_string[0..3] == "---\n"
168
- config_string = config_string[4..-1]
159
+ item_type_code = catalog_item_type['type'].to_s.downcase
160
+ if options[:no_config] != true
161
+ if item_type_code == 'instance'
162
+ print_h2 "Config YAML"
163
+ if config
164
+ #print reset,(JSON.pretty_generate(config) rescue config),"\n",reset
165
+ #print reset,(as_yaml(config, options) rescue config),"\n",reset
166
+ config_string = as_yaml(config, options) rescue config
167
+ config_lines = config_string.split("\n")
168
+ config_line_count = config_lines.size
169
+ max_lines = 10
170
+ if config_lines.size > max_lines
171
+ config_string = config_lines.first(max_lines).join("\n")
172
+ config_string << "\n\n"
173
+ config_string << "#{dark}(#{(config_line_count - max_lines)} more lines were not shown, use -c to show the config)#{reset}"
174
+ #config_string << "\n"
175
+ end
176
+ # strip --- yaml header
177
+ if config_string[0..3] == "---\n"
178
+ config_string = config_string[4..-1]
179
+ end
180
+ print reset,config_string.chomp("\n"),"\n",reset
181
+ else
182
+ print reset,"(blank)","\n",reset
183
+ end
184
+ elsif item_type_code == 'blueprint' || item_type_code == 'apptemplate' || item_type_code == 'app'
185
+ print_h2 "App Spec"
186
+ if catalog_item_type['appSpec']
187
+ #print reset,(JSON.pretty_generate(config) rescue config),"\n",reset
188
+ #print reset,(as_yaml(config, options) rescue config),"\n",reset
189
+ config_string = catalog_item_type['appSpec'] || ""
190
+ config_lines = config_string.split("\n")
191
+ config_line_count = config_lines.size
192
+ max_lines = 10
193
+ if config_lines.size > max_lines
194
+ config_string = config_lines.first(max_lines).join("\n")
195
+ config_string << "\n\n"
196
+ config_string << "#{dark}(#{(config_line_count - max_lines)} more lines were not shown, use -c to show the config)#{reset}"
197
+ #config_string << "\n"
198
+ end
199
+ # strip --- yaml header
200
+ if config_string[0..3] == "---\n"
201
+ config_string = config_string[4..-1]
202
+ end
203
+ print reset,config_string.chomp("\n"),"\n",reset
204
+ else
205
+ print reset,"(blank)","\n",reset
206
+ end
207
+ elsif item_type_code == 'workflow' || item_type_code == 'operationalworkflow' || item_type_code == 'taskset'
169
208
  end
170
- print reset,config_string.chomp("\n"),"\n",reset
209
+ end
210
+
211
+ # Content (Wiki Page)
212
+ if !catalog_item_type["content"].to_s.empty? && options[:no_content] != true
213
+ print_h2 "Content"
214
+ print reset,catalog_item_type["content"].chomp("\n"),"\n",reset
171
215
  end
172
216
 
173
217
  print reset,"\n"
@@ -180,6 +224,10 @@ EOT
180
224
  params = {}
181
225
  optparse = Morpheus::Cli::OptionParser.new do |opts|
182
226
  opts.banner = subcommand_usage("[name] [options]")
227
+ # opts.on('-t', '--type [instance|blueprint|workflow]', "Item Type, default is instance.") do |val|
228
+ # # params['type'] = val.to_s.downcase
229
+ # options[:options]['type'] = val.to_s.downcase
230
+ # end
183
231
  build_option_type_options(opts, options, add_catalog_item_type_option_types)
184
232
  opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
185
233
  options[:config_file] = val.to_s
@@ -233,6 +281,8 @@ EOT
233
281
  payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
234
282
  else
235
283
  payload.deep_merge!({catalog_item_type_object_key => parse_passed_options(options)})
284
+ # Type prompt first
285
+ #params['type'] = Morpheus::Cli::OptionTypes.no_prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}, {'name' => 'Workflow', 'value' => 'workflow'}], 'defaultValue' => 'instance', 'required' => true}], options[:options], @api_client, options[:params])['type']
236
286
  v_prompt = Morpheus::Cli::OptionTypes.prompt(add_catalog_item_type_option_types(), options[:options], @api_client, options[:params])
237
287
  params.deep_merge!(v_prompt)
238
288
  advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_catalog_item_type_advanced_option_types, options[:options], @api_client, options[:params])
@@ -241,13 +291,15 @@ EOT
241
291
  # convert checkbox "on" and "off" to true and false
242
292
  params.booleanize!
243
293
  # convert type to refType until api accepts type
244
- if params['type'] && !params['refType']
245
- if params['type'].to_s.downcase == 'blueprint'
246
- params['refType'] = 'AppTemplate'
247
- else
248
- params['refType'] = 'InstanceType'
249
- end
250
- end
294
+ # if params['type'] && !params['refType']
295
+ # if params['type'].to_s.downcase == 'instance'
296
+ # params['refType'] = 'InstanceType'
297
+ # elsif params['type'].to_s.downcase == 'blueprint'
298
+ # params['refType'] = 'AppTemplate'
299
+ # elsif params['type'].to_s.downcase == 'workflow'
300
+ # params['refType'] = 'OperationalWorkflow'
301
+ # end
302
+ # end
251
303
  # convert config string to a map
252
304
  config = params['config']
253
305
  if config && config.is_a?(String)
@@ -261,14 +313,14 @@ EOT
261
313
  params['config'] = config_map
262
314
  end
263
315
  end
264
- if params['optionTypes']
265
- # todo: move to optionSource, so it will be /api/options/optionTypes lol
266
- prompt_results = prompt_for_option_types(params, options, @api_client)
267
- if prompt_results[:success]
268
- params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
269
- else
270
- return 1
271
- end
316
+ # massage association params a bit
317
+ params['workflow'] = {'id' => params['workflow']} if params['workflow'] && !params['workflow'].is_a?(Hash)
318
+ params['blueprint'] = {'id' => params['blueprint']} if params['blueprint'] && !params['blueprint'].is_a?(Hash)
319
+ prompt_results = prompt_for_option_types(params, options, @api_client)
320
+ if prompt_results[:success]
321
+ params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
322
+ else
323
+ return 1, "failed to parse optionTypes"
272
324
  end
273
325
  payload[catalog_item_type_object_key].deep_merge!(params)
274
326
  end
@@ -280,7 +332,7 @@ EOT
280
332
  json_response = @catalog_item_types_interface.create(payload)
281
333
  catalog_item_type = json_response[catalog_item_type_object_key]
282
334
  render_response(json_response, options, catalog_item_type_object_key) do
283
- print_green_success "Added catalog item #{catalog_item_type['name']}"
335
+ print_green_success "Added catalog item type #{catalog_item_type['name']}"
284
336
  return _get(catalog_item_type["id"], {}, options)
285
337
  end
286
338
  return 0, nil
@@ -291,7 +343,7 @@ EOT
291
343
  params = {}
292
344
  payload = {}
293
345
  optparse = Morpheus::Cli::OptionParser.new do |opts|
294
- opts.banner = subcommand_usage("[catalog item type] [options]")
346
+ opts.banner = subcommand_usage("[type] [options]")
295
347
  build_option_type_options(opts, options, update_catalog_item_type_option_types)
296
348
  opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
297
349
  options[:config_file] = val.to_s
@@ -333,7 +385,7 @@ EOT
333
385
  build_standard_update_options(opts, options)
334
386
  opts.footer = <<-EOT
335
387
  Update a catalog item type.
336
- [catalog item type] is required. This is the name or id of a catalog item type.
388
+ [type] is required. This is the name or id of a catalog item type.
337
389
  EOT
338
390
  end
339
391
  optparse.parse!(args)
@@ -356,14 +408,7 @@ EOT
356
408
  params.deep_merge!(advanced_config)
357
409
  # convert checkbox "on" and "off" to true and false
358
410
  params.booleanize!
359
- # convert type to refType until api accepts type
360
- if params['type'] && !params['refType']
361
- if params['type'].to_s.downcase == 'blueprint'
362
- params['refType'] = 'AppTemplate'
363
- else
364
- params['refType'] = 'InstanceType'
365
- end
366
- end
411
+
367
412
  # convert config string to a map
368
413
  config = params['config']
369
414
  if config && config.is_a?(String)
@@ -377,6 +422,18 @@ EOT
377
422
  params['config'] = config_map
378
423
  end
379
424
  end
425
+ if params['optionTypes']
426
+ # todo: move to optionSource, so it will be /api/options/optionTypes lol
427
+ prompt_results = prompt_for_option_types(params, options, @api_client)
428
+ if prompt_results[:success]
429
+ params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
430
+ else
431
+ return 1, "failed to parse optionTypes"
432
+ end
433
+ end
434
+ # massage association params a bit
435
+ params['workflow'] = {'id' => params['workflow']} if params['workflow'] && !params['workflow'].is_a?(Hash)
436
+ params['blueprint'] = {'id' => params['blueprint']} if params['blueprint'] && !params['blueprint'].is_a?(Hash)
380
437
  payload.deep_merge!({catalog_item_type_object_key => params})
381
438
  if payload[catalog_item_type_object_key].empty? # || options[:no_prompt]
382
439
  raise_command_error "Specify at least one option to update.\n#{optparse}"
@@ -390,7 +447,7 @@ EOT
390
447
  json_response = @catalog_item_types_interface.update(catalog_item_type['id'], payload)
391
448
  catalog_item_type = json_response[catalog_item_type_object_key]
392
449
  render_response(json_response, options, catalog_item_type_object_key) do
393
- print_green_success "Updated catalog item #{catalog_item_type['name']}"
450
+ print_green_success "Updated catalog item type #{catalog_item_type['name']}"
394
451
  return _get(catalog_item_type["id"], {}, options)
395
452
  end
396
453
  return 0, nil
@@ -400,11 +457,11 @@ EOT
400
457
  options = {}
401
458
  params = {}
402
459
  optparse = Morpheus::Cli::OptionParser.new do |opts|
403
- opts.banner = subcommand_usage("[catalog item type] [options]")
460
+ opts.banner = subcommand_usage("[type] [options]")
404
461
  build_standard_remove_options(opts, options)
405
462
  opts.footer = <<-EOT
406
- Delete a catalog_item_type.
407
- [catalog item type] is required. This is the name or id of a catalog item type.
463
+ Delete a catalog item type.
464
+ [type] is required. This is the name or id of a catalog item type.
408
465
  EOT
409
466
  end
410
467
  optparse.parse!(args)
@@ -417,12 +474,12 @@ EOT
417
474
  print_dry_run @catalog_item_types_interface.dry.destroy(catalog_item_type['id'], params)
418
475
  return
419
476
  end
420
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the catalog item #{catalog_item_type['name']}?")
477
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the catalog item type #{catalog_item_type['name']}?")
421
478
  return 9, "aborted command"
422
479
  end
423
480
  json_response = @catalog_item_types_interface.destroy(catalog_item_type['id'], params)
424
481
  render_response(json_response, options) do
425
- print_green_success "Removed catalog item #{catalog_item_type['name']}"
482
+ print_green_success "Removed catalog item type #{catalog_item_type['name']}"
426
483
  end
427
484
  return 0, nil
428
485
  end
@@ -436,6 +493,9 @@ EOT
436
493
  "Description" => 'description',
437
494
  "Type" => lambda {|it| format_catalog_type(it) },
438
495
  "Blueprint" => lambda {|it| it['blueprint'] ? it['blueprint']['name'] : nil },
496
+ "Workflow" => lambda {|it| it['workflow'] ? it['workflow']['name'] : nil },
497
+ "Context" => lambda {|it| it['context'] },
498
+ # "Content" => lambda {|it| it['content'] },
439
499
  "Enabled" => lambda {|it| format_boolean(it['enabled']) },
440
500
  "Featured" => lambda {|it| format_boolean(it['featured']) },
441
501
  #"Config" => lambda {|it| it['config'] },
@@ -455,6 +515,7 @@ EOT
455
515
  out << (catalog_item_type['type']['name'] || catalog_item_type['type']['code']) rescue catalog_item_type['type'].to_s
456
516
  end
457
517
  else
518
+ # refType is not returned
458
519
  ref_type = catalog_item_type['refType']
459
520
  if ref_type == 'InstanceType'
460
521
  out << "Instance"
@@ -469,18 +530,24 @@ EOT
469
530
  out
470
531
  end
471
532
 
472
- # this is not so simple, need to first choose select instance, host or provider
473
533
  def add_catalog_item_type_option_types
474
534
  [
535
+ {'code' => 'catalogItemType.type', 'shorthand' => '-t', 'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}, {'name' => 'Workflow', 'value' => 'workflow'}], 'defaultValue' => 'instance', 'required' => true},
475
536
  {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
476
537
  {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
477
- {'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}], 'defaultValue' => 'instance'},
478
538
  {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'defaultValue' => true},
479
539
  {'fieldName' => 'featured', 'fieldLabel' => 'Featured', 'type' => 'checkbox', 'defaultValue' => false},
480
540
  {'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'required' => true},
481
541
  {'fieldName' => 'iconPath', 'fieldLabel' => 'Logo', 'type' => 'select', 'optionSource' => 'iconList'},
482
542
  #{'fieldName' => 'optionTypes', 'fieldLabel' => 'Option Types', 'type' => 'text', 'description' => 'Option Types to include, comma separated list of names or IDs.'},
483
- {'fieldName' => 'config', 'fieldLabel' => 'Config', 'type' => 'code-editor', 'required' => true, 'description' => 'JSON or YAML'}
543
+ {'dependsOnCode' => 'catalogItemType.type:instance', 'fieldName' => 'config', 'fieldLabel' => 'Config', 'type' => 'code-editor', 'description' => 'JSON or YAML', 'required' => true},
544
+ {'dependsOnCode' => 'catalogItemType.type:blueprint', 'fieldName' => 'blueprint', 'fieldLabel' => 'Blueprint', 'type' => 'select', 'optionSource' => 'blueprints', 'description' => 'Choose a blueprint to apply to the catalog item.', 'required' => true, 'noParams' => true},
545
+ {'dependsOnCode' => 'catalogItemType.type:blueprint', 'fieldName' => 'appSpec', 'fieldLabel' => 'App Spec', 'type' => 'code-editor', 'description' => 'Enter a spec in the for the App, the Scribe YAML format', 'required' => true},
546
+ {'dependsOnCode' => 'catalogItemType.type:workflow', 'fieldName' => 'workflow', 'fieldLabel' => 'Workflow', 'type' => 'select', 'optionSource' => 'operationWorkflows', 'description' => 'Enter a spec in the for the App, the Scribe YAML format', 'noParams' => true},
547
+ {'dependsOnCode' => 'catalogItemType.type:workflow', 'fieldName' => 'context', 'fieldLabel' => 'Context Type', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
548
+ [{'name' => "Select", 'value' => ""}, {'name' => "None", 'value' => "appliance"}, {'name' => "Instance", 'value' => "instance"}, {'name' => "Server", 'value' => "server"}]
549
+ }, 'description' => 'Context for operational workflow, determines target type', 'defaultValue' => 'Select', 'required' => false},
550
+ {'fieldName' => 'content', 'fieldLabel' => 'Content', 'type' => 'code-editor', 'description' => 'Wiki Page Content describing the catalog item'}
484
551
  ]
485
552
  end
486
553
 
@@ -489,11 +556,13 @@ EOT
489
556
  end
490
557
 
491
558
  def update_catalog_item_type_option_types
492
- add_catalog_item_type_option_types.collect {|it|
559
+ list = add_catalog_item_type_option_types.collect {|it|
493
560
  it.delete('required')
494
561
  it.delete('defaultValue')
495
562
  it
496
563
  }
564
+ list = list.reject {|it| ["type"].include? it['fieldName'] }
565
+ list
497
566
  end
498
567
 
499
568
  def update_catalog_item_type_advanced_option_types
@@ -504,4 +573,50 @@ EOT
504
573
  }
505
574
  end
506
575
 
576
+ def catalog_item_type_object_key
577
+ 'catalogItemType'
578
+ end
579
+
580
+ def catalog_item_type_list_key
581
+ 'catalogItemTypes'
582
+ end
583
+
584
+ def find_catalog_item_type_by_name_or_id(val)
585
+ if val.to_s =~ /\A\d{1,}\Z/
586
+ return find_catalog_item_type_by_id(val)
587
+ else
588
+ return find_catalog_item_type_by_name(val)
589
+ end
590
+ end
591
+
592
+ def find_catalog_item_type_by_id(id)
593
+ begin
594
+ json_response = @catalog_item_types_interface.get(id.to_i)
595
+ return json_response[catalog_item_type_object_key]
596
+ rescue RestClient::Exception => e
597
+ if e.response && e.response.code == 404
598
+ print_red_alert "catalog item type not found by id '#{id}'"
599
+ else
600
+ raise e
601
+ end
602
+ end
603
+ end
604
+
605
+ def find_catalog_item_type_by_name(name)
606
+ json_response = @catalog_item_types_interface.list({name: name.to_s})
607
+ catalog_item_types = json_response[catalog_item_type_list_key]
608
+ if catalog_item_types.empty?
609
+ print_red_alert "catalog item type not found by name '#{name}'"
610
+ return nil
611
+ elsif catalog_item_types.size > 1
612
+ print_red_alert "#{catalog_item_types.size} catalog item types found by name '#{name}'"
613
+ puts_error as_pretty_table(catalog_item_types, [:id, :name], {color:red})
614
+ print_red_alert "Try using ID instead"
615
+ print reset,"\n"
616
+ return nil
617
+ else
618
+ return catalog_item_types[0]
619
+ end
620
+ end
621
+
507
622
  end