morpheus-cli 3.6.3 → 3.6.4

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.
@@ -43,16 +43,15 @@ class Morpheus::Cli::BlueprintsCommand
43
43
  options = {}
44
44
  optparse = Morpheus::Cli::OptionParser.new do |opts|
45
45
  opts.banner = subcommand_usage()
46
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
46
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
47
47
  opts.footer = "List blueprints."
48
48
  end
49
49
  optparse.parse!(args)
50
50
  connect(options)
51
51
  begin
52
52
  params = {}
53
- [:phrase, :offset, :max, :sort, :direction].each do |k|
54
- params[k] = options[k] unless options[k].nil?
55
- end
53
+ params.merge!(parse_list_options(options))
54
+
56
55
  if options[:dry_run]
57
56
  print_dry_run @blueprints_interface.dry.list(params)
58
57
  return
@@ -75,10 +74,9 @@ class Morpheus::Cli::BlueprintsCommand
75
74
 
76
75
  title = "Morpheus Blueprints"
77
76
  subtitles = []
78
- if params[:phrase]
79
- subtitles << "Search: #{params[:phrase]}".strip
80
- end
77
+ subtitles += parse_list_subtitles(options)
81
78
  print_h1 title, subtitles
79
+
82
80
  if blueprints.empty?
83
81
  print cyan,"No blueprints found.",reset,"\n"
84
82
  else
@@ -101,7 +99,7 @@ class Morpheus::Cli::BlueprintsCommand
101
99
  opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
102
100
  options[:show_config] = true
103
101
  end
104
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
102
+ build_common_options(opts, options, [:json, :yaml, :csv, :fields, :outfile, :dry_run, :remote])
105
103
  opts.footer = "Get details about a blueprint.\n" +
106
104
  "[id] is required. This is the name or id of a blueprint."
107
105
  end
@@ -127,61 +125,48 @@ class Morpheus::Cli::BlueprintsCommand
127
125
  #json_response = @blueprints_interface.get(blueprint['id'])
128
126
  blueprint = json_response['blueprint']
129
127
 
128
+ # export just the config as json or yaml (default)
130
129
  if options[:show_config]
131
- #print_h2 "RAW"
132
- if options[:json]
133
- print cyan
134
- print "// JSON config for Morpheus Blueprint: #{blueprint['name']}","\n"
135
- print reset
136
- puts as_json(blueprint["config"])
137
- else
138
- print cyan
139
- print "# YAML config for Morpheus Blueprint: #{blueprint['name']}","\n"
140
- print reset
141
- puts as_yaml(blueprint["config"])
130
+ unless options[:json] || options[:yaml] || options[:csv]
131
+ options[:yaml] = true
142
132
  end
143
- return 0
133
+ blueprint_config = blueprint['config']
134
+ render_result = render_with_format(blueprint_config, options)
135
+ return 0 if render_result
144
136
  end
145
137
 
146
- if options[:json]
147
- puts as_json(json_response, options, "blueprint")
148
- return 0
149
- elsif options[:yaml]
150
- puts as_yaml(json_response, options, "blueprint")
151
- return 0
152
- elsif options[:csv]
153
- puts records_as_csv([json_response['blueprint']], options)
154
- return 0
155
- end
156
-
138
+ render_result = render_with_format(json_response, options, 'blueprint')
139
+ return 0 if render_result
140
+
157
141
  print_h1 "Blueprint Details"
158
142
 
159
143
  print_blueprint_details(blueprint)
160
144
 
161
145
  if blueprint['resourcePermission'].nil?
162
- print "\n", "No group access found", "\n"
146
+ #print "\n", "No group access found", "\n"
163
147
  else
164
- print_h2 "Group Access"
165
- rows = []
166
- if blueprint['resourcePermission']['allSites'] || blueprint['resourcePermission']['all']
167
- rows.push({"name" => 'All'})
168
- end
169
- if blueprint['resourcePermission']['sites']
170
- blueprint['resourcePermission']['sites'].each do |site|
171
- rows.push(site)
172
- end
173
- end
174
- rows = rows.collect do |site|
175
- {group: site['name'], default: site['default'] ? 'Yes' : ''}
176
- end
177
- # columns = [:group, :default]
178
- columns = [:group]
179
- print cyan
180
- print as_pretty_table(rows, columns)
148
+ # print_h2 "Group Access"
149
+ # rows = []
150
+ # if blueprint['resourcePermission']['allSites'] || blueprint['resourcePermission']['all']
151
+ # rows.push({"name" => 'All'})
152
+ # end
153
+ # if blueprint['resourcePermission']['sites']
154
+ # blueprint['resourcePermission']['sites'].each do |site|
155
+ # rows.push(site)
156
+ # end
157
+ # end
158
+ # rows = rows.collect do |site|
159
+ # {group: site['name'], default: site['default'] ? 'Yes' : ''}
160
+ # end
161
+ # # columns = [:group, :default]
162
+ # columns = [:group]
163
+ # print cyan
164
+ # print as_pretty_table(rows, columns)
165
+ # print reset,"\n"
181
166
  end
182
167
 
183
- print reset,"\n"
184
-
168
+ #print reset,"\n"
169
+ return 0
185
170
  rescue RestClient::Exception => e
186
171
  print_rest_exception(e, options)
187
172
  exit 1
@@ -192,83 +177,42 @@ class Morpheus::Cli::BlueprintsCommand
192
177
  options = {}
193
178
  optparse = Morpheus::Cli::OptionParser.new do |opts|
194
179
  opts.banner = subcommand_usage("[name] [options]")
195
- opts.on('--config JSON', String, "Blueprint Config JSON") do |val|
196
- options[:config] = JSON.parse(val.to_s)
197
- end
198
- opts.on('--config-yaml YAML', String, "Blueprint Config YAML") do |val|
199
- options[:config] = YAML.load(val.to_s)
200
- end
201
- opts.on('--config-file FILE', String, "Blueprint Config from a local JSON or YAML file") do |val|
202
- options[:config_file] = val.to_s
203
- end
204
- opts.on('--config-dir DIRECTORY', String, "Blueprint Config from a local directory, merging all JSON or YAML files") do |val|
205
- options[:config_dir] = val.to_s
206
- end
207
180
  build_option_type_options(opts, options, add_blueprint_option_types(false))
208
- build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
181
+ opts.on('-t', '--type TYPE', String, "Blueprint Type. Default is morpheus.") do |val|
182
+ options[:blueprint_type] = val.to_s
183
+ end
184
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
209
185
  opts.footer = "Create a new blueprint.\n" +
210
- "[name] is optional and can be passed as --name or inside the config instead."
211
- "[--config] or [--config-file] can be used to define the blueprint."
186
+ "[name] is required. This is the name of the new blueprint."
212
187
  end
213
188
  optparse.parse!(args)
214
189
  if args.count > 1
215
190
  print_error Morpheus::Terminal.angry_prompt
216
- puts_error "#{command_name} add expects 0-1 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
191
+ puts_error "#{command_name} add expects 0-1 arguments and received #{args.count}: #{args}\n#{optparse}"
217
192
  return 1
218
193
  end
219
194
  options[:options] ||= {}
220
- if args[0] && !options[:options]['name']
195
+ if args[0]
221
196
  options[:options]['name'] = args[0]
222
197
  end
223
198
  connect(options)
224
199
  begin
225
- payload = nil
226
- if options[:config]
227
- config_payload = options[:config]
228
- payload = config_payload
229
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
230
- elsif options[:config_file]
231
- config_file = File.expand_path(options[:config_file])
232
- if !File.exists?(config_file) || !File.file?(config_file)
233
- print_red_alert "File not found: #{config_file}"
234
- return false
235
- end
236
- if config_file =~ /\.ya?ml\Z/
237
- config_payload = YAML.load_file(config_file)
238
- else
239
- config_payload = JSON.parse(File.read(config_file))
240
- end
241
- payload = config_payload
242
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
243
- elsif options[:config_dir]
244
- config_dir = File.expand_path(options[:config_dir])
245
- if !Dir.exists?(config_dir) || !File.directory?(config_dir)
246
- print_red_alert "Directory not found: #{config_dir}"
247
- return false
248
- end
249
- merged_payload = {}
250
- config_files = []
251
- config_files += Dir["#{config_dir}/*.json"]
252
- config_files += Dir["#{config_dir}/*.yml"]
253
- config_files += Dir["#{config_dir}/*.yaml"]
254
- if config_files.empty?
255
- print_red_alert "No .json/yaml files found in config directory: #{config_dir}"
256
- return false
257
- end
258
- config_files.each do |config_file|
259
- if config_file =~ /\.ya?ml\Z/
260
- config_payload = YAML.load_file(config_file)
261
- else
262
- config_payload = JSON.parse(File.read(config_file))
263
- end
264
- merged_payload.deep_merge!(config_payload)
265
- end
266
- payload = merged_payload
267
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
200
+ payload = {}
201
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
202
+ if options[:payload]
203
+ payload = options[:payload]
204
+ payload.deep_merge!(passed_options) unless passed_options.empty?
268
205
  else
206
+ # prompt for payload
269
207
  payload = {}
270
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
208
+ payload.deep_merge!(passed_options) unless passed_options.empty?
209
+ if options[:blueprint_type]
210
+ options[:options]['type'] = options[:blueprint_type]
211
+ else
212
+ # options[:options]['type'] = 'morpheus'
213
+ end
271
214
  params = Morpheus::Cli::OptionTypes.prompt(add_blueprint_option_types, options[:options], @api_client, options[:params])
215
+ params.deep_compact!
272
216
  #blueprint_payload = params.select {|k,v| ['name', 'description', 'category'].include?(k) }
273
217
  # expects no namespace, just the config
274
218
  #payload = blueprint_payload
@@ -289,8 +233,7 @@ class Morpheus::Cli::BlueprintsCommand
289
233
  blueprint = json_response["blueprint"]
290
234
  print_green_success "Added blueprint #{blueprint['name']}"
291
235
  if !options[:no_prompt]
292
- prompt_for_tier = options[:config].nil? && options[:config_file].nil? && options[:config_dir].nil?
293
- if prompt_for_tier && ::Morpheus::Cli::OptionTypes::confirm("Would you like to add a tier now?", options.merge({default: false}))
236
+ if options[:payload].nil? && ::Morpheus::Cli::OptionTypes::confirm("Would you like to add a tier now?", options.merge({default: false}))
294
237
  add_tier([blueprint['id']])
295
238
  while ::Morpheus::Cli::OptionTypes::confirm("Add another tier?", options.merge({default: false})) do
296
239
  add_tier([blueprint['id']])
@@ -312,20 +255,8 @@ class Morpheus::Cli::BlueprintsCommand
312
255
  options = {}
313
256
  optparse = Morpheus::Cli::OptionParser.new do |opts|
314
257
  opts.banner = subcommand_usage("[id] [options]")
315
- opts.on('--config JSON', String, "Blueprint Config JSON") do |val|
316
- options[:config] = JSON.parse(val.to_s)
317
- end
318
- opts.on('--config-yaml YAML', String, "Blueprint Config YAML") do |val|
319
- options[:config] = YAML.load(val.to_s)
320
- end
321
- opts.on('--config-file FILE', String, "Blueprint Config from a local JSON or YAML file") do |val|
322
- options[:config_file] = val.to_s
323
- end
324
- opts.on('--config-dir DIRECTORY', String, "Blueprint Config from a local directory, merging all JSON or YAML files") do |val|
325
- options[:config_dir] = val.to_s
326
- end
327
258
  build_option_type_options(opts, options, update_blueprint_option_types(false))
328
- build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
259
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
329
260
  opts.footer = "Update a blueprint.\n" +
330
261
  "[id] is required. This is the name or id of a blueprint.\n" +
331
262
  "[options] Available options include --name and --description. This will update only the specified values.\n" +
@@ -343,54 +274,23 @@ class Morpheus::Cli::BlueprintsCommand
343
274
  begin
344
275
 
345
276
  blueprint = find_blueprint_by_name_or_id(args[0])
346
- exit 1 if blueprint.nil?
277
+ return 1 if blueprint.nil?
347
278
 
348
- payload = nil
349
- if options[:config]
350
- config_payload = options[:config]
351
- payload = config_payload
352
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
353
- elsif options[:config_file]
354
- config_file = options[:config_file]
355
- if !File.exists?(config_file)
356
- print_red_alert "File not found: #{config_file}"
357
- return false
358
- end
359
- if config_file =~ /\.ya?ml\Z/
360
- config_payload = YAML.load_file(config_file)
361
- else
362
- config_payload = JSON.parse(File.read(config_file))
363
- end
364
- payload = config_payload
365
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
366
- elsif options[:config_dir]
367
- config_dir = File.expand_path(options[:config_dir])
368
- if !Dir.exists?(config_dir) || !File.directory?(config_dir)
369
- print_red_alert "Directory not found: #{config_dir}"
370
- return false
371
- end
372
- merged_payload = {}
373
- config_files = []
374
- config_files += Dir["#{config_dir}/*.json"]
375
- config_files += Dir["#{config_dir}/*.yml"]
376
- config_files += Dir["#{config_dir}/*.yaml"]
377
- if config_files.empty?
378
- print_red_alert "No .json/yaml files found in config directory: #{config_dir}"
379
- return false
380
- end
381
- config_files.each do |config_file|
382
- if config_file =~ /\.ya?ml\Z/
383
- config_payload = YAML.load_file(config_file)
384
- else
385
- config_payload = JSON.parse(File.read(config_file))
386
- end
387
- merged_payload.deep_merge!(config_payload)
388
- end
389
- payload = merged_payload
390
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
279
+ payload = {}
280
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
281
+ if options[:payload]
282
+ payload = options[:payload]
283
+ payload.deep_merge!(passed_options) unless passed_options.empty?
391
284
  else
285
+ # no prompting, just merge passed options
392
286
  payload = blueprint["config"]
393
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
287
+ payload.deep_merge!(passed_options) unless passed_options.empty?
288
+
289
+ if passed_options.empty?
290
+ print_red_alert "Specify atleast one option to update"
291
+ puts optparse
292
+ return 1
293
+ end
394
294
  end
395
295
 
396
296
  if options[:dry_run]
@@ -535,7 +435,7 @@ class Morpheus::Cli::BlueprintsCommand
535
435
  optparse.parse!(args)
536
436
  if args.count != 2
537
437
  print_error Morpheus::Terminal.angry_prompt
538
- puts_error "#{command_name} upload-image expects 2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
438
+ puts_error "#{command_name} upload-image expects 2 arguments and received #{args.count}: #{args}\n#{optparse}"
539
439
  return 1
540
440
  end
541
441
  blueprint_name = args[0]
@@ -690,7 +590,7 @@ class Morpheus::Cli::BlueprintsCommand
690
590
 
691
591
  if args.count < 1
692
592
  print_error Morpheus::Terminal.angry_prompt
693
- puts_error "#{command_name} add-instance expects 3 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
593
+ puts_error "#{command_name} add-instance expects 3 arguments and received #{args.count}: #{args}\n#{optparse}"
694
594
  return 1
695
595
  end
696
596
 
@@ -1248,6 +1148,7 @@ class Morpheus::Cli::BlueprintsCommand
1248
1148
  options = {}
1249
1149
  boot_order = nil
1250
1150
  linked_tiers = nil
1151
+ tier_index = nil
1251
1152
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1252
1153
  opts.banner = subcommand_usage("[id] [tier]")
1253
1154
  opts.on('--name VALUE', String, "Tier Name") do |val|
@@ -1259,6 +1160,9 @@ class Morpheus::Cli::BlueprintsCommand
1259
1160
  opts.on('--linkedTiers x,y,z', Array, "Connected Tiers.") do |val|
1260
1161
  linked_tiers = val
1261
1162
  end
1163
+ opts.on('--tierIndex NUMBER', Array, "Tier Index. Used for Display Order") do |val|
1164
+ tier_index = val
1165
+ end
1262
1166
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
1263
1167
  end
1264
1168
  optparse.parse!(args)
@@ -1329,6 +1233,19 @@ class Morpheus::Cli::BlueprintsCommand
1329
1233
  end
1330
1234
  end
1331
1235
 
1236
+ # Tier Index
1237
+ if !tier_index
1238
+ #v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'tierIndex', 'fieldLabel' => 'Tier Index', 'type' => 'number', 'required' => false, 'description' => 'Sequence order for displaying app instances by tier. 0-N', 'defaultValue' => tier['tierIndex']}], options[:options])
1239
+ #tier_index = v_prompt['tierIndex']
1240
+ tier_index = (tiers.size - 1)
1241
+ end
1242
+
1243
+ if tier_index.to_s == 'null'
1244
+ tier.delete('tierIndex')
1245
+ elsif tier_index
1246
+ tier['tierIndex'] = tier_index.to_i
1247
+ end
1248
+
1332
1249
  # ok, make api request
1333
1250
  blueprint["config"]["tiers"] = tiers
1334
1251
  payload = blueprint["config"]
@@ -1370,6 +1287,7 @@ class Morpheus::Cli::BlueprintsCommand
1370
1287
  new_tier_name = nil
1371
1288
  boot_order = nil
1372
1289
  linked_tiers = nil
1290
+ tier_index = nil
1373
1291
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1374
1292
  opts.banner = subcommand_usage("[id] [tier]")
1375
1293
  opts.on('--name VALUE', String, "Tier Name") do |val|
@@ -1381,13 +1299,16 @@ class Morpheus::Cli::BlueprintsCommand
1381
1299
  opts.on('--linkedTiers x,y,z', Array, "Connected Tiers") do |val|
1382
1300
  linked_tiers = val
1383
1301
  end
1302
+ opts.on('--tierIndex NUMBER', String, "Tier Index. Used for Display Order") do |val|
1303
+ tier_index = val.to_i
1304
+ end
1384
1305
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
1385
1306
  end
1386
1307
  optparse.parse!(args)
1387
1308
 
1388
1309
  if args.count != 2
1389
1310
  print_error Morpheus::Terminal.angry_prompt
1390
- puts_error "#{command_name} update-tier expects 2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1311
+ puts_error "#{command_name} update-tier expects 2 arguments and received #{args.count}: #{args}\n#{optparse}"
1391
1312
  return 1
1392
1313
  end
1393
1314
  blueprint_name = args[0]
@@ -1409,15 +1330,18 @@ class Morpheus::Cli::BlueprintsCommand
1409
1330
  end
1410
1331
  tier = tiers[tier_name]
1411
1332
 
1333
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
1412
1334
 
1413
1335
  if options[:no_prompt]
1414
- if !(new_tier_name || boot_order || linked_tiers)
1336
+ if !(new_tier_name || boot_order || linked_tiers || tier_index || !passed_options.empty?)
1415
1337
  print_error Morpheus::Terminal.angry_prompt
1416
1338
  puts_error "#{command_name} update-tier requires an option to update.\n#{optparse}"
1417
1339
  return 1
1418
1340
  end
1419
1341
  end
1420
1342
 
1343
+ tier.deep_merge!(passed_options) unless passed_options.empty?
1344
+
1421
1345
  # prompt update tier
1422
1346
  # Name
1423
1347
  if !new_tier_name
@@ -1474,6 +1398,13 @@ class Morpheus::Cli::BlueprintsCommand
1474
1398
  end
1475
1399
  end
1476
1400
 
1401
+ # Tier Index
1402
+ if tier_index.to_s == 'null'
1403
+ tier.delete('tierIndex')
1404
+ elsif tier_index
1405
+ tier['tierIndex'] = tier_index.to_i
1406
+ end
1407
+
1477
1408
  # ok, make api request
1478
1409
  blueprint["config"]["tiers"] = tiers
1479
1410
  payload = blueprint["config"]
@@ -1508,7 +1439,7 @@ class Morpheus::Cli::BlueprintsCommand
1508
1439
 
1509
1440
  if args.count < 2
1510
1441
  print_error Morpheus::Terminal.angry_prompt
1511
- puts_error "#{command_name} remove-tier expects 2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1442
+ puts_error "#{command_name} remove-tier expects 2 arguments and received #{args.count}: #{args}\n#{optparse}"
1512
1443
  return 1
1513
1444
  end
1514
1445
  blueprint_name = args[0]
@@ -1575,7 +1506,7 @@ class Morpheus::Cli::BlueprintsCommand
1575
1506
 
1576
1507
  if args.count < 3
1577
1508
  print_error Morpheus::Terminal.angry_prompt
1578
- puts_error "#{command_name} connect-tiers expects 3 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1509
+ puts_error "#{command_name} connect-tiers expects 3 arguments and received #{args.count}: #{args}\n#{optparse}"
1579
1510
  # puts optparse
1580
1511
  return 1
1581
1512
  end
@@ -1673,7 +1604,7 @@ class Morpheus::Cli::BlueprintsCommand
1673
1604
 
1674
1605
  if args.count < 3
1675
1606
  print_error Morpheus::Terminal.angry_prompt
1676
- puts_error "#{command_name} disconnect-tiers expects 3 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1607
+ puts_error "#{command_name} disconnect-tiers expects 3 arguments and received #{args.count}: #{args}\n#{optparse}"
1677
1608
  # puts optparse
1678
1609
  return 1
1679
1610
  end
@@ -1869,11 +1800,10 @@ class Morpheus::Cli::BlueprintsCommand
1869
1800
 
1870
1801
  def add_blueprint_option_types(connected=true)
1871
1802
  [
1872
- {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
1873
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
1874
- # skip Type for now because other types need to use --config anyhow
1875
- #{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => (connected ? get_available_blueprint_types() : []), 'required' => true, 'defaultValue' => 'morpheus', 'displayOrder' => 3},
1876
- {'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'text', 'required' => false, 'displayOrder' => 4},
1803
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for this app'},
1804
+ {'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => (connected ? get_available_blueprint_types() : []), 'required' => true, 'defaultValue' => 'morpheus'},
1805
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false},
1806
+ {'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'text', 'required' => false},
1877
1807
  #{'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'selectOptions' => (connected ? get_available_groups() : []), 'required' => true}
1878
1808
  ]
1879
1809
  end
@@ -1897,7 +1827,7 @@ class Morpheus::Cli::BlueprintsCommand
1897
1827
 
1898
1828
  def update_blueprint_option_types(connected=true)
1899
1829
  list = add_blueprint_option_types(connected)
1900
- list = list.reject {|it| ["group"].include? it['fieldName'] }
1830
+ list = list.select {|it| ["name","decription","category"].include? it['fieldName'] }
1901
1831
  list.each {|it| it['required'] = false }
1902
1832
  list
1903
1833
  end
@@ -2064,14 +1994,36 @@ class Morpheus::Cli::BlueprintsCommand
2064
1994
  "Type" => lambda {|it| it['type'].kind_of?(Hash) ? it['type']['name'] : it['type'] },
2065
1995
  "Category" => 'category',
2066
1996
  "Image" => lambda {|it| it['config'] ? (it['config']['image'] == '/assets/apps/template.png' ? '(default)' : it['config']['image']) : '' },
2067
- "Visibility" => 'visibility'
1997
+ "Visibility" => 'visibility',
1998
+ "Group Access" => lambda {|it|
1999
+ group_access_str = ""
2000
+ begin
2001
+ rows = []
2002
+ if blueprint['resourcePermission']['allSites'] || blueprint['resourcePermission']['all']
2003
+ rows.push({"name" => 'All'})
2004
+ end
2005
+ if blueprint['resourcePermission']['sites']
2006
+ blueprint['resourcePermission']['sites'].each do |site|
2007
+ rows.push(site)
2008
+ end
2009
+ end
2010
+ group_access_str = rows.collect {|it| it['default'] ? "#{it['name']} (default)" : "#{it['name']}"}.join(',')
2011
+ rescue => ex
2012
+ Morpheus::Logging::DarkPrinter.puts "Error parsing group access: #{ex}" if Morpheus::Logging.debug?
2013
+ end
2014
+ group_access_str
2015
+ }
2068
2016
  }
2069
2017
  print_description_list(description_cols, blueprint)
2070
2018
  # print_h2 "Tiers"
2071
2019
  if blueprint["config"] && blueprint["config"]["tiers"] && blueprint["config"]["tiers"].keys.size != 0
2072
2020
  print cyan
2073
2021
  #puts as_yaml(blueprint["config"]["tiers"])
2074
- blueprint["config"]["tiers"].each do |tier_name, tier_config|
2022
+ tiers = blueprint["config"]["tiers"]
2023
+ sorted_tiers = tiers.collect {|k,v| [k,v] }.sort {|a,b| a[1]['tierIndex'] <=> b[1]['tierIndex'] }
2024
+ sorted_tiers.each do |tier_obj|
2025
+ tier_name = tier_obj[0]
2026
+ tier_config = tier_obj[1]
2075
2027
  # print_h2 "Tier: #{tier_name}"
2076
2028
  print_h2 tier_name
2077
2029
  # puts " Instances:"