morpheus-cli 3.6.38 → 4.0.0

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.
@@ -14,7 +14,7 @@ class Morpheus::Cli::Hosts
14
14
  include Morpheus::Cli::ProvisioningHelper
15
15
  set_command_name :hosts
16
16
  set_command_description "View and manage hosts (servers)."
17
- register_subcommands :list, :count, :get, :stats, :add, :update, :remove, :logs, :start, :stop, :resize, :run_workflow, {:'make-managed' => :install_agent}, :upgrade_agent
17
+ register_subcommands :list, :count, :get, :view, :stats, :add, :update, :remove, :logs, :start, :stop, :resize, :run_workflow, {:'make-managed' => :install_agent}, :upgrade_agent
18
18
  register_subcommands :'types' => :list_types
19
19
  register_subcommands :exec => :execution_request
20
20
  register_subcommands :wiki, :update_wiki
@@ -359,7 +359,7 @@ class Morpheus::Cli::Hosts
359
359
  options = {}
360
360
  optparse = Morpheus::Cli::OptionParser.new do |opts|
361
361
  opts.banner = subcommand_usage("[name]")
362
- opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is 5 seconds.") do |val|
362
+ opts.on('--refresh [SECONDS]', String, "Refresh until status is provisioned,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
363
363
  options[:refresh_until_status] ||= "provisioned,failed"
364
364
  if !val.to_s.empty?
365
365
  options[:refresh_interval] = val.to_f
@@ -436,19 +436,34 @@ class Morpheus::Cli::Hosts
436
436
  "Power" => lambda {|it| format_server_power_state(it) },
437
437
  }, server)
438
438
 
439
+ if server['statusMessage']
440
+ print_h2 "Status Message", options
441
+ if server['status'] == 'failed'
442
+ print red, server['statusMessage'], reset
443
+ else
444
+ print server['statusMessage']
445
+ end
446
+ print "\n"
447
+ end
448
+ if server['errorMessage']
449
+ print_h2 "Error Message", options
450
+ print red, server['errorMessage'], reset, "\n"
451
+ end
452
+
439
453
  print_h2 "Host Usage", options
440
454
  print_stats_usage(stats)
441
455
  print reset, "\n"
442
456
 
457
+
443
458
  # refresh until a status is reached
444
459
  if options[:refresh_until_status]
445
460
  if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
446
- options[:refresh_interval] = 5
461
+ options[:refresh_interval] = default_refresh_interval
447
462
  end
448
463
  statuses = options[:refresh_until_status].to_s.downcase.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
449
464
  if !statuses.include?(server['status'])
450
465
  print cyan
451
- print cyan, "Refreshing in #{options[:refresh_interval]} seconds"
466
+ print cyan, "Refreshing in #{options[:refresh_interval] > 1 ? options[:refresh_interval].to_i : options[:refresh_interval]} seconds"
452
467
  sleep_with_dots(options[:refresh_interval])
453
468
  print "\n"
454
469
  _get(arg, options)
@@ -599,14 +614,23 @@ class Morpheus::Cli::Hosts
599
614
  opts.on( '-t', '--type TYPE', "Server Type Code" ) do |val|
600
615
  options[:server_type_code] = val
601
616
  end
617
+ opts.on("--security-groups LIST", Integer, "Security Groups, comma sepearated list of security group IDs") do |val|
618
+ options[:security_groups] = val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
619
+ end
620
+ opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
621
+ options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
622
+ end
602
623
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
603
624
  end
604
625
  optparse.parse!(args)
605
626
  connect(options)
606
627
  begin
628
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
607
629
  payload = nil
608
630
  if options[:payload]
609
631
  payload = options[:payload]
632
+ #payload.deep_merge!({'server' => passed_options}) unless passed_options.empty?
633
+ payload.deep_merge!(passed_options) unless passed_options.empty?
610
634
  else
611
635
  # support old format of `hosts add CLOUD NAME`
612
636
  if args[0]
@@ -619,7 +643,6 @@ class Morpheus::Cli::Hosts
619
643
  options[:group] ||= @active_group_id
620
644
 
621
645
  params = {}
622
-
623
646
  # Group
624
647
  group_id = nil
625
648
  group = options[:group] ? find_group_by_name_or_id_for_provisioning(options[:group]) : nil
@@ -683,20 +706,45 @@ class Morpheus::Cli::Hosts
683
706
  plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'plan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this server'}],options[:options])
684
707
  service_plan = service_plans.find {|sp| sp["id"] == plan_prompt['plan'].to_i }
685
708
 
686
- payload['server'] = {
709
+ # uh ok, this actually expects config at root level, sibling of server
710
+ # payload.deep_merge!({'server' => passed_options}) unless passed_options.empty?
711
+ payload.deep_merge!(passed_options) unless passed_options.empty?
712
+ payload.deep_merge!({'server' => {
687
713
  'name' => host_name,
688
714
  'zone' => {'id' => cloud['id']},
689
715
  'computeServerType' => {'id' => server_type['id']},
690
716
  'plan' => {'id' => service_plan["id"]}
691
- }
717
+ }
718
+ })
719
+
720
+ option_type_list = server_type['optionTypes']
721
+ # remove volume options if volumes were configured
722
+ if !payload['volumes'].empty?
723
+ option_type_list = reject_volume_option_types(option_type_list)
724
+ end
725
+ # remove networkId option if networks were configured above
726
+ if !payload['networkInterfaces'].empty?
727
+ option_type_list = reject_networking_option_types(option_type_list)
728
+ end
729
+
730
+ # remove cpu and memory option types, which now come from the plan
731
+ option_type_list = reject_service_plan_option_types(option_type_list)
692
732
 
693
733
  # prompt for resource pool
734
+ pool_id = nil
694
735
  has_zone_pools = server_type["provisionType"] && server_type["provisionType"]["hasZonePools"]
695
736
  if has_zone_pools
696
- resource_pool_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'config', 'fieldName' => 'resourcePool', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'optionSource' => 'zonePools', 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.'}],options[:options],api_client,{groupId: group_id, zoneId: cloud_id, cloudId: cloud_id, planId: service_plan["id"]})
697
- if resource_pool_prompt['config'] && resource_pool_prompt['config']['resourcePool']
698
- payload['config'] ||= {}
699
- payload['config']['resourcePool'] = resource_pool_prompt['config']['resourcePool']
737
+ # pluck out the resourcePoolId option type to prompt for..why the heck is this even needed?
738
+ resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
739
+ option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
740
+ resource_pool_option_type ||= {'fieldContext' => 'config', 'fieldName' => 'resourcePool', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'optionSource' => 'zonePools', 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.'}
741
+ resource_pool_prompt = Morpheus::Cli::OptionTypes.prompt([resource_pool_option_type],options[:options],api_client,{groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, planId: service_plan["id"], serverTypeId: server_type['id']})
742
+ resource_pool_prompt.deep_compact!
743
+ payload.deep_merge!(resource_pool_prompt)
744
+ if resource_pool_option_type['fieldContext'] && resource_pool_prompt[resource_pool_option_type['fieldContext']]
745
+ pool_id = resource_pool_prompt[resource_pool_option_type['fieldContext']][resource_pool_option_type['fieldName']]
746
+ elsif resource_pool_prompt[resource_pool_option_type['fieldName']]
747
+ pool_id = resource_pool_prompt[resource_pool_option_type['fieldName']]
700
748
  end
701
749
  end
702
750
 
@@ -709,7 +757,7 @@ class Morpheus::Cli::Hosts
709
757
  # prompt for network interfaces (if supported)
710
758
  if server_type["provisionType"] && server_type["provisionType"]["id"] && server_type["provisionType"]["hasNetworks"]
711
759
  begin
712
- network_interfaces = prompt_network_interfaces(cloud['id'], server_type["provisionType"]["id"], options)
760
+ network_interfaces = prompt_network_interfaces(cloud['id'], server_type["provisionType"]["id"], pool_id, options)
713
761
  if !network_interfaces.empty?
714
762
  payload['networkInterfaces'] = network_interfaces
715
763
  end
@@ -719,23 +767,36 @@ class Morpheus::Cli::Hosts
719
767
  end
720
768
  end
721
769
 
722
- server_type_option_types = server_type['optionTypes']
723
- # remove volume options if volumes were configured
724
- if !payload['volumes'].empty?
725
- server_type_option_types = reject_volume_option_types(server_type_option_types)
770
+ # Security Groups
771
+ # prompt for multiple security groups
772
+ sg_option_type = option_type_list.find {|opt| ((opt['code'] == 'provisionType.amazon.securityId') || (opt['name'] == 'securityId')) }
773
+ option_type_list = option_type_list.reject {|opt| ((opt['code'] == 'provisionType.amazon.securityId') || (opt['name'] == 'securityId')) }
774
+ # ok.. seed data has changed and serverTypes do not have this optionType anymore...
775
+ if sg_option_type.nil?
776
+ if server_type["provisionType"] && (server_type["provisionType"]["code"] == 'amazon')
777
+ sg_option_type = {'fieldContext' => 'config', 'fieldName' => 'securityId', 'type' => 'select', 'fieldLabel' => 'Security Group', 'optionSource' => 'amazonSecurityGroup', 'required' => true, 'description' => 'Select security group.'}
778
+ end
726
779
  end
727
- # remove networkId option if networks were configured above
728
- if !payload['networkInterfaces'].empty?
729
- server_type_option_types = reject_networking_option_types(server_type_option_types)
780
+ has_security_groups = !!sg_option_type
781
+ if options[:security_groups]
782
+ payload['securityGroups'] = options[:security_groups].collect {|sg_id| {'id' => sg_id} }
783
+ else
784
+ if has_security_groups
785
+ security_groups_array = prompt_security_groups(sg_option_type, {zoneId: cloud_id, poolId: pool_id}, options)
786
+ if !security_groups_array.empty?
787
+ payload['securityGroups'] = security_groups_array.collect {|sg_id| {'id' => sg_id} }
788
+ end
789
+ end
730
790
  end
731
- # remove resourcePoolId if it was configured above
732
- if has_zone_pools
733
- server_type_option_types = server_type_option_types.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
791
+
792
+ api_params = {}
793
+ api_params['zoneId'] = cloud['id']
794
+ api_params['poolId'] = payload['config']['resourcePool'] if (payload['config'] && payload['config']['resourcePool'])
795
+ if payload['config']
796
+ api_params.deep_merge!(payload['config'])
734
797
  end
735
- # remove cpu and memory option types, which now come from the plan
736
- server_type_option_types = reject_service_plan_option_types(server_type_option_types)
737
-
738
- params = Morpheus::Cli::OptionTypes.prompt(server_type_option_types,options[:options],@api_client, {zoneId: cloud['id']})
798
+ #api_params.deep_merge(payload)
799
+ params = Morpheus::Cli::OptionTypes.prompt(option_type_list,options[:options],@api_client, api_params)
739
800
  payload.deep_merge!(params)
740
801
 
741
802
  end
@@ -749,8 +810,12 @@ class Morpheus::Cli::Hosts
749
810
  print JSON.pretty_generate(json_response)
750
811
  print "\n"
751
812
  elsif !options[:quiet]
752
- print_green_success "Provisioning Server..."
753
- list([])
813
+ server_id = json_response["server"]["id"]
814
+ server_name = json_response["server"]["name"]
815
+ print_green_success "Provisioning host [#{server_id}] #{server_name}"
816
+ # print details
817
+ get_args = [server_id] + (options[:remote] ? ["-r",options[:remote]] : []) + (options[:refresh_interval] ? ['--refresh', options[:refresh_interval].to_s] : [])
818
+ get(get_args)
754
819
  end
755
820
  rescue RestClient::Exception => e
756
821
  print_rest_exception(e, options)
@@ -794,7 +859,8 @@ class Morpheus::Cli::Hosts
794
859
  server = find_host_by_name_or_id(args[0])
795
860
  return 1 if server.nil?
796
861
  new_group = nil
797
- params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
862
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
863
+ params.deep_merge!(passed_options) unless passed_options.empty?
798
864
  payload = nil
799
865
  if options[:payload]
800
866
  payload = options[:payload]
@@ -1039,7 +1105,7 @@ class Morpheus::Cli::Hosts
1039
1105
  # prompt for network interfaces (if supported)
1040
1106
  # if server_type["provisionType"] && server_type["provisionType"]["id"] && server_type["provisionType"]["hasNetworks"]
1041
1107
  # begin
1042
- # network_interfaces = prompt_network_interfaces(cloud['id'], server_type["provisionType"]["id"], options)
1108
+ # network_interfaces = prompt_network_interfaces(cloud['id'], server_type["provisionType"]["id"], null, options)
1043
1109
  # if !network_interfaces.empty?
1044
1110
  # payload[:networkInterfaces] = network_interfaces
1045
1111
  # end
@@ -1410,6 +1476,64 @@ class Morpheus::Cli::Hosts
1410
1476
  end
1411
1477
  end
1412
1478
 
1479
+ def view(args)
1480
+ options = {}
1481
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1482
+ opts.banner = subcommand_usage("[host]")
1483
+ opts.on('-w','--wiki', "Open the wiki tab for this host") do
1484
+ options[:link_tab] = "wiki"
1485
+ end
1486
+ opts.on('--tab VALUE', String, "Open a specific tab") do |val|
1487
+ options[:link_tab] = val.to_s
1488
+ end
1489
+ build_common_options(opts, options, [:dry_run, :remote])
1490
+ opts.footer = "View a host in a web browser" + "\n" +
1491
+ "[host] is required. This is the name or id of a host. Supports 1-N [host] arguments."
1492
+ end
1493
+ optparse.parse!(args)
1494
+ if args.count != 1
1495
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
1496
+ end
1497
+ connect(options)
1498
+ id_list = parse_id_list(args)
1499
+ return run_command_for_each_arg(id_list) do |arg|
1500
+ _view(arg, options)
1501
+ end
1502
+ end
1503
+
1504
+ def _view(arg, options={})
1505
+ begin
1506
+ host = find_host_by_name_or_id(arg)
1507
+ return 1 if host.nil?
1508
+
1509
+ link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/infrastructure/servers/#{host['id']}"
1510
+ if options[:link_tab]
1511
+ link << "#!#{options[:link_tab]}"
1512
+ end
1513
+
1514
+ open_command = nil
1515
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
1516
+ open_command = "start #{link}"
1517
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
1518
+ open_command = "open #{link}"
1519
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
1520
+ open_command = "xdg-open #{link}"
1521
+ end
1522
+
1523
+ if options[:dry_run]
1524
+ puts "system: #{open_command}"
1525
+ return 0
1526
+ end
1527
+
1528
+ system(open_command)
1529
+
1530
+ return 0
1531
+ rescue RestClient::Exception => e
1532
+ print_rest_exception(e, options)
1533
+ exit 1
1534
+ end
1535
+ end
1536
+
1413
1537
  def wiki(args)
1414
1538
  options = {}
1415
1539
  params = {}
@@ -22,7 +22,7 @@ class Morpheus::Cli::Instances
22
22
  # register_subcommands {:'lb-update' => :load_balancer_update}
23
23
  alias_subcommand :details, :get
24
24
  set_default_subcommand :list
25
-
25
+
26
26
  def initialize()
27
27
  #@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
28
28
  end
@@ -333,6 +333,12 @@ class Morpheus::Cli::Instances
333
333
  opts.on("--create-backup [on|off]", String, "Automation: Create Backups.") do |val|
334
334
  options[:create_backup] = ['on','true','1',''].include?(val.to_s.downcase) ? 'on' : 'off'
335
335
  end
336
+ opts.on("--security-groups LIST", Integer, "Security Groups, comma sepearated list of security group IDs") do |val|
337
+ options[:security_groups] = val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
338
+ end
339
+ opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
340
+ options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
341
+ end
336
342
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
337
343
  opts.footer = "Create a new instance." + "\n" +
338
344
  "[name] is required. This is the new instance name." + "\n" +
@@ -427,7 +433,9 @@ class Morpheus::Cli::Instances
427
433
  instance_id = json_response["instance"]["id"]
428
434
  instance_name = json_response["instance"]["name"]
429
435
  print_green_success "Provisioning instance [#{instance_id}] #{instance_name}"
430
- get([instance_id] + (options[:remote] ? ["-r",options[:remote]] : []))
436
+ # print details
437
+ get_args = [instance_id] + (options[:remote] ? ["-r",options[:remote]] : []) + (options[:refresh_interval] ? ['--refresh', options[:refresh_interval].to_s] : [])
438
+ get(get_args)
431
439
  end
432
440
  return 0
433
441
  rescue RestClient::Exception => e
@@ -547,7 +555,6 @@ class Morpheus::Cli::Instances
547
555
  end
548
556
 
549
557
  def update_notes(args)
550
- print_error "#{yellow}DEPRECATION WARNING: `instances update-notes` is deprecated in 4.0, use `instances update-wiki` instead.#{reset}\n"
551
558
  usage = "Usage: morpheus instances update-notes [instance] [options]"
552
559
  options = {}
553
560
  params = {}
@@ -580,7 +587,7 @@ class Morpheus::Cli::Instances
580
587
  return 1
581
588
  end
582
589
  connect(options)
583
-
590
+ print_error "#{yellow}DEPRECATION WARNING: `instances update-notes` is deprecated in 4.0, use `instances update-wiki` instead.#{reset}\n"
584
591
  begin
585
592
  instance = find_instance_by_name_or_id(args[0])
586
593
  return 1 if instance.nil?
@@ -1092,7 +1099,7 @@ class Morpheus::Cli::Instances
1092
1099
  opts.on( nil, '--scaling', "Display Instance Scaling Settings" ) do
1093
1100
  options[:include_scaling] = true
1094
1101
  end
1095
- opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is 5 seconds.") do |val|
1102
+ opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
1096
1103
  options[:refresh_until_status] ||= "running,failed"
1097
1104
  if !val.to_s.empty?
1098
1105
  options[:refresh_interval] = val.to_f
@@ -1279,6 +1286,7 @@ class Morpheus::Cli::Instances
1279
1286
  status: format_container_status(container),
1280
1287
  name: container['server'] ? container['server']['name'] : '(no server)', # there is a server.displayName too?
1281
1288
  type: container['containerType'] ? container['containerType']['name'] : '',
1289
+ host: container['server'] ? container['server']['name'] : '',
1282
1290
  cloud: container['cloud'] ? container['cloud']['name'] : '',
1283
1291
  location: format_container_connection_string(container),
1284
1292
  cpu: cpu_usage_str + cyan,
@@ -1287,7 +1295,7 @@ class Morpheus::Cli::Instances
1287
1295
  }
1288
1296
  row
1289
1297
  }
1290
- columns = [:id, :status, :name, :type, :cloud, :location, :cpu, :memory, :storage]
1298
+ columns = [:id, :status, :name, :type, :cloud, :host, :location, :cpu, :memory, :storage]
1291
1299
  # custom pretty table columns ...
1292
1300
  if options[:include_fields]
1293
1301
  columns = options[:include_fields]
@@ -1314,11 +1322,11 @@ class Morpheus::Cli::Instances
1314
1322
  # refresh until a status is reached
1315
1323
  if options[:refresh_until_status]
1316
1324
  if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
1317
- options[:refresh_interval] = 5
1325
+ options[:refresh_interval] = default_refresh_interval
1318
1326
  end
1319
1327
  statuses = options[:refresh_until_status].to_s.downcase.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
1320
1328
  if !statuses.include?(instance['status'])
1321
- print cyan, "Refreshing in #{options[:refresh_interval]} seconds"
1329
+ print cyan, "Refreshing in #{options[:refresh_interval] > 1 ? options[:refresh_interval].to_i : options[:refresh_interval]} seconds"
1322
1330
  sleep_with_dots(options[:refresh_interval])
1323
1331
  print "\n"
1324
1332
  _get(arg, options)
@@ -5,6 +5,7 @@ require 'yaml'
5
5
  require 'ostruct'
6
6
  require 'io/console'
7
7
  require 'morpheus/logging'
8
+ require 'fileutils'
8
9
 
9
10
  module Morpheus::Cli::PrintHelper
10
11
 
@@ -144,9 +145,9 @@ module Morpheus::Cli::PrintHelper
144
145
  params = nil
145
146
  if api_request[:params] && !api_request[:params].empty?
146
147
  params = api_request[:params]
147
- elsif api_request[:headers] && api_request[:headers][:params]
148
+ elsif headers && headers[:params]
148
149
  # params inside headers for restclient reasons..
149
- params = api_request[:headers][:params]
150
+ params = headers[:params]
150
151
  elsif api_request[:query] && !api_request[:query].empty?
151
152
  params = api_request[:query]
152
153
  end
@@ -159,8 +160,54 @@ module Morpheus::Cli::PrintHelper
159
160
  end
160
161
  request_string = "#{http_method.to_s.upcase} #{url}".strip
161
162
  payload = api_request[:payload] || api_request[:body]
162
-
163
163
  #Morpheus::Logging::DarkPrinter.puts "API payload is: (#{payload.class}) #{payload.inspect}"
164
+ content_type = (headers && headers['Content-Type']) ? headers['Content-Type'] : 'application/x-www-form-urlencoded'
165
+
166
+ # write to a file?
167
+ if options[:outfile]
168
+ output = ""
169
+ if api_request[:curl] || options[:curl]
170
+ output = format_curl_command(http_method, url, headers, payload, options)
171
+ else
172
+ # body payload
173
+ output = payload
174
+ if content_type == 'application/json'
175
+ if payload.is_a?(String)
176
+ begin
177
+ payload = JSON.parse(payload)
178
+ rescue => e
179
+ #payload = "(unparsable) #{payload}"
180
+ end
181
+ end
182
+ output = JSON.pretty_generate(payload)
183
+ else
184
+ if payload.is_a?(File)
185
+ pretty_size = "#{payload.size} B"
186
+ output = "File: #{payload.path} (#{pretty_size})"
187
+ elsif payload.is_a?(String)
188
+ output = payload
189
+ else
190
+ if content_type == 'application/x-www-form-urlencoded'
191
+ body_str = payload.to_s
192
+ begin
193
+ body_str = URI.encode_www_form(payload)
194
+ rescue => ex
195
+ # raise ex
196
+ end
197
+ output = body_str
198
+ else
199
+ begin
200
+ output = JSON.pretty_generate(payload)
201
+ rescue
202
+ output = payload.to_s
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+ print_result = print_to_file(output, options[:outfile], options[:overwrite])
209
+ return print_result
210
+ end
164
211
 
165
212
  # curl output?
166
213
  if api_request[:curl] || options[:curl]
@@ -171,30 +218,14 @@ module Morpheus::Cli::PrintHelper
171
218
  return
172
219
  end
173
220
 
174
- # print this thing:
175
- # REQUEST:
176
- # POST http://morpheusdata.com/api/whoami
177
- # f it..removing this, just DRY RUN printed at the start of command
178
221
  print "\n"
179
- # if command_string != false
180
- # if command_string
181
- # print_h1 "DRY RUN > #{command_string}"
182
- # else
183
- # #print "\n"
184
- # #print_h1 "DRY RUN"
185
- # end
186
- # end
187
222
  puts "#{cyan}#{bold}#{dark}REQUEST#{reset}\n"
188
- # print cyan
189
- # print "Request: ", "\n"
190
- # print reset
191
223
  request_string = "#{http_method.to_s.upcase} #{url}".strip
192
224
  print request_string, "\n"
193
225
  print cyan
194
226
  if payload
195
-
196
227
  print "\n"
197
- if api_request[:headers] && api_request[:headers]['Content-Type'] == 'application/json'
228
+ if content_type == 'application/json'
198
229
  if payload.is_a?(String)
199
230
  begin
200
231
  payload = JSON.parse(payload)
@@ -203,18 +234,12 @@ module Morpheus::Cli::PrintHelper
203
234
  end
204
235
  end
205
236
  puts "#{cyan}#{bold}#{dark}JSON#{reset}\n"
206
- # print "JSON: ", "\n"
207
- # print reset
208
237
  print JSON.pretty_generate(payload)
209
238
  else
210
- content_type = api_request[:headers]['Content-Type'] || 'application/x-www-form-urlencoded'
211
239
  print "Content-Type: #{content_type}", "\n"
212
- # print "Body: ", "\n"
213
240
  print reset
214
241
  if payload.is_a?(File)
215
- # pretty_size = Filesize.from("#{payload.size} B").pretty.strip
216
242
  pretty_size = "#{payload.size} B"
217
- # print "File: #{payload.path} (#{payload.size} bytes)"
218
243
  print "File: #{payload.path} (#{pretty_size})"
219
244
  elsif payload.is_a?(String)
220
245
  print payload
@@ -1039,4 +1064,37 @@ module Morpheus::Cli::PrintHelper
1039
1064
  end
1040
1065
  end
1041
1066
 
1067
+ def print_to_file(txt, filename, overwrite=false, access_mode = 'w+')
1068
+ Morpheus::Logging::DarkPrinter.puts "Writing #{txt.to_s.bytesize} bytes to file #{filename} ..." if Morpheus::Logging.debug?
1069
+ outfile = nil
1070
+ begin
1071
+ full_filename = File.expand_path(filename)
1072
+ if File.exists?(full_filename)
1073
+ if !overwrite
1074
+ print "#{red}Output file '#{filename}' already exists.#{reset}\n"
1075
+ print "#{red}Use --overwrite to overwrite the existing file.#{reset}\n"
1076
+ return 1
1077
+ end
1078
+ end
1079
+ if Dir.exists?(full_filename)
1080
+ print "#{red}Output file '#{filename}' is invalid. It is the name of an existing directory.#{reset}\n"
1081
+ return 1
1082
+ end
1083
+ target_dir = File.dirname(full_filename)
1084
+ if !Dir.exists?(target_dir)
1085
+ FileUtils.mkdir_p(target_dir)
1086
+ end
1087
+ outfile = File.open(full_filename, access_mode)
1088
+ outfile.print(txt)
1089
+ print "#{cyan}Wrote #{txt.to_s.bytesize} bytes to file #{filename}\n"
1090
+ return 0
1091
+ rescue => ex
1092
+ # puts_error "Error writing to outfile '#{filename}'. Error: #{ex}"
1093
+ print "#{red}Error writing to file '#{filename}'. Error: #{ex}#{reset}\n"
1094
+ return 1
1095
+ ensure
1096
+ outfile.close if outfile
1097
+ end
1098
+ end
1099
+
1042
1100
  end