morpheus-cli 4.2.8 → 4.2.10

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api.rb +1 -1
  4. data/lib/morpheus/api/activity_interface.rb +9 -0
  5. data/lib/morpheus/api/api_client.rb +83 -27
  6. data/lib/morpheus/api/apps_interface.rb +21 -0
  7. data/lib/morpheus/api/dashboard_interface.rb +5 -21
  8. data/lib/morpheus/api/instances_interface.rb +3 -10
  9. data/lib/morpheus/api/invoice_line_items_interface.rb +14 -0
  10. data/lib/morpheus/api/invoices_interface.rb +7 -12
  11. data/lib/morpheus/api/library_layouts_interface.rb +8 -0
  12. data/lib/morpheus/api/ping_interface.rb +20 -0
  13. data/lib/morpheus/api/projects_interface.rb +33 -0
  14. data/lib/morpheus/api/setup_interface.rb +19 -36
  15. data/lib/morpheus/api/user_settings_interface.rb +0 -6
  16. data/lib/morpheus/api/whoami_interface.rb +4 -8
  17. data/lib/morpheus/benchmarking.rb +16 -26
  18. data/lib/morpheus/cli.rb +10 -5
  19. data/lib/morpheus/cli/access_token_command.rb +5 -8
  20. data/lib/morpheus/cli/activity_command.rb +146 -0
  21. data/lib/morpheus/cli/apps.rb +312 -121
  22. data/lib/morpheus/cli/archives_command.rb +1 -1
  23. data/lib/morpheus/cli/auth_command.rb +4 -11
  24. data/lib/morpheus/cli/blueprints_command.rb +196 -137
  25. data/lib/morpheus/cli/change_password_command.rb +1 -1
  26. data/lib/morpheus/cli/cli_command.rb +225 -72
  27. data/lib/morpheus/cli/cli_registry.rb +2 -2
  28. data/lib/morpheus/cli/cloud_datastores_command.rb +1 -1
  29. data/lib/morpheus/cli/clouds.rb +5 -20
  30. data/lib/morpheus/cli/clusters.rb +4 -28
  31. data/lib/morpheus/cli/commands/standard/alias_command.rb +2 -9
  32. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +2 -0
  33. data/lib/morpheus/cli/commands/standard/curl_command.rb +2 -3
  34. data/lib/morpheus/cli/commands/standard/history_command.rb +3 -6
  35. data/lib/morpheus/cli/commands/standard/man_command.rb +10 -7
  36. data/lib/morpheus/cli/commands/standard/ssl_verification_command.rb +10 -9
  37. data/lib/morpheus/cli/containers_command.rb +3 -3
  38. data/lib/morpheus/cli/credentials.rb +13 -16
  39. data/lib/morpheus/cli/error_handler.rb +18 -12
  40. data/lib/morpheus/cli/errors.rb +45 -0
  41. data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
  42. data/lib/morpheus/cli/execution_request_command.rb +4 -4
  43. data/lib/morpheus/cli/groups.rb +84 -132
  44. data/lib/morpheus/cli/hosts.rb +6 -16
  45. data/lib/morpheus/cli/instances.rb +100 -183
  46. data/lib/morpheus/cli/invoices_command.rb +505 -71
  47. data/lib/morpheus/cli/library_layouts_command.rb +254 -166
  48. data/lib/morpheus/cli/library_option_lists_command.rb +0 -87
  49. data/lib/morpheus/cli/library_option_types_command.rb +0 -96
  50. data/lib/morpheus/cli/license.rb +3 -0
  51. data/lib/morpheus/cli/login.rb +17 -37
  52. data/lib/morpheus/cli/logout.rb +9 -5
  53. data/lib/morpheus/cli/mixins/accounts_helper.rb +83 -7
  54. data/lib/morpheus/cli/mixins/operations_helper.rb +41 -0
  55. data/lib/morpheus/cli/mixins/option_source_helper.rb +255 -0
  56. data/lib/morpheus/cli/mixins/print_helper.rb +18 -4
  57. data/lib/morpheus/cli/mixins/provisioning_helper.rb +222 -13
  58. data/lib/morpheus/cli/mixins/remote_helper.rb +139 -0
  59. data/lib/morpheus/cli/monitoring_checks_command.rb +11 -3
  60. data/lib/morpheus/cli/network_groups_command.rb +8 -2
  61. data/lib/morpheus/cli/option_types.rb +1 -1
  62. data/lib/morpheus/cli/ping.rb +252 -0
  63. data/lib/morpheus/cli/price_sets_command.rb +16 -27
  64. data/lib/morpheus/cli/prices_command.rb +34 -27
  65. data/lib/morpheus/cli/processes_command.rb +81 -7
  66. data/lib/morpheus/cli/projects_command.rb +607 -0
  67. data/lib/morpheus/cli/recent_activity_command.rb +87 -65
  68. data/lib/morpheus/cli/remote.rb +965 -974
  69. data/lib/morpheus/cli/reports_command.rb +3 -15
  70. data/lib/morpheus/cli/roles.rb +8 -31
  71. data/lib/morpheus/cli/service_plans_command.rb +25 -31
  72. data/lib/morpheus/cli/setup.rb +392 -0
  73. data/lib/morpheus/cli/shell.rb +144 -56
  74. data/lib/morpheus/cli/subnets_command.rb +71 -11
  75. data/lib/morpheus/cli/tasks.rb +3 -3
  76. data/lib/morpheus/cli/user_sources_command.rb +4 -4
  77. data/lib/morpheus/cli/users.rb +135 -109
  78. data/lib/morpheus/cli/version.rb +1 -1
  79. data/lib/morpheus/cli/whitelabel_settings_command.rb +7 -7
  80. data/lib/morpheus/cli/whoami.rb +90 -129
  81. data/lib/morpheus/cli/wiki_command.rb +2 -14
  82. data/lib/morpheus/ext/rest_client.rb +36 -0
  83. data/lib/morpheus/formatters.rb +42 -5
  84. data/lib/morpheus/rest_client.rb +0 -10
  85. data/lib/morpheus/terminal.rb +41 -1
  86. data/lib/morpheus/util.rb +24 -0
  87. metadata +16 -3
  88. data/lib/morpheus/cli/command_error.rb +0 -22
@@ -1206,7 +1206,7 @@ class Morpheus::Cli::ArchivesCommand
1206
1206
  print_archive_file_links_table(archive_file_links)
1207
1207
  print_results_pagination(json_response, {:label => "link", :n_label => "links"})
1208
1208
  else
1209
- puts "No history found"
1209
+ puts "No file links found"
1210
1210
  end
1211
1211
  print reset,"\n"
1212
1212
  return 0
@@ -1,5 +1,6 @@
1
1
  require 'morpheus/cli/cli_command'
2
2
 
3
+ # JD: this is not in use, we have login, logout and access-token instead
3
4
  # This provides commands for authentication
4
5
  # This also includes credential management.
5
6
  class Morpheus::Cli::AuthCommand
@@ -14,20 +15,12 @@ class Morpheus::Cli::AuthCommand
14
15
  # register_subcommands :'use-refresh-token' => :use_refresh_token
15
16
  register_subcommands :login, :logout
16
17
  register_subcommands :test => :login_test
17
-
18
-
19
- def initialize()
20
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
21
- end
22
18
 
23
19
  def connect(options)
24
- @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true}))
20
+ @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
25
21
  # automatically get @appliance_name, @appliance_url, @wallet
26
22
  if !@appliance_name
27
- unless options[:quiet]
28
- print yellow,"Please specify a Morpheus Appliance with -r or see the command `remote use`#{reset}\n"
29
- end
30
- return 1
23
+ raise_command_error "#{command_name} requires a remote to be specified, use -r [remote] or set the active remote with `remote use`"
31
24
  end
32
25
  if !@appliance_url
33
26
  unless options[:quiet]
@@ -39,7 +32,7 @@ class Morpheus::Cli::AuthCommand
39
32
  if @wallet.nil? || @wallet['access_token'].nil?
40
33
  unless options[:quiet]
41
34
  print_error yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
42
- print_error yellow,"Use the 'login' command.",reset,"\n"
35
+ print_error yellow,"Use `login` to authenticate.",reset,"\n"
43
36
  end
44
37
  return 1
45
38
  end
@@ -1,9 +1,11 @@
1
1
  require 'morpheus/cli/cli_command'
2
- require 'morpheus/cli/mixins/provisioning_helper'
3
2
 
4
3
  class Morpheus::Cli::BlueprintsCommand
5
4
  include Morpheus::Cli::CliCommand
6
5
  include Morpheus::Cli::ProvisioningHelper
6
+ include Morpheus::Cli::AccountsHelper # needed? replace with OptionSourceHelper
7
+ include Morpheus::Cli::OptionSourceHelper
8
+
7
9
  set_command_name :'blueprints'
8
10
  register_subcommands :list, :get, :add, :update, :remove
9
11
  register_subcommands :'types' => :list_types
@@ -34,6 +36,7 @@ class Morpheus::Cli::BlueprintsCommand
34
36
  @options_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).options
35
37
  @active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
36
38
  @clouds_interface = @api_client.clouds
39
+ @users_interface = @api_client.users
37
40
  @library_layouts_interface = @api_client.library_layouts
38
41
  end
39
42
 
@@ -42,16 +45,37 @@ class Morpheus::Cli::BlueprintsCommand
42
45
  end
43
46
 
44
47
  def list(args)
48
+ params = {}
45
49
  options = {}
46
50
  optparse = Morpheus::Cli::OptionParser.new do |opts|
47
51
  opts.banner = subcommand_usage()
52
+ opts.on('-t', '--type CODE', "Blueprint Type") do |val|
53
+ params['type'] ||= []
54
+ params['type'] << val
55
+ end
56
+ opts.on( '--owner USER', "Owner Username or ID" ) do |val|
57
+ params['ownerId'] ||= []
58
+ params['ownerId'] << val
59
+ end
60
+ opts.on( '--created-by USER', "Alias for --owner" ) do |val|
61
+ params['ownerId'] ||= []
62
+ params['ownerId'] << val
63
+ end
64
+ opts.add_hidden_option('--created-by')
48
65
  build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
49
66
  opts.footer = "List blueprints."
50
67
  end
51
68
  optparse.parse!(args)
52
69
  connect(options)
53
70
  begin
54
- params = {}
71
+ if params['ownerId']
72
+ params['ownerId'] = params['ownerId'].collect do |owner_id|
73
+ # user = find_user_by_username_or_id(nil, owner_id)
74
+ user = find_available_user_option(owner_id)
75
+ return 1 if user.nil?
76
+ user['id']
77
+ end
78
+ end
55
79
  params.merge!(parse_list_options(options))
56
80
  @blueprints_interface.setopts(options)
57
81
  if options[:dry_run]
@@ -97,32 +121,39 @@ class Morpheus::Cli::BlueprintsCommand
97
121
  def get(args)
98
122
  options = {}
99
123
  optparse = Morpheus::Cli::OptionParser.new do |opts|
100
- opts.banner = subcommand_usage("[id]")
124
+ opts.banner = subcommand_usage("[blueprint]")
101
125
  opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
102
126
  options[:show_config] = true
103
127
  end
104
128
  build_common_options(opts, options, [:json, :yaml, :csv, :fields, :outfile, :dry_run, :remote])
105
129
  opts.footer = "Get details about a blueprint.\n" +
106
- "[id] is required. This is the name or id of a blueprint."
130
+ "[blueprint] is required. This is the name or id of a blueprint. Supports 1-N [instance] arguments."
107
131
  end
108
132
  optparse.parse!(args)
109
133
  if args.count < 1
110
- puts optparse
111
- exit 1
134
+ raise_command_error "wrong number of arguments, expected 1-N and got (#{args.count}) #{args.join(', ')}\n#{optparse}"
112
135
  end
136
+ connect(options)
137
+ id_list = parse_id_list(args)
138
+ return run_command_for_each_arg(id_list) do |arg|
139
+ _get(arg, options)
140
+ end
141
+ end
142
+
143
+ def _get(arg, options)
113
144
  connect(options)
114
145
  begin
115
146
  if options[:dry_run]
116
147
  @blueprints_interface.setopts(options)
117
148
  if args[0].to_s =~ /\A\d{1,}\Z/
118
- print_dry_run @blueprints_interface.dry.get(args[0].to_i)
149
+ print_dry_run @blueprints_interface.dry.get(arg.to_i)
119
150
  else
120
- print_dry_run @blueprints_interface.dry.list({name:args[0]})
151
+ print_dry_run @blueprints_interface.dry.list({name:arg})
121
152
  end
122
153
  return
123
154
  end
124
155
  @blueprints_interface.setopts(options)
125
- blueprint = find_blueprint_by_name_or_id(args[0])
156
+ blueprint = find_blueprint_by_name_or_id(arg)
126
157
  exit 1 if blueprint.nil?
127
158
 
128
159
  json_response = {'blueprint' => blueprint} # skip redundant request
@@ -183,7 +214,7 @@ class Morpheus::Cli::BlueprintsCommand
183
214
  opts.banner = subcommand_usage("[name] [options]")
184
215
  build_option_type_options(opts, options, add_blueprint_option_types(false))
185
216
  opts.on('-t', '--type TYPE', String, "Blueprint Type. Default is morpheus.") do |val|
186
- options[:blueprint_type] = val.to_s
217
+ options[:blueprint_type] = parse_blueprint_type(val.to_s)
187
218
  end
188
219
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
189
220
  opts.footer = "Create a new blueprint.\n" +
@@ -244,7 +275,7 @@ class Morpheus::Cli::BlueprintsCommand
244
275
  end
245
276
  else
246
277
  # print details
247
- get([blueprint['id']])
278
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
248
279
  end
249
280
  end
250
281
  end
@@ -256,45 +287,57 @@ class Morpheus::Cli::BlueprintsCommand
256
287
  end
257
288
 
258
289
  def update(args)
259
- options = {}
290
+ params, payload, options = {}, {}, {}
260
291
  optparse = Morpheus::Cli::OptionParser.new do |opts|
261
- opts.banner = subcommand_usage("[id] [options]")
292
+ opts.banner = subcommand_usage("[blueprint] [options]")
262
293
  build_option_type_options(opts, options, update_blueprint_option_types(false))
294
+ opts.on( '--owner USER', "Owner Username or ID" ) do |val|
295
+ options[:owner] = val == 'null' ? nil : val
296
+ end
263
297
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
264
298
  opts.footer = "Update a blueprint.\n" +
265
- "[id] is required. This is the name or id of a blueprint.\n" +
266
- "[options] Available options include --name and --description. This will update only the specified values.\n" +
267
- "[--config] or [--config-file] can be used to replace the entire blueprint."
299
+ "[blueprint] is required. This is the name or id of a blueprint."
268
300
  end
269
301
  optparse.parse!(args)
270
-
271
- if args.count < 1
272
- puts optparse
273
- exit 1
302
+ if args.count != 1
303
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(', ')}\n#{optparse}"
274
304
  end
275
-
276
305
  connect(options)
277
-
278
306
  begin
279
-
280
307
  blueprint = find_blueprint_by_name_or_id(args[0])
281
308
  return 1 if blueprint.nil?
282
-
283
309
  payload = {}
284
310
  passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
285
311
  if options[:payload]
286
312
  payload = options[:payload]
287
- payload.deep_merge!(passed_options) unless passed_options.empty?
313
+ payload.deep_merge!(parse_passed_options(options))
288
314
  else
289
315
  # no prompting, just merge passed options
290
316
  payload = blueprint["config"]
291
- payload.deep_merge!(passed_options) unless passed_options.empty?
292
-
293
- if passed_options.empty?
294
- print_red_alert "Specify at least one option to update"
295
- puts optparse
296
- return 1
317
+ end
318
+ payload.deep_merge!(parse_passed_options(options))
319
+ # Owner
320
+ if options.key?(:owner)
321
+ owner_id = options[:owner]
322
+ if owner_id.to_s.empty?
323
+ # allow clearing
324
+ owner_id = nil
325
+ elsif options[:owner]
326
+ if owner_id.to_s =~ /\A\d{1,}\Z/
327
+ # allow id without lookup
328
+ else
329
+ user = find_available_user_option(owner_id)
330
+ return 1 if user.nil?
331
+ owner_id = user['id']
332
+ end
297
333
  end
334
+ # payload['blueprint'] ||= {}
335
+ # payload['blueprint']['ownerId'] = owner_id
336
+ payload['ownerId'] = owner_id
337
+ end
338
+ if payload.empty?
339
+ # this wont happen because its sending back the current config
340
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
298
341
  end
299
342
  @blueprints_interface.setopts(options)
300
343
  if options[:dry_run]
@@ -311,8 +354,7 @@ class Morpheus::Cli::BlueprintsCommand
311
354
  unless options[:quiet]
312
355
  blueprint = json_response['blueprint']
313
356
  print_green_success "Updated blueprint #{blueprint['name']}"
314
- details_options = [blueprint['id']]
315
- get(details_options)
357
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
316
358
  end
317
359
  end
318
360
 
@@ -323,14 +365,14 @@ class Morpheus::Cli::BlueprintsCommand
323
365
  end
324
366
 
325
367
  def update_permissions(args)
368
+ params, payload, options = {}, {}, {}
326
369
  group_access_all = nil
327
370
  group_access_list = nil
328
371
  group_defaults_list = nil
329
- options = {}
330
372
  optparse = Morpheus::Cli::OptionParser.new do |opts|
331
- opts.banner = subcommand_usage("[id] [options]")
373
+ opts.banner = subcommand_usage("[blueprint] [options]")
332
374
  opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
333
- group_access_all = val.to_s == 'on' || val.to_s == 'true' || val == '' || val.nil?
375
+ group_access_all = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
334
376
  end
335
377
  opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
336
378
  if list.size == 1 && list[0] == 'null' # hacky way to clear it
@@ -342,10 +384,13 @@ class Morpheus::Cli::BlueprintsCommand
342
384
  opts.on('--visibility [private|public]', String, "Visibility") do |val|
343
385
  options['visibility'] = val
344
386
  end
387
+ opts.on( '--owner USER', "Owner Username or ID" ) do |val|
388
+ options[:owner] = val == 'null' ? nil : val
389
+ end
345
390
  build_option_type_options(opts, options, update_blueprint_option_types(false))
346
391
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
347
392
  opts.footer = "Update a blueprint permissions.\n" +
348
- "[id] is required. This is the name or id of a blueprint."
393
+ "[blueprint] is required. This is the name or id of a blueprint."
349
394
  end
350
395
  optparse.parse!(args)
351
396
 
@@ -357,48 +402,54 @@ class Morpheus::Cli::BlueprintsCommand
357
402
  connect(options)
358
403
 
359
404
  begin
360
-
361
405
  blueprint = find_blueprint_by_name_or_id(args[0])
362
406
  return 1 if blueprint.nil?
363
-
364
- payload = nil
365
407
  if options[:payload]
366
408
  payload = options[:payload]
367
- else
368
- payload = {
369
- 'blueprint' => {
370
- }
371
- }
372
-
373
- # allow arbitrary -O options
374
- payload['blueprint'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
375
-
376
- # Group Access
377
- if group_access_all != nil
378
- payload['resourcePermissions'] ||= {}
379
- payload['resourcePermissions']['all'] = group_access_all
380
- end
381
- if group_access_list != nil
382
- payload['resourcePermissions'] ||= {}
383
- payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
384
- site = {"id" => site_id.to_i}
385
- if group_defaults_list && group_defaults_list.include?(site_id)
386
- site["default"] = true
387
- end
388
- site
409
+ end
410
+ payload['blueprint'] ||= {}
411
+ payload.deep_merge!(parse_passed_options(options))
412
+ # Group Access
413
+ if group_access_all != nil
414
+ payload['resourcePermissions'] ||= {}
415
+ payload['resourcePermissions']['all'] = group_access_all
416
+ end
417
+ if group_access_list != nil
418
+ payload['resourcePermissions'] ||= {}
419
+ payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
420
+ site = {"id" => site_id.to_i}
421
+ if group_defaults_list && group_defaults_list.include?(site_id)
422
+ site["default"] = true
389
423
  end
424
+ site
390
425
  end
391
-
392
- # Tenants
393
- # if options['tenants']
394
- # payload['tenantPermissions'] = {}
395
- # payload['tenantPermissions']['accounts'] = options['tenants']
396
- # end
397
-
398
- # Visibility
399
- if options['visibility'] != nil
400
- payload['blueprint']['visibility'] = options['visibility']
426
+ end
427
+ # Visibility
428
+ if options['visibility'] != nil
429
+ payload['blueprint']['visibility'] = options['visibility'].to_s.downcase
430
+ end
431
+ # Owner
432
+ if options.key?(:owner)
433
+ owner_id = options[:owner]
434
+ if owner_id.to_s.empty?
435
+ # allow clearing
436
+ owner_id = nil
437
+ elsif options[:owner]
438
+ if owner_id.to_s =~ /\A\d{1,}\Z/
439
+ # allow id without lookup
440
+ else
441
+ user = find_available_user_option(owner_id)
442
+ return 1 if user.nil?
443
+ owner_id = user['id']
444
+ end
401
445
  end
446
+ payload['blueprint']['ownerId'] = owner_id
447
+ end
448
+ if payload['blueprint'] && payload['blueprint'].empty?
449
+ payload.delete('blueprint')
450
+ end
451
+ if payload.empty?
452
+ raise_command_error "Specify at least one option to update.\n#{optparse}" if payload.empty?
402
453
  end
403
454
  @blueprints_interface.setopts(options)
404
455
  if options[:dry_run]
@@ -414,8 +465,7 @@ class Morpheus::Cli::BlueprintsCommand
414
465
  unless options[:quiet]
415
466
  blueprint = json_response['blueprint']
416
467
  print_green_success "Updated permissions for blueprint #{blueprint['name']}"
417
- details_options = [blueprint['id']]
418
- get(details_options)
468
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
419
469
  end
420
470
  end
421
471
  return 0
@@ -430,10 +480,10 @@ class Morpheus::Cli::BlueprintsCommand
430
480
  image_type_name = nil
431
481
  options = {}
432
482
  optparse = Morpheus::Cli::OptionParser.new do |opts|
433
- opts.banner = subcommand_usage("[id] [file]")
483
+ opts.banner = subcommand_usage("[blueprint] [file]")
434
484
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
435
485
  opts.footer = "Upload an image file to be used as the icon for a blueprint.\n" +
436
- "[id] is required. This is the name or id of a blueprint.\n" +
486
+ "[blueprint] is required. This is the name or id of a blueprint.\n" +
437
487
  "[file] is required. This is the local path of a file to upload [png|jpg|svg]."
438
488
  end
439
489
  optparse.parse!(args)
@@ -473,7 +523,7 @@ class Morpheus::Cli::BlueprintsCommand
473
523
  blueprint = json_response['blueprint']
474
524
  new_image_url = blueprint['image']
475
525
  print cyan, "Updated blueprint #{blueprint['name']} image.\nNew image url is: #{new_image_url}", reset, "\n\n"
476
- get([blueprint['id']])
526
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
477
527
  end
478
528
  return 0
479
529
  rescue RestClient::Exception => e
@@ -485,10 +535,10 @@ class Morpheus::Cli::BlueprintsCommand
485
535
  def duplicate(args)
486
536
  options = {}
487
537
  optparse = Morpheus::Cli::OptionParser.new do |opts|
488
- opts.banner = subcommand_usage("[id] [new name]")
538
+ opts.banner = subcommand_usage("[blueprint] [new name]")
489
539
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
490
540
  opts.footer = "Duplicate a blueprint." + "\n" +
491
- "[id] is required. This is the name or id of a blueprint." + "\n" +
541
+ "[blueprint] is required. This is the name or id of a blueprint." + "\n" +
492
542
  "[new name] is required. This is the name for the clone."
493
543
  end
494
544
  optparse.parse!(args)
@@ -523,7 +573,7 @@ class Morpheus::Cli::BlueprintsCommand
523
573
  else
524
574
  new_blueprint = json_response["blueprint"] || {}
525
575
  print_green_success "Created duplicate blueprint '#{new_blueprint['name']}'"
526
- #get([new_blueprint["id"]])
576
+ #get([new_blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
527
577
  end
528
578
 
529
579
  rescue RestClient::Exception => e
@@ -535,10 +585,10 @@ class Morpheus::Cli::BlueprintsCommand
535
585
  def remove(args)
536
586
  options = {}
537
587
  optparse = Morpheus::Cli::OptionParser.new do |opts|
538
- opts.banner = subcommand_usage("[id]")
588
+ opts.banner = subcommand_usage("[blueprint]")
539
589
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
540
590
  opts.footer = "Delete a blueprint." + "\n" +
541
- "[id] is required. This is the name or id of a blueprint."
591
+ "[blueprint] is required. This is the name or id of a blueprint."
542
592
  end
543
593
  optparse.parse!(args)
544
594
 
@@ -577,7 +627,7 @@ class Morpheus::Cli::BlueprintsCommand
577
627
  def add_instance(args)
578
628
  options = {}
579
629
  optparse = Morpheus::Cli::OptionParser.new do |opts|
580
- opts.banner = subcommand_usage("[id] [tier] [instance-type]")
630
+ opts.banner = subcommand_usage("[blueprint] [tier] [instance-type]")
581
631
  # opts.on( '-g', '--group GROUP', "Group" ) do |val|
582
632
  # options[:group] = val
583
633
  # end
@@ -589,7 +639,7 @@ class Morpheus::Cli::BlueprintsCommand
589
639
  end
590
640
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
591
641
  opts.footer = "Update a blueprint, adding an instance." + "\n" +
592
- "[id] is required. This is the name or id of a blueprint." + "\n" +
642
+ "[blueprint] is required. This is the name or id of a blueprint." + "\n" +
593
643
  "[tier] is required and will be prompted for. This is the name of the tier." + "\n" +
594
644
  "[instance-type] is required and will be prompted for. This is the type of instance."
595
645
  end
@@ -686,7 +736,7 @@ class Morpheus::Cli::BlueprintsCommand
686
736
  end
687
737
  else
688
738
  # print details
689
- get([blueprint['name']])
739
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
690
740
  end
691
741
  end
692
742
  end
@@ -702,7 +752,7 @@ class Morpheus::Cli::BlueprintsCommand
702
752
  def add_instance_config(args)
703
753
  options = {}
704
754
  optparse = Morpheus::Cli::OptionParser.new do |opts|
705
- opts.banner = subcommand_usage("[id] [tier] [instance]")
755
+ opts.banner = subcommand_usage("[blueprint] [tier] [instance]")
706
756
  opts.on( '-g', '--group GROUP', "Group" ) do |val|
707
757
  options[:group] = val
708
758
  end
@@ -717,7 +767,7 @@ class Morpheus::Cli::BlueprintsCommand
717
767
  end
718
768
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
719
769
  opts.footer = "Update a blueprint, adding an instance config." + "\n" +
720
- "[id] is required. This is the name or id of a blueprint." + "\n" +
770
+ "[blueprint] is required. This is the name or id of a blueprint." + "\n" +
721
771
  "[tier] is required. This is the name of the tier." + "\n" +
722
772
  "[instance] is required. This is the type of instance."
723
773
  end
@@ -802,7 +852,7 @@ class Morpheus::Cli::BlueprintsCommand
802
852
 
803
853
  options[:name_required] = false
804
854
  options[:instance_type_code] = instance_config['instance']['type'] #instance_type["code"]
805
-
855
+ options[:for_app] = true
806
856
  #options[:options].deep_merge!(specific_config)
807
857
  # this provisioning helper method handles all (most) of the parsing and prompting
808
858
  instance_config_payload = prompt_new_instance(options)
@@ -850,7 +900,7 @@ class Morpheus::Cli::BlueprintsCommand
850
900
  puts JSON.pretty_generate(json_response)
851
901
  else
852
902
  print_green_success "Instance added to blueprint #{blueprint['name']}"
853
- get([blueprint['name']])
903
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
854
904
  end
855
905
  return 0
856
906
 
@@ -865,7 +915,7 @@ class Morpheus::Cli::BlueprintsCommand
865
915
  instance_index = nil
866
916
  options = {}
867
917
  optparse = Morpheus::Cli::OptionParser.new do |opts|
868
- opts.banner = subcommand_usage("[id] [tier] [instance] -g GROUP -c CLOUD")
918
+ opts.banner = subcommand_usage("[blueprint] [tier] [instance] -g GROUP -c CLOUD")
869
919
  opts.on( '-g', '--group GROUP', "Group" ) do |val|
870
920
  options[:group] = val
871
921
  end
@@ -880,7 +930,7 @@ class Morpheus::Cli::BlueprintsCommand
880
930
  # end
881
931
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
882
932
  opts.footer = "Update a blueprint, removing a specified instance config." + "\n" +
883
- "[id] is required. This is the name or id of a blueprint." + "\n" +
933
+ "[blueprint] is required. This is the name or id of a blueprint." + "\n" +
884
934
  "[tier] is required. This is the name of the tier." + "\n" +
885
935
  "[instance] is required. This is the instance identifier, which may be the type, the name, or the index starting with 0." + "\n" +
886
936
  "The config scope is specified with the -g GROUP, -c CLOUD and -e ENV. The -g and -c options are required."
@@ -1033,7 +1083,7 @@ class Morpheus::Cli::BlueprintsCommand
1033
1083
  puts JSON.pretty_generate(json_response)
1034
1084
  else
1035
1085
  print_green_success "Removed instance from blueprint."
1036
- get([blueprint['id']])
1086
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1037
1087
  end
1038
1088
  return 0
1039
1089
 
@@ -1057,13 +1107,13 @@ class Morpheus::Cli::BlueprintsCommand
1057
1107
  instance_index = nil
1058
1108
  options = {}
1059
1109
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1060
- opts.banner = subcommand_usage("[id] [tier] [instance]")
1110
+ opts.banner = subcommand_usage("[blueprint] [tier] [instance]")
1061
1111
  # opts.on('--index NUMBER', Number, "Identify Instance by index within tier, starting with 0." ) do |val|
1062
1112
  # instance_index = val.to_i
1063
1113
  # end
1064
1114
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
1065
1115
  opts.footer = "Update a blueprint, removing a specified instance." + "\n" +
1066
- "[id] is required. This is the name or id of a blueprint." + "\n" +
1116
+ "[blueprint] is required. This is the name or id of a blueprint." + "\n" +
1067
1117
  "[tier] is required. This is the name of the tier." + "\n" +
1068
1118
  "[instance] is required. This is the instance identifier, which may be the type, the name, or the index starting with 0."
1069
1119
  end
@@ -1160,7 +1210,7 @@ class Morpheus::Cli::BlueprintsCommand
1160
1210
  puts JSON.pretty_generate(json_response)
1161
1211
  else
1162
1212
  print_green_success "Removed instance from blueprint."
1163
- get([blueprint['id']])
1213
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1164
1214
  end
1165
1215
  return 0
1166
1216
 
@@ -1176,7 +1226,7 @@ class Morpheus::Cli::BlueprintsCommand
1176
1226
  linked_tiers = nil
1177
1227
  tier_index = nil
1178
1228
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1179
- opts.banner = subcommand_usage("[id] [tier]")
1229
+ opts.banner = subcommand_usage("[blueprint] [tier]")
1180
1230
  opts.on('--name VALUE', String, "Tier Name") do |val|
1181
1231
  options[:name] = val
1182
1232
  end
@@ -1195,7 +1245,7 @@ class Morpheus::Cli::BlueprintsCommand
1195
1245
 
1196
1246
  if args.count < 1
1197
1247
  print_error Morpheus::Terminal.angry_prompt
1198
- puts_error "#{command_name} add-tier requires argument: [id]\n#{optparse}"
1248
+ puts_error "#{command_name} add-tier requires argument: [blueprint]\n#{optparse}"
1199
1249
  # puts optparse
1200
1250
  return 1
1201
1251
  end
@@ -1299,7 +1349,7 @@ class Morpheus::Cli::BlueprintsCommand
1299
1349
  end
1300
1350
  end
1301
1351
  # print details
1302
- get([blueprint['name']])
1352
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1303
1353
  end
1304
1354
  return 0
1305
1355
  rescue RestClient::Exception => e
@@ -1315,7 +1365,7 @@ class Morpheus::Cli::BlueprintsCommand
1315
1365
  linked_tiers = nil
1316
1366
  tier_index = nil
1317
1367
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1318
- opts.banner = subcommand_usage("[id] [tier]")
1368
+ opts.banner = subcommand_usage("[blueprint] [tier]")
1319
1369
  opts.on('--name VALUE', String, "Tier Name") do |val|
1320
1370
  new_tier_name = val
1321
1371
  end
@@ -1446,7 +1496,7 @@ class Morpheus::Cli::BlueprintsCommand
1446
1496
  puts JSON.pretty_generate(json_response)
1447
1497
  elsif !options[:quiet]
1448
1498
  print_green_success "Updated tier #{tier_name}"
1449
- get([blueprint['id']])
1499
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1450
1500
  end
1451
1501
  return 0
1452
1502
  rescue RestClient::Exception => e
@@ -1458,7 +1508,7 @@ class Morpheus::Cli::BlueprintsCommand
1458
1508
  def remove_tier(args)
1459
1509
  options = {}
1460
1510
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1461
- opts.banner = subcommand_usage("[id] [tier]")
1511
+ opts.banner = subcommand_usage("[blueprint] [tier]")
1462
1512
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
1463
1513
  end
1464
1514
  optparse.parse!(args)
@@ -1513,7 +1563,7 @@ class Morpheus::Cli::BlueprintsCommand
1513
1563
  print "\n"
1514
1564
  else
1515
1565
  print_green_success "Removed tier #{tier_name}"
1516
- get([blueprint['name']])
1566
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1517
1567
  end
1518
1568
 
1519
1569
  rescue RestClient::Exception => e
@@ -1525,7 +1575,7 @@ class Morpheus::Cli::BlueprintsCommand
1525
1575
  def connect_tiers(args)
1526
1576
  options = {}
1527
1577
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1528
- opts.banner = subcommand_usage("[id] [Tier1] [Tier2]")
1578
+ opts.banner = subcommand_usage("[blueprint] [Tier1] [Tier2]")
1529
1579
  build_common_options(opts, options, [:json, :dry_run, :remote])
1530
1580
  end
1531
1581
  optparse.parse!(args)
@@ -1611,7 +1661,7 @@ class Morpheus::Cli::BlueprintsCommand
1611
1661
  print "\n"
1612
1662
  else
1613
1663
  print_green_success "Connected 2 tiers for blueprint #{blueprint['name']}"
1614
- get([blueprint['name']])
1664
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1615
1665
  end
1616
1666
 
1617
1667
  rescue RestClient::Exception => e
@@ -1623,7 +1673,7 @@ class Morpheus::Cli::BlueprintsCommand
1623
1673
  def disconnect_tiers(args)
1624
1674
  options = {}
1625
1675
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1626
- opts.banner = subcommand_usage("[id] [Tier1] [Tier2]")
1676
+ opts.banner = subcommand_usage("[blueprint] [Tier1] [Tier2]")
1627
1677
  build_common_options(opts, options, [:json, :dry_run, :remote])
1628
1678
  end
1629
1679
  optparse.parse!(args)
@@ -1701,7 +1751,7 @@ class Morpheus::Cli::BlueprintsCommand
1701
1751
  print "\n"
1702
1752
  else
1703
1753
  print_green_success "Connected 2 tiers for blueprint #{blueprint['name']}"
1704
- get([blueprint['name']])
1754
+ get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
1705
1755
  end
1706
1756
 
1707
1757
  rescue RestClient::Exception => e
@@ -1915,10 +1965,13 @@ class Morpheus::Cli::BlueprintsCommand
1915
1965
  {
1916
1966
  id: blueprint['id'],
1917
1967
  name: blueprint['name'],
1968
+ type: blueprint['type'].kind_of?(Hash) ? blueprint['type']['name'] : format_blueprint_type(blueprint['type']),
1918
1969
  description: blueprint['description'],
1919
- type: blueprint['type'].kind_of?(Hash) ? blueprint['type']['name'] : blueprint['type'],
1920
1970
  category: blueprint['category'],
1921
- tiers_summary: format_blueprint_tiers_summary(blueprint)
1971
+ visibility: blueprint['visibility'].to_s.capitalize,
1972
+ owner: blueprint['owner'] ? blueprint['owner']['username'] : '',
1973
+ tenant: blueprint['tenant'] ? blueprint['tenant']['name'] : '',
1974
+ tiers_summary: format_blueprint_tiers_summary(blueprint),
1922
1975
  }
1923
1976
  end
1924
1977
 
@@ -1930,10 +1983,13 @@ class Morpheus::Cli::BlueprintsCommand
1930
1983
  columns = [
1931
1984
  :id,
1932
1985
  :name,
1933
- :description,
1934
1986
  :type,
1987
+ :description,
1935
1988
  :category,
1936
- {:tiers_summary => {:display_name => "TIERS", :max_width => tiers_col_width} }
1989
+ :owner,
1990
+ :tenant,
1991
+ :visibility,
1992
+ {:tiers_summary => {:display_name => "TIERS", :max_width => tiers_col_width} },
1937
1993
  ]
1938
1994
  if opts[:include_fields]
1939
1995
  columns = opts[:include_fields]
@@ -2006,17 +2062,41 @@ class Morpheus::Cli::BlueprintsCommand
2006
2062
  description_cols = {
2007
2063
  "ID" => 'id',
2008
2064
  "Name" => 'name',
2009
- "Description" => 'description',
2010
2065
  "Type" => lambda {|it| it['type'].kind_of?(Hash) ? it['type']['name'] : it['type'] },
2066
+ "Description" => 'description',
2011
2067
  "Category" => 'category',
2012
2068
  "Image" => lambda {|it| it['config'] ? (it['config']['image'] == '/assets/apps/template.png' ? '(default)' : it['config']['image']) : '' },
2069
+ "Owner" => lambda {|it| it['owner'] ? it['owner']['username'] : '' },
2070
+ "Tenant" => lambda {|it| it['tenant'] ? it['tenant']['name'] : '' },
2013
2071
  "Visibility" => 'visibility',
2072
+ "Group Access" => lambda {|it|
2073
+ group_access_str = ""
2074
+ begin
2075
+ rows = []
2076
+ if blueprint['resourcePermission']
2077
+ if blueprint['resourcePermission']['allSites'] || blueprint['resourcePermission']['all']
2078
+ rows.push({"name" => 'All'})
2079
+ end
2080
+ if blueprint['resourcePermission']['sites']
2081
+ blueprint['resourcePermission']['sites'].each do |site|
2082
+ rows.push(site)
2083
+ end
2084
+ end
2085
+ else
2086
+ # rows.push({"name" => 'All'})
2087
+ end
2088
+ group_access_str = rows.collect {|it| it['default'] ? "#{it['name']} (default)" : "#{it['name']}"}.join(',')
2089
+ rescue => ex
2090
+ Morpheus::Logging::DarkPrinter.puts "Error parsing group access: #{ex}" if Morpheus::Logging.debug?
2091
+ end
2092
+ group_access_str
2093
+ },
2014
2094
  "Tiers" => lambda {|it|
2015
2095
  tiers = []
2016
2096
  if blueprint["config"]["tiers"].is_a?(Hash)
2017
2097
  tiers = blueprint["config"]["tiers"].keys
2018
2098
  end
2019
- "#{tiers.collect {|it| it.is_a?(Hash) ? it['name'] : it }.join(',')}"
2099
+ "(#{(tiers || []).size()}) #{tiers.collect {|it| it.is_a?(Hash) ? it['name'] : it }.join(', ')}"
2020
2100
  },
2021
2101
  "Instances" => lambda {|it|
2022
2102
  instances = []
@@ -2035,33 +2115,11 @@ class Morpheus::Cli::BlueprintsCommand
2035
2115
  end
2036
2116
  end
2037
2117
  #"(#{instances.count})"
2038
- "(#{instances.count}) #{instances.collect {|it| it['instance'] ? it['instance']['type'] : (it['type'] || it['name']) }.join(',')}"
2118
+ "(#{instances.count}) #{instances.collect {|it| it['instance'] ? it['instance']['type'] : (it['type'] || it['name']) }.join(', ')}"
2039
2119
  },
2040
2120
  # "Containers" => lambda {|it|
2041
2121
  # i wish
2042
2122
  # },
2043
- "Group Access" => lambda {|it|
2044
- group_access_str = ""
2045
- begin
2046
- rows = []
2047
- if blueprint['resourcePermission']
2048
- if blueprint['resourcePermission']['allSites'] || blueprint['resourcePermission']['all']
2049
- rows.push({"name" => 'All'})
2050
- end
2051
- if blueprint['resourcePermission']['sites']
2052
- blueprint['resourcePermission']['sites'].each do |site|
2053
- rows.push(site)
2054
- end
2055
- end
2056
- else
2057
- # rows.push({"name" => 'All'})
2058
- end
2059
- group_access_str = rows.collect {|it| it['default'] ? "#{it['name']} (default)" : "#{it['name']}"}.join(',')
2060
- rescue => ex
2061
- Morpheus::Logging::DarkPrinter.puts "Error parsing group access: #{ex}" if Morpheus::Logging.debug?
2062
- end
2063
- group_access_str
2064
- }
2065
2123
  }
2066
2124
 
2067
2125
  print_description_list(description_cols, blueprint)
@@ -2145,7 +2203,7 @@ class Morpheus::Cli::BlueprintsCommand
2145
2203
  end
2146
2204
 
2147
2205
  else
2148
- print white," Tier is empty, use `blueprints add-instance \"#{blueprint['name']}\" \"#{tier_name}\"`",reset,"\n"
2206
+ #print cyan," Tier is empty, use `blueprints add-instance \"#{blueprint['name']}\" \"#{tier_name}\"`",reset,"\n"
2149
2207
  end
2150
2208
  # print "\n"
2151
2209
 
@@ -2153,8 +2211,9 @@ class Morpheus::Cli::BlueprintsCommand
2153
2211
  # print "\n"
2154
2212
 
2155
2213
  else
2156
- print white,"\nTemplate is empty, use `blueprints add-tier \"#{blueprint['name']}\"`",reset,"\n"
2214
+ #print white,"\nTemplate is empty, use `blueprints add-tier \"#{blueprint['name']}\"`",reset,"\n"
2157
2215
  end
2216
+ print reset,"\n"
2158
2217
  end
2159
2218
 
2160
2219
  # this parses the environments => groups => clouds tree structure