morpheus-cli 4.1.8 → 4.1.9

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +24 -0
  4. data/lib/morpheus/api/{old_cypher_interface.rb → budgets_interface.rb} +10 -11
  5. data/lib/morpheus/api/cloud_datastores_interface.rb +7 -0
  6. data/lib/morpheus/api/cloud_resource_pools_interface.rb +2 -2
  7. data/lib/morpheus/api/cypher_interface.rb +18 -12
  8. data/lib/morpheus/api/health_interface.rb +72 -0
  9. data/lib/morpheus/api/instances_interface.rb +1 -1
  10. data/lib/morpheus/api/library_instance_types_interface.rb +7 -0
  11. data/lib/morpheus/api/log_settings_interface.rb +6 -0
  12. data/lib/morpheus/api/network_security_servers_interface.rb +30 -0
  13. data/lib/morpheus/api/price_sets_interface.rb +42 -0
  14. data/lib/morpheus/api/prices_interface.rb +68 -0
  15. data/lib/morpheus/api/provisioning_settings_interface.rb +29 -0
  16. data/lib/morpheus/api/servers_interface.rb +1 -1
  17. data/lib/morpheus/api/service_plans_interface.rb +34 -11
  18. data/lib/morpheus/api/task_sets_interface.rb +8 -0
  19. data/lib/morpheus/api/tasks_interface.rb +8 -0
  20. data/lib/morpheus/cli.rb +6 -3
  21. data/lib/morpheus/cli/appliance_settings_command.rb +13 -5
  22. data/lib/morpheus/cli/approvals_command.rb +1 -1
  23. data/lib/morpheus/cli/apps.rb +88 -28
  24. data/lib/morpheus/cli/backup_settings_command.rb +1 -1
  25. data/lib/morpheus/cli/blueprints_command.rb +2 -0
  26. data/lib/morpheus/cli/budgets_command.rb +672 -0
  27. data/lib/morpheus/cli/cli_command.rb +13 -2
  28. data/lib/morpheus/cli/cli_registry.rb +1 -0
  29. data/lib/morpheus/cli/clusters.rb +40 -274
  30. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +114 -66
  31. data/lib/morpheus/cli/commands/standard/coloring_command.rb +12 -0
  32. data/lib/morpheus/cli/commands/standard/curl_command.rb +31 -6
  33. data/lib/morpheus/cli/commands/standard/echo_command.rb +8 -3
  34. data/lib/morpheus/cli/commands/standard/set_prompt_command.rb +1 -1
  35. data/lib/morpheus/cli/containers_command.rb +37 -24
  36. data/lib/morpheus/cli/cypher_command.rb +191 -150
  37. data/lib/morpheus/cli/health_command.rb +903 -0
  38. data/lib/morpheus/cli/hosts.rb +43 -32
  39. data/lib/morpheus/cli/instances.rb +119 -68
  40. data/lib/morpheus/cli/jobs_command.rb +1 -1
  41. data/lib/morpheus/cli/library_instance_types_command.rb +61 -11
  42. data/lib/morpheus/cli/library_option_types_command.rb +2 -2
  43. data/lib/morpheus/cli/log_settings_command.rb +46 -3
  44. data/lib/morpheus/cli/logs_command.rb +24 -17
  45. data/lib/morpheus/cli/mixins/accounts_helper.rb +2 -0
  46. data/lib/morpheus/cli/mixins/logs_helper.rb +73 -19
  47. data/lib/morpheus/cli/mixins/print_helper.rb +29 -1
  48. data/lib/morpheus/cli/mixins/provisioning_helper.rb +554 -96
  49. data/lib/morpheus/cli/mixins/whoami_helper.rb +13 -1
  50. data/lib/morpheus/cli/networks_command.rb +3 -0
  51. data/lib/morpheus/cli/option_types.rb +83 -53
  52. data/lib/morpheus/cli/price_sets_command.rb +543 -0
  53. data/lib/morpheus/cli/prices_command.rb +669 -0
  54. data/lib/morpheus/cli/processes_command.rb +0 -2
  55. data/lib/morpheus/cli/provisioning_settings_command.rb +237 -0
  56. data/lib/morpheus/cli/remote.rb +9 -4
  57. data/lib/morpheus/cli/reports_command.rb +10 -4
  58. data/lib/morpheus/cli/roles.rb +93 -38
  59. data/lib/morpheus/cli/security_groups.rb +10 -0
  60. data/lib/morpheus/cli/service_plans_command.rb +736 -0
  61. data/lib/morpheus/cli/tasks.rb +220 -8
  62. data/lib/morpheus/cli/tenants_command.rb +3 -16
  63. data/lib/morpheus/cli/users.rb +2 -25
  64. data/lib/morpheus/cli/version.rb +1 -1
  65. data/lib/morpheus/cli/whitelabel_settings_command.rb +18 -18
  66. data/lib/morpheus/cli/whoami.rb +28 -10
  67. data/lib/morpheus/cli/workflows.rb +488 -36
  68. data/lib/morpheus/formatters.rb +22 -0
  69. data/morpheus-cli.gemspec +1 -0
  70. metadata +28 -5
  71. data/lib/morpheus/cli/accounts.rb +0 -335
  72. data/lib/morpheus/cli/old_cypher_command.rb +0 -412
@@ -5,6 +5,7 @@ require 'optparse'
5
5
  require 'morpheus/cli/cli_command'
6
6
  require 'morpheus/cli/mixins/accounts_helper'
7
7
  require 'morpheus/cli/mixins/provisioning_helper'
8
+ require 'morpheus/cli/mixins/logs_helper'
8
9
  require 'morpheus/cli/option_types'
9
10
  require 'json'
10
11
 
@@ -12,6 +13,7 @@ class Morpheus::Cli::Hosts
12
13
  include Morpheus::Cli::CliCommand
13
14
  include Morpheus::Cli::AccountsHelper
14
15
  include Morpheus::Cli::ProvisioningHelper
16
+ include Morpheus::Cli::LogsHelper
15
17
  set_command_name :hosts
16
18
  set_command_description "View and manage hosts (servers)."
17
19
  register_subcommands :list, :count, :get, :view, :stats, :add, :update, :remove, :logs, :start, :stop, :resize, :run_workflow, :make_managed, :upgrade_agent
@@ -37,7 +39,7 @@ class Morpheus::Cli::Hosts
37
39
  @server_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).server_types
38
40
  @logs_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).logs
39
41
  @accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
40
- @active_group_id = Morpheus::Cli::Groups.active_group
42
+ @active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
41
43
  @execution_request_interface = @api_client.execution_request
42
44
  @clusters_interface = @api_client.clusters
43
45
  end
@@ -562,8 +564,24 @@ class Morpheus::Cli::Hosts
562
564
 
563
565
  def logs(args)
564
566
  options = {}
567
+ params = {}
565
568
  optparse = Morpheus::Cli::OptionParser.new do |opts|
566
569
  opts.banner = subcommand_usage("[name]")
570
+ opts.on('--start TIMESTAMP','--start TIMESTAMP', "Start timestamp. Default is 30 days ago.") do |val|
571
+ options[:start] = parse_time(val) #.utc.iso8601
572
+ end
573
+ opts.on('--end TIMESTAMP','--end TIMESTAMP', "End timestamp. Default is now.") do |val|
574
+ options[:end] = parse_time(val) #.utc.iso8601
575
+ end
576
+ opts.on('--level VALUE', String, "Log Level. DEBUG,INFO,WARN,ERROR") do |val|
577
+ params['level'] = params['level'] ? [params['level'], val].flatten : val
578
+ end
579
+ opts.on('--table', '--table', "Format ouput as a table.") do
580
+ options[:table] = true
581
+ end
582
+ opts.on('-a', '--all', "Display all details: entire message." ) do
583
+ options[:details] = true
584
+ end
567
585
  build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
568
586
  end
569
587
  optparse.parse!(args)
@@ -574,54 +592,47 @@ class Morpheus::Cli::Hosts
574
592
  connect(options)
575
593
  begin
576
594
  server = find_host_by_name_or_id(args[0])
577
- params = {}
578
595
  params.merge!(parse_list_options(options))
579
- params[:query] = params.delete(:phrase) unless params[:phrase].nil?
580
- params[:order] = params[:direction] unless params[:direction].nil? # old api version expects order instead of direction
596
+ params['query'] = params.delete('phrase') if params['phrase']
597
+ params['order'] = params['direction'] unless params['direction'].nil? # old api version expects order instead of direction
598
+ params['startMs'] = (options[:start].to_i * 1000) if options[:start]
599
+ params['endMs'] = (options[:end].to_i * 1000) if options[:end]
581
600
  @logs_interface.setopts(options)
582
601
  if options[:dry_run]
583
602
  print_dry_run @logs_interface.dry.server_logs([server['id']], params)
584
603
  return
585
604
  end
586
605
  json_response = @logs_interface.server_logs([server['id']], params)
587
- render_result = render_with_format(json_response, options, 'data')
606
+ render_result = json_response['logs'] ? render_with_format(json_response, options, 'logs') : render_with_format(json_response, options, 'data')
588
607
  return 0 if render_result
589
608
 
590
- logs = json_response
591
609
  title = "Host Logs: #{server['name']} (#{server['computeServerType'] ? server['computeServerType']['name'] : 'unmanaged'})"
592
610
  subtitles = parse_list_subtitles(options)
611
+ if options[:start]
612
+ subtitles << "Start: #{options[:start]}".strip
613
+ end
614
+ if options[:end]
615
+ subtitles << "End: #{options[:end]}".strip
616
+ end
593
617
  if params[:query]
594
618
  subtitles << "Search: #{params[:query]}".strip
595
619
  end
596
- # todo: startMs, endMs, sorts insteaad of sort..etc
620
+ # if params['containers']
621
+ # subtitles << "Containers: #{params['containers']}".strip
622
+ # end
623
+ if params['level']
624
+ subtitles << "Level: #{params['level']}"
625
+ end
597
626
  print_h1 title, subtitles, options
598
- if logs['data'].empty?
599
- puts "#{cyan}No logs found.#{reset}"
627
+ logs = json_response['data'] || json_response['logs']
628
+ if logs.empty?
629
+ print "#{cyan}No logs found.#{reset}\n"
600
630
  else
601
- if logs['data'].empty?
602
- puts "#{cyan}No logs found.#{reset}"
603
- else
604
- logs['data'].each do |log_entry|
605
- log_level = ''
606
- case log_entry['level']
607
- when 'INFO'
608
- log_level = "#{blue}#{bold}INFO#{reset}"
609
- when 'DEBUG'
610
- log_level = "#{white}#{bold}DEBUG#{reset}"
611
- when 'WARN'
612
- log_level = "#{yellow}#{bold}WARN#{reset}"
613
- when 'ERROR'
614
- log_level = "#{red}#{bold}ERROR#{reset}"
615
- when 'FATAL'
616
- log_level = "#{red}#{bold}FATAL#{reset}"
617
- end
618
- puts "[#{log_entry['ts']}] #{log_level} - #{log_entry['message'].to_s.strip}"
619
- end
620
- print_results_pagination({'meta'=>{'total'=>json_response['total'],'size'=>json_response['data'].size,'max'=>(json_response['max'] || options[:max]),'offset'=>(json_response['offset'] || options[:offset] || 0)}})
621
- end
622
- print reset, "\n"
623
- return 0
631
+ print format_log_records(logs, options)
632
+ print_results_pagination({'meta'=>{'total'=>(json_response['total']['value'] rescue json_response['total']),'size'=>logs.size,'max'=>(json_response['max'] || options[:max]),'offset'=>(json_response['offset'] || options[:offset] || 0)}})
624
633
  end
634
+ print reset, "\n"
635
+ return 0
625
636
  rescue RestClient::Exception => e
626
637
  print_rest_exception(e, options)
627
638
  exit 1
@@ -6,6 +6,7 @@ require 'morpheus/cli/cli_command'
6
6
  require 'morpheus/cli/mixins/accounts_helper'
7
7
  require 'morpheus/cli/mixins/provisioning_helper'
8
8
  require 'morpheus/cli/mixins/processes_helper'
9
+ require 'morpheus/cli/mixins/logs_helper'
9
10
  require 'morpheus/cli/option_types'
10
11
 
11
12
  class Morpheus::Cli::Instances
@@ -13,6 +14,7 @@ class Morpheus::Cli::Instances
13
14
  include Morpheus::Cli::AccountsHelper
14
15
  include Morpheus::Cli::ProvisioningHelper
15
16
  include Morpheus::Cli::ProcessesHelper
17
+ include Morpheus::Cli::LogsHelper
16
18
  set_command_name :instances
17
19
  set_command_description "View and manage instances."
18
20
  register_subcommands :list, :count, :get, :view, :add, :update, :update_notes, :remove, :logs, :history, {:'history-details' => :history_details}, {:'history-event' => :history_event_details}, :stats, :stop, :start, :restart, :actions, :action, :suspend, :eject, :backup, :backups, :stop_service, :start_service, :restart_service, :resize, :clone, :envs, :setenv, :delenv, :security_groups, :apply_security_groups, :run_workflow, :import_snapshot, :console, :status_check, {:containers => :list_containers}, :scaling, {:'scaling-update' => :scaling_update}
@@ -36,11 +38,13 @@ class Morpheus::Cli::Instances
36
38
  @logs_interface = @api_client.logs
37
39
  @tasks_interface = @api_client.tasks
38
40
  @instance_types_interface = @api_client.instance_types
41
+ @library_layouts_interface = @api_client.library_layouts
39
42
  @clouds_interface = @api_client.clouds
43
+ @clouds_datastores_interface = @api_client.cloud_datastores
40
44
  @servers_interface = @api_client.servers
41
45
  @provision_types_interface = @api_client.provision_types
42
46
  @options_interface = @api_client.options
43
- @active_group_id = Morpheus::Cli::Groups.active_group
47
+ @active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
44
48
  @execution_request_interface = @api_client.execution_request
45
49
  end
46
50
 
@@ -312,6 +316,15 @@ class Morpheus::Cli::Instances
312
316
  opts.on("--layout-size NUMBER", Integer, "Apply a multiply factor of containers/vms within the instance") do |val|
313
317
  options[:layout_size] = val.to_i
314
318
  end
319
+ opts.on( '-l', '--layout LAYOUT', "Layout ID" ) do |val|
320
+ options[:layout] = val
321
+ end
322
+ opts.on( '-p', '--plan PLAN', "Service plan ID") do |val|
323
+ options[:service_plan] = val
324
+ end
325
+ opts.on( '--resource-pool ID', String, "Resource pool ID" ) do |val|
326
+ options[:resource_pool] = val
327
+ end
315
328
  opts.on("--workflow ID", String, "Automation: Workflow ID") do |val|
316
329
  options[:workflow_id] = val
317
330
  end
@@ -359,7 +372,7 @@ class Morpheus::Cli::Instances
359
372
 
360
373
  # use active group by default
361
374
  options[:group] ||= @active_group_id
362
-
375
+ options[:select_datastore] = true
363
376
  options[:name_required] = true
364
377
  begin
365
378
  payload = nil
@@ -1015,9 +1028,42 @@ class Morpheus::Cli::Instances
1015
1028
  options = {}
1016
1029
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1017
1030
  opts.banner = subcommand_usage("[instance]")
1031
+ # opts.on('--hosts HOSTS', String, "Filter logs to specific Host ID(s)") do |val|
1032
+ # params['servers'] = val.to_s.split(",").collect {|it| it.to_s.strip }.select {|it| it }.compact
1033
+ # end
1034
+ # opts.on('--servers HOSTS', String, "alias for --hosts") do |val|
1035
+ # params['servers'] = val.to_s.split(",").collect {|it| it.to_s.strip }.select {|it| it }.compact
1036
+ # end
1037
+ # opts.on('--vms HOSTS', String, "alias for --hosts") do |val|
1038
+ # params['servers'] = val.to_s.split(",").collect {|it| it.to_s.strip }.select {|it| it }.compact
1039
+ # end
1018
1040
  opts.on( '-n', '--node NODE_ID', "Scope logs to specific Container or VM" ) do |node_id|
1019
1041
  options[:node_id] = node_id.to_i
1020
1042
  end
1043
+ # opts.on('--container CONTAINER', String, "Filter logs to specific Container ID(s)") do |val|
1044
+ # params['containers'] = val.to_s.split(",").collect {|it| it.to_s.strip }.select {|it| it }.compact
1045
+ # end
1046
+ # opts.on('--nodes HOST', String, "alias for --containers") do |val|
1047
+ # params['containers'] = val.to_s.split(",").collect {|it| it.to_s.strip }.select {|it| it }.compact
1048
+ # end
1049
+ opts.on('--start TIMESTAMP','--start TIMESTAMP', "Start timestamp. Default is 30 days ago.") do |val|
1050
+ options[:start] = parse_time(val) #.utc.iso8601
1051
+ end
1052
+ opts.on('--end TIMESTAMP','--end TIMESTAMP', "End timestamp. Default is now.") do |val|
1053
+ options[:end] = parse_time(val) #.utc.iso8601
1054
+ end
1055
+ # opts.on('--interval TIME','--interval TIME', "Interval of time to include, in seconds. Default is 30 days ago.") do |val|
1056
+ # options[:interval] = parse_time(val).utc.iso8601
1057
+ # end
1058
+ opts.on('--level VALUE', String, "Log Level. DEBUG,INFO,WARN,ERROR") do |val|
1059
+ params['level'] = params['level'] ? [params['level'], val].flatten : val
1060
+ end
1061
+ opts.on('--table', '--table', "Format ouput as a table.") do
1062
+ options[:table] = true
1063
+ end
1064
+ opts.on('-a', '--all', "Display all details: entire message." ) do
1065
+ options[:details] = true
1066
+ end
1021
1067
  build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
1022
1068
  end
1023
1069
  optparse.parse!(args)
@@ -1029,53 +1075,62 @@ class Morpheus::Cli::Instances
1029
1075
  begin
1030
1076
  instance = find_instance_by_name_or_id(args[0])
1031
1077
  container_ids = instance['containers']
1032
- if options[:node_id] && container_ids.include?(options[:node_id])
1033
- container_ids = [options[:node_id]]
1078
+ if options[:node_id]
1079
+ if container_ids.include?(options[:node_id])
1080
+ container_ids = [options[:node_id]]
1081
+ else
1082
+ print_red_alert "Instance does not include node #{options[:node_id]}"
1083
+ return 1
1084
+ end
1034
1085
  end
1035
1086
  params.merge!(parse_list_options(options))
1036
- params[:query] = params.delete(:phrase) unless params[:phrase].nil?
1087
+ params['query'] = params.delete('phrase') if params['phrase']
1037
1088
  params['order'] = params['direction'] unless params['direction'].nil? # old api version expects order instead of direction
1089
+ params['startMs'] = (options[:start].to_i * 1000) if options[:start]
1090
+ params['endMs'] = (options[:end].to_i * 1000) if options[:end]
1091
+ params['interval'] = options[:interval].to_s if options[:interval]
1038
1092
  @logs_interface.setopts(options)
1039
1093
  if options[:dry_run]
1040
1094
  print_dry_run @logs_interface.dry.container_logs(container_ids, params)
1041
1095
  return
1042
1096
  end
1043
1097
  json_response = @logs_interface.container_logs(container_ids, params)
1044
- render_result = render_with_format(json_response, options, 'data')
1098
+ render_result = json_response['logs'] ? render_with_format(json_response, options, 'logs') : render_with_format(json_response, options, 'data')
1045
1099
  return 0 if render_result
1046
1100
 
1047
- logs = json_response
1048
1101
  title = "Instance Logs: #{instance['name']} (#{instance['instanceType'] ? instance['instanceType']['name'] : ''})"
1049
1102
  subtitles = parse_list_subtitles(options)
1103
+ if options[:start]
1104
+ subtitles << "Start: #{options[:start]}".strip
1105
+ end
1106
+ if options[:end]
1107
+ subtitles << "End: #{options[:end]}".strip
1108
+ end
1109
+ if params[:query]
1110
+ subtitles << "Search: #{params[:query]}".strip
1111
+ end
1112
+ if params['servers']
1113
+ subtitles << "Servers: #{params['servers']}".strip
1114
+ end
1115
+ if params['containers']
1116
+ subtitles << "Containers: #{params['containers']}".strip
1117
+ end
1050
1118
  if params[:query]
1051
1119
  subtitles << "Search: #{params[:query]}".strip
1052
1120
  end
1053
- # todo: startMs, endMs, sorts insteaad of sort..etc
1121
+ if params['level']
1122
+ subtitles << "Level: #{params['level']}"
1123
+ end
1124
+ logs = json_response['data'] || json_response['logs']
1054
1125
  print_h1 title, subtitles, options
1055
- if logs['data'].empty?
1056
- puts "#{cyan}No logs found.#{reset}"
1126
+ if logs.empty?
1127
+ print "#{cyan}No logs found.#{reset}\n"
1057
1128
  else
1058
- logs['data'].each do |log_entry|
1059
- log_level = ''
1060
- case log_entry['level']
1061
- when 'INFO'
1062
- log_level = "#{blue}#{bold}INFO#{reset}"
1063
- when 'DEBUG'
1064
- log_level = "#{white}#{bold}DEBUG#{reset}"
1065
- when 'WARN'
1066
- log_level = "#{yellow}#{bold}WARN#{reset}"
1067
- when 'ERROR'
1068
- log_level = "#{red}#{bold}ERROR#{reset}"
1069
- when 'FATAL'
1070
- log_level = "#{red}#{bold}FATAL#{reset}"
1071
- end
1072
- puts "[#{log_entry['ts']}] #{log_level} - #{log_entry['message'].to_s.strip}"
1073
- end
1074
- print_results_pagination({'meta'=>{'total'=>json_response['total'],'size'=>json_response['data'].size,'max'=>(json_response['max'] || options[:max]),'offset'=>(json_response['offset'] || options[:offset] || 0)}})
1129
+ print format_log_records(logs, options)
1130
+ print_results_pagination({'meta'=>{'total'=>(json_response['total']['value'] rescue json_response['total']),'size'=>logs.size,'max'=>(json_response['max'] || options[:max]),'offset'=>(json_response['offset'] || options[:offset] || 0)}})
1075
1131
  end
1076
1132
  print reset, "\n"
1077
1133
  return 0
1078
-
1079
1134
  rescue RestClient::Exception => e
1080
1135
  print_rest_exception(e, options)
1081
1136
  exit 1
@@ -1086,6 +1141,11 @@ class Morpheus::Cli::Instances
1086
1141
  options = {}
1087
1142
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1088
1143
  opts.banner = subcommand_usage("[instance]")
1144
+ opts.on('-a', '--all', "Display all details: containers|vms, and scaling." ) do
1145
+ options[:details] = true
1146
+ options[:include_containers] = true
1147
+ options[:include_scaling] = true
1148
+ end
1089
1149
  opts.on( nil, '--containers', "Display Instance Containers" ) do
1090
1150
  options[:include_containers] = true
1091
1151
  end
@@ -1556,55 +1616,47 @@ class Morpheus::Cli::Instances
1556
1616
  return 1 if instance.nil?
1557
1617
 
1558
1618
  options[:options] ||= {}
1559
-
1619
+ options[:select_datastore] = true
1620
+ options[:name_required] = true
1621
+
1622
+ # defaults derived from clone
1623
+ options[:default_name] = instance['name'] + '-clone' if instance['name']
1624
+ options[:default_group] = instance['group']['id'] if instance['group']
1625
+ options[:default_cloud] = instance['cloud']['name'] if instance['cloud']
1626
+ options[:default_plan] = instance['plan']['name'] if instance['plan']
1627
+ options[:default_resource_pool] = instance['config']['resourcePoolId'] if instance['config']
1628
+ options[:default_config] = instance['config']
1629
+ options[:default_security_group] = instance['config']['securityGroups'][0]['id'] if instance['config'] && (instance['config']['securityGroups'] || []).count > 0
1630
+
1631
+ # immutable derived from clone
1632
+ options[:instance_type_code] = instance['instanceType']['code'] if instance['instanceType']
1633
+ options[:version] = instance['instanceVersion']
1634
+ options[:layout] = instance['layout']['id'] if instance['layout']
1635
+
1636
+ # volume defaults
1637
+ options[:options]['volumes'] = instance['volumes']
1638
+
1639
+ # network defaults
1640
+ options[:options]['networkInterfaces'] = instance['interfaces']
1641
+
1560
1642
  # use the -g GROUP or active group by default
1561
1643
  #options[:options]['group'] ||= (options[:group] || @active_group_id)
1562
1644
  # support [new-name]
1563
1645
  if args[1]
1564
1646
  options[:options]['name'] = args[1]
1565
1647
  end
1566
- passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
1648
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) || ['networkInterfaces'].include?(k)} : {}
1567
1649
  payload = {}
1568
1650
  if options[:payload]
1569
1651
  payload = options[:payload]
1570
1652
  else
1571
- payload = {
1653
+ new_instance_payload = prompt_new_instance(options)
1572
1654
 
1573
- }
1574
-
1575
- # Name
1576
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for the new instance'}], options[:options], @api_client, options[:params])
1577
- payload['name'] = v_prompt['name'] unless v_prompt['name'].to_s.empty?
1578
-
1579
- # Group
1580
- group = nil
1581
- if options[:group].nil?
1582
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'selectOptions' => get_available_groups(), 'defaultValue' => instance['group']['id']}], options[:options], @api_client, options[:params])
1583
- options[:group] = v_prompt['group'] unless v_prompt['group'].to_s.empty?
1584
- else
1585
- #options[:group] = instance['group']['id']
1586
- end
1587
- if options[:group]
1588
- group = find_group_by_name_or_id_for_provisioning(options[:group])
1589
- return 1 if group.nil?
1590
- payload['group'] = {id: group['id']}
1591
- end
1592
- # Cloud
1593
- cloud = nil
1594
- if group
1595
- if options[:cloud].nil?
1596
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'selectOptions' => get_available_clouds(group['id']), 'defaultValue' => instance['cloud']['id']}], options[:options], @api_client, options[:params])
1597
- options[:cloud] = v_prompt['cloud'] unless v_prompt['cloud'].to_s.empty?
1598
- else
1599
- #options[:cloud] = instance['cloud']['id']
1600
- end
1601
- cloud = find_zone_by_name_or_id(nil, options[:cloud])
1602
- return 1 if cloud.nil?
1603
- if cloud
1604
- payload['cloud'] = {id: cloud['id']}
1605
- end
1606
- end
1607
-
1655
+ # adjust for differences between new and clone payloads
1656
+ payload = new_instance_payload.delete('instance')
1657
+ payload.deep_merge!(new_instance_payload)
1658
+ payload['cloud'] = {'id' => payload.delete('zoneId')}
1659
+ payload['group'] = payload.delete('site')
1608
1660
  end
1609
1661
  unless passed_options.empty?
1610
1662
  passed_options.delete('cloud')
@@ -3215,7 +3267,7 @@ class Morpheus::Cli::Instances
3215
3267
  # end
3216
3268
  params = {}
3217
3269
  params.merge!(parse_list_options(options))
3218
- # params[:query] = params.delete(:phrase) unless params[:phrase].nil?
3270
+ # params['query'] = params.delete('phrase') if params['phrase']
3219
3271
  @instances_interface.setopts(options)
3220
3272
  if options[:dry_run]
3221
3273
  print_dry_run @instances_interface.dry.history(instance['id'], params)
@@ -3348,7 +3400,6 @@ class Morpheus::Cli::Instances
3348
3400
  instance = find_instance_by_name_or_id(args[0])
3349
3401
  params = {}
3350
3402
  params.merge!(parse_list_options(options))
3351
- params[:query] = params.delete(:phrase) unless params[:phrase].nil?
3352
3403
  @instances_interface.setopts(options)
3353
3404
  if options[:dry_run]
3354
3405
  print_dry_run @instances_interface.dry.history_details(instance['id'], process_id, params)
@@ -5,7 +5,7 @@ class Morpheus::Cli::JobsCommand
5
5
  include Morpheus::Cli::AccountsHelper
6
6
 
7
7
  set_command_name :'jobs'
8
- set_command_hidden
8
+
9
9
  register_subcommands :list, :get, :add, :update, :execute, :remove
10
10
  register_subcommands :list_executions, :get_execution, :get_execution_event
11
11
  set_default_subcommand :list
@@ -11,6 +11,7 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
11
11
  set_command_name :'library-instance-types'
12
12
  register_subcommands :list, :get, :add, :update, :remove
13
13
  register_subcommands({:'update-logo' => :update_logo})
14
+ register_subcommands({:'toggle-featured' => :toggle_featured})
14
15
 
15
16
  def initialize()
16
17
  # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -300,12 +301,11 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
300
301
  end
301
302
 
302
303
  print_green_success "Added Instance Type #{params['name']}"
303
-
304
- #list([])
305
-
304
+ _get(json_response['instanceType']['id'], options)
305
+ return 0
306
306
  rescue RestClient::Exception => e
307
307
  print_rest_exception(e, options)
308
- exit 1
308
+ return 1
309
309
  end
310
310
  end
311
311
 
@@ -349,21 +349,71 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
349
349
  @library_instance_types_interface.setopts(options)
350
350
  if options[:dry_run]
351
351
  print_dry_run @library_instance_types_interface.dry.update(instance_type['id'], payload)
352
- return
352
+ return 0
353
353
  end
354
354
 
355
355
  json_response = @library_instance_types_interface.update(instance_type['id'], payload)
356
356
 
357
357
  if options[:json]
358
358
  print JSON.pretty_generate(json_response), "\n"
359
- return
359
+ return 0
360
360
  end
361
361
 
362
362
  print_green_success "Updated Instance Type #{params['name'] || instance_type['name']}"
363
- #list([])
363
+ _get(json_response['instanceType']['id'], options)
364
+ return 0
364
365
  rescue RestClient::Exception => e
365
366
  print_rest_exception(e, options)
366
- exit 1
367
+ return 1
368
+ end
369
+ end
370
+
371
+ def toggle_featured(args)
372
+ options = {}
373
+ params = {}
374
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
375
+ opts.banner = subcommand_usage("[name] [options]")
376
+ # opts.on('--featured [on|off]', String, "Featured flag") do |val|
377
+ # params['featured'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
378
+ # end
379
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
380
+ opts.footer = "Toggle featured flag for an instance type." + "\n" +
381
+ "[name] is required. This is the name or id of a instance type."
382
+ end
383
+ optparse.parse!(args)
384
+ if args.count < 1
385
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
386
+ end
387
+ connect(options)
388
+ begin
389
+ instance_type = find_instance_type_by_name_or_id(args[0])
390
+ return 1 if instance_type.nil?
391
+ payload = nil
392
+ if options[:payload]
393
+ payload = options[:payload]
394
+ else
395
+ instance_type_payload = {}
396
+ instance_type_payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
397
+ payload = {'instanceType' => instance_type_payload}
398
+ end
399
+ @library_instance_types_interface.setopts(options)
400
+ if options[:dry_run]
401
+ print_dry_run @library_instance_types_interface.dry.toggle_featured(instance_type['id'], params, payload)
402
+ return 0
403
+ end
404
+
405
+ json_response = @library_instance_types_interface.toggle_featured(instance_type['id'], params, payload)
406
+
407
+ if options[:json]
408
+ print JSON.pretty_generate(json_response), "\n"
409
+ return 0
410
+ end
411
+ print_green_success "Updated Instance Type #{params['name'] || instance_type['name']}"
412
+ _get(instance_type['id'], options)
413
+ return 0
414
+ rescue RestClient::Exception => e
415
+ print_rest_exception(e, options)
416
+ return 1
367
417
  end
368
418
  end
369
419
 
@@ -408,13 +458,13 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
408
458
  json_response = @library_instance_types_interface.update_logo(instance_type['id'], logo_file)
409
459
  if options[:json]
410
460
  print JSON.pretty_generate(json_response), "\n"
411
- return
461
+ return 0
412
462
  end
413
463
  print_green_success "Updated Instance Type #{instance_type['name']} logo"
414
- #list([])
464
+ _get(instance_type['id'], options)
415
465
  rescue RestClient::Exception => e
416
466
  print_rest_exception(e, options)
417
- exit 1
467
+ return 1
418
468
  end
419
469
  end
420
470