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.
@@ -11,8 +11,7 @@ class Morpheus::Cli::NetworkPoolsCommand
11
11
  set_command_name :'network-pools'
12
12
 
13
13
  register_subcommands :list, :get, :add, :update, :remove #, :generate_pool
14
-
15
- # set_default_subcommand :list
14
+ register_subcommands :list_ips, :get_ip, :add_ip, :update_ip, :remove_ip
16
15
 
17
16
  def initialize()
18
17
  # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -21,6 +20,7 @@ class Morpheus::Cli::NetworkPoolsCommand
21
20
  def connect(opts)
22
21
  @api_client = establish_remote_appliance_connection(opts)
23
22
  @network_pools_interface = @api_client.network_pools
23
+ @network_pool_ips_interface = @api_client.network_pool_ips
24
24
  @clouds_interface = @api_client.clouds
25
25
  @options_interface = @api_client.options
26
26
  end
@@ -34,7 +34,7 @@ class Morpheus::Cli::NetworkPoolsCommand
34
34
  params = {}
35
35
  optparse = Morpheus::Cli::OptionParser.new do |opts|
36
36
  opts.banner = subcommand_usage()
37
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
37
+ build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
38
38
  opts.footer = "List network pools."
39
39
  end
40
40
  optparse.parse!(args)
@@ -438,10 +438,339 @@ class Morpheus::Cli::NetworkPoolsCommand
438
438
  end
439
439
  end
440
440
 
441
+ def list_ips(args)
442
+ options = {}
443
+ params = {}
444
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
445
+ opts.banner = subcommand_usage("[network-pool]")
446
+ build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
447
+ opts.footer = "List network pool IP addresses.\n" +
448
+ "[network-pool] is required. This is the name or id of a network pool."
449
+ end
450
+ optparse.parse!(args)
451
+ connect(options)
452
+ if args.count != 1
453
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
454
+ end
455
+ begin
456
+ network_pool = find_network_pool_by_name_or_id(args[0])
457
+ return 1 if network_pool.nil?
458
+ network_pool_id = network_pool['id']
459
+
460
+ params.merge!(parse_list_options(options))
461
+ @network_pool_ips_interface.setopts(options)
462
+ if options[:dry_run]
463
+ print_dry_run @network_pool_ips_interface.dry.list(network_pool_id, params)
464
+ return
465
+ end
466
+ json_response = @network_pool_ips_interface.list(network_pool_id, params)
467
+ network_pool_ips = json_response["networkPoolIps"]
468
+ if options[:json]
469
+ puts as_json(json_response, options, "networkPoolIps")
470
+ return 0
471
+ elsif options[:yaml]
472
+ puts as_yaml(json_response, options, "networkPoolIps")
473
+ return 0
474
+ elsif options[:csv]
475
+ puts records_as_csv(network_pool_ips, options)
476
+ return 0
477
+ end
478
+ title = "Morpheus Network Pool IPs"
479
+ subtitles = []
480
+ subtitles += parse_list_subtitles(options)
481
+ print_h1 title, subtitles
482
+ if network_pool_ips.empty?
483
+ print cyan,"No network pool IPs found.",reset,"\n"
484
+ else
485
+ columns = [
486
+ {"ID" => lambda {|it| it['id'] } },
487
+ {"IP ADDRESS" => lambda {|it| it['ipAddress'] } },
488
+ {"HOSTNAME" => lambda {|it| it['hostname'] } },
489
+ {"TYPE" => lambda {|it| it['ipType'] } },
490
+ #{"CREATED BY" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' } },
491
+ {"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } },
492
+ {"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) } },
493
+ ]
494
+ if options[:include_fields]
495
+ columns = options[:include_fields]
496
+ end
497
+ print as_pretty_table(network_pool_ips, columns, options)
498
+ print_results_pagination(json_response)
499
+ end
500
+ print reset,"\n"
501
+ return 0
502
+ rescue RestClient::Exception => e
503
+ print_rest_exception(e, options)
504
+ exit 1
505
+ end
506
+ end
507
+
508
+ def get_ip(args)
509
+ options = {}
510
+ params = {}
511
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
512
+ opts.banner = subcommand_usage("[network-pool] [ip]")
513
+ build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
514
+ opts.footer = "Get details about a network pool IP address.\n" +
515
+ "[network-pool] is required. This is the name or id of a network pool.\n" +
516
+ "[ip] is required. This is the ip address or id of a network pool IP."
517
+ end
518
+ optparse.parse!(args)
519
+ connect(options)
520
+ if args.count != 2
521
+ raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
522
+ end
523
+ begin
524
+ network_pool = find_network_pool_by_name_or_id(args[0])
525
+ return 1 if network_pool.nil?
526
+ network_pool_id = network_pool['id']
527
+
528
+ params.merge!(parse_list_options(options))
529
+ @network_pool_ips_interface.setopts(options)
530
+ if options[:dry_run]
531
+ if args[1].to_s =~ /\A\d{1,}\Z/
532
+ print_dry_run @network_pool_ips_interface.dry.get(network_pool_id, args[1].to_i)
533
+ else
534
+ print_dry_run @network_pool_ips_interface.dry.list(network_pool_id, {ipAddress:args[1]})
535
+ end
536
+ return
537
+ end
538
+ network_pool_ip = find_network_pool_ip_by_address_or_id(network_pool_id, args[1])
539
+ return 1 if network_pool_ip.nil?
540
+ json_response = {'networkPoolIp' => network_pool_ip} # skip redundant request
541
+ # json_response = @network_pool_ips_interface.get(network_pool_id, args[1])
542
+ #network_pool_ip = json_response['networkPoolIp']
543
+ if options[:json]
544
+ puts as_json(json_response, options, "networkPoolIp")
545
+ return 0
546
+ elsif options[:yaml]
547
+ puts as_yaml(json_response, options, "networkPoolIp")
548
+ return 0
549
+ elsif options[:csv]
550
+ puts records_as_csv([network_pool_ip], options)
551
+ return 0
552
+ end
553
+ print_h1 "Network Pool IP Details"
554
+ print cyan
555
+ description_cols = {
556
+ "ID" => 'id',
557
+ "IP Address" => lambda {|it| it['ipAddress'] },
558
+ "Hostname" => lambda {|it| it['hostname'] },
559
+ "Type" => lambda {|it| it['ipType'] ? it['ipType'] : '' },
560
+ # "Gateway" => lambda {|it| network_pool['gatewayAddress'] },
561
+ # "Subnet Mask" => lambda {|it| network_pool['subnetMask'] },
562
+ # "DNS Server" => lambda {|it| network_pool['dnsServer'] },
563
+ "Pool" => lambda {|it| network_pool['name'] },
564
+ #"Pool" => lambda {|it| it['networkPool'] ? it['networkPool']['name'] : '' },
565
+ "Interface" => lambda {|it| network_pool['interfaceName'] },
566
+ "Created By" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' },
567
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
568
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
569
+ }
570
+ print_description_list(description_cols, network_pool_ip)
571
+
572
+ print reset,"\n"
573
+ return 0
574
+ rescue RestClient::Exception => e
575
+ print_rest_exception(e, options)
576
+ exit 1
577
+ end
578
+ end
579
+
580
+ def add_ip(args)
581
+ options = {}
582
+ params = {}
583
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
584
+ opts.banner = subcommand_usage("[network-pool] [ip]")
585
+ opts.on('--ip-address VALUE', String, "IP Address for this network pool IP") do |val|
586
+ options[:options]['ipAddress'] = val
587
+ end
588
+ opts.on('--hostname VALUE', String, "Hostname for this network pool IP") do |val|
589
+ options[:options]['hostname'] = val
590
+ end
591
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
592
+ opts.footer = "Create a new network pool IP." + "\n" +
593
+ "[network-pool] is required. This is the name or id of a network pool.\n" +
594
+ "[ip] is required and can be passed as --ip-address instead."
595
+ end
596
+ optparse.parse!(args)
597
+ if args.count < 1 || args.count > 2
598
+ raise_command_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args}\n#{optparse}"
599
+ end
600
+ connect(options)
601
+ begin
602
+ network_pool = find_network_pool_by_name_or_id(args[0])
603
+ return 1 if network_pool.nil?
604
+ network_pool_id = network_pool['id']
605
+
606
+ # support [ip] as first argument
607
+ if args[1]
608
+ options[:options]['ipAddress'] = args[1]
609
+ end
610
+
611
+ # construct payload
612
+ payload = nil
613
+ if options[:payload]
614
+ payload = options[:payload]
615
+ else
616
+ # prompt for network options
617
+ payload = {
618
+ 'networkPoolIp' => {
619
+ }
620
+ }
621
+
622
+ # allow arbitrary -O options
623
+ payload['networkPoolIp'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
624
+
625
+ # IP Address
626
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ipAddress', 'fieldLabel' => 'IP Address', 'type' => 'text', 'required' => true, 'description' => 'IP Address for this network pool IP.'}], options[:options])
627
+ payload['networkPoolIp']['ipAddress'] = v_prompt['ipAddress'] unless v_prompt['ipAddress'].to_s.empty?
628
+
629
+ # Hostname
630
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hostname', 'fieldLabel' => 'Hostname', 'type' => 'text', 'required' => true, 'description' => 'Hostname for this network pool IP.'}], options[:options])
631
+ payload['networkPoolIp']['hostname'] = v_prompt['hostname'] unless v_prompt['hostname'].to_s.empty?
632
+
633
+ end
634
+
635
+ @network_pool_ips_interface.setopts(options)
636
+ if options[:dry_run]
637
+ print_dry_run @network_pool_ips_interface.dry.create(network_pool_id, payload)
638
+ return
639
+ end
640
+ json_response = @network_pool_ips_interface.create(network_pool_id, payload)
641
+ if options[:json]
642
+ print JSON.pretty_generate(json_response)
643
+ print "\n"
644
+ elsif !options[:quiet]
645
+ network_pool_ip = json_response['networkPoolIp']
646
+ print_green_success "Added network pool IP #{network_pool_ip['ipAddress']}"
647
+ get_ip([network_pool['id'], network_pool_ip['id']])
648
+ end
649
+ return 0
650
+ rescue RestClient::Exception => e
651
+ print_rest_exception(e, options)
652
+ exit 1
653
+ end
654
+ end
655
+
656
+ def update_ip(args)
657
+ options = {}
658
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
659
+ opts.banner = subcommand_usage("[network-pool] [ip] [options]")
660
+ opts.on('--hostname VALUE', String, "Hostname for this network pool IP") do |val|
661
+ options[:options]['hostname'] = val
662
+ end
663
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
664
+ opts.footer = "Update a network pool IP." + "\n" +
665
+ "[network-pool] is required. This is the name or id of a network pool.\n" +
666
+ "[ip] is required. This is the ip address or id of a network pool IP."
667
+ end
668
+ optparse.parse!(args)
669
+ if args.count != 2
670
+ raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
671
+ end
672
+ connect(options)
673
+ begin
674
+ network_pool = find_network_pool_by_name_or_id(args[0])
675
+ return 1 if network_pool.nil?
676
+ network_pool_id = network_pool['id']
677
+
678
+ network_pool_ip = find_network_pool_ip_by_address_or_id(network_pool_id, args[1])
679
+ return 1 if network_pool_ip.nil?
680
+
681
+ # merge -O options into normally parsed options
682
+ options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
683
+
684
+ # construct payload
685
+ payload = nil
686
+ if options[:payload]
687
+ payload = options[:payload]
688
+ else
689
+ # prompt for network options
690
+ payload = {
691
+ 'networkPoolIp' => {
692
+ }
693
+ }
694
+
695
+ # allow arbitrary -O options
696
+ payload['networkPoolIp'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
697
+
698
+ if payload['networkPoolIp'].empty?
699
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
700
+ end
701
+
702
+ end
703
+
704
+ @network_pool_ips_interface.setopts(options)
705
+ if options[:dry_run]
706
+ print_dry_run @network_pool_ips_interface.dry.update(network_pool_id, network_pool_ip['id'], payload)
707
+ return
708
+ end
709
+ json_response = @network_pool_ips_interface.update(network_pool_id, network_pool_ip['id'], payload)
710
+ if options[:json]
711
+ print JSON.pretty_generate(json_response)
712
+ print "\n"
713
+ elsif !options[:quiet]
714
+ network_pool_ip = json_response['networkPoolIp']
715
+ print_green_success "Updated network pool IP #{network_pool_ip['ipAddress']}"
716
+ get_ip([network_pool['id'], network_pool_ip['id']])
717
+ end
718
+ return 0
719
+ rescue RestClient::Exception => e
720
+ print_rest_exception(e, options)
721
+ exit 1
722
+ end
723
+ end
724
+
725
+ def remove_ip(args)
726
+ options = {}
727
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
728
+ opts.banner = subcommand_usage("[network-pool] [ip]")
729
+ build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
730
+ opts.footer = "Delete a network pool IP." + "\n" +
731
+ "[network-pool] is required. This is the name or id of a network pool.\n" +
732
+ "[ip] is required. This is the ip address or id of a network pool IP."
733
+ end
734
+ optparse.parse!(args)
735
+ if args.count != 2
736
+ raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
737
+ end
738
+ connect(options)
739
+ begin
740
+ network_pool = find_network_pool_by_name_or_id(args[0])
741
+ return 1 if network_pool.nil?
742
+ network_pool_id = network_pool['id']
743
+
744
+ network_pool_ip = find_network_pool_ip_by_address_or_id(network_pool_id, args[1])
745
+ return 1 if network_pool_ip.nil?
746
+
747
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the network pool IP: #{network_pool_ip['ipAddress']} (#{network_pool_ip['hostname']})?")
748
+ return 9, "aborted command"
749
+ end
750
+ @network_pool_ips_interface.setopts(options)
751
+ if options[:dry_run]
752
+ print_dry_run @network_pool_ips_interface.dry.destroy(network_pool['id'], network_pool_ip['id'])
753
+ return 0
754
+ end
755
+ json_response = @network_pool_ips_interface.destroy(network_pool['id'], network_pool_ip['id'])
756
+ if options[:json]
757
+ print JSON.pretty_generate(json_response)
758
+ print "\n"
759
+ else
760
+ print_green_success "Removed network pool IP #{network_pool_ip['ipAddress']} (#{network_pool_ip['hostname']})"
761
+ # list([])
762
+ end
763
+ return 0
764
+ rescue RestClient::Exception => e
765
+ print_rest_exception(e, options)
766
+ return 1
767
+ end
768
+ end
769
+
441
770
  private
442
771
 
443
772
 
444
- def find_network_pool_by_name_or_id(val)
773
+ def find_network_pool_by_name_or_id(val)
445
774
  if val.to_s =~ /\A\d{1,}\Z/
446
775
  return find_network_pool_by_id(val)
447
776
  else
@@ -482,4 +811,47 @@ class Morpheus::Cli::NetworkPoolsCommand
482
811
  end
483
812
  end
484
813
 
814
+ def find_network_pool_ip_by_address_or_id(network_pool_id, val)
815
+ if val.to_s =~ /\A\d{1,}\Z/
816
+ return find_network_pool_ip_by_id(network_pool_id, val)
817
+ else
818
+ return find_network_pool_ip_by_address(network_pool_id, val)
819
+ end
820
+ end
821
+
822
+ def find_network_pool_ip_by_id(network_pool_id, id)
823
+ begin
824
+ json_response = @network_pool_ips_interface.get(network_pool_id, id.to_i)
825
+ return json_response['networkPoolIp']
826
+ rescue RestClient::Exception => e
827
+ if e.response && e.response.code == 404
828
+ print_red_alert "Network Pool IP not found by id #{id}"
829
+ return nil
830
+ else
831
+ raise e
832
+ end
833
+ end
834
+ end
835
+
836
+ def find_network_pool_ip_by_address(network_pool_id, address)
837
+ json_response = @network_pool_ips_interface.list(network_pool_id, {ipAddress: address.to_s})
838
+ network_pool_ips = json_response['networkPoolIps']
839
+ if network_pool_ips.empty?
840
+ print_red_alert "Network Pool IP not found by address #{address}"
841
+ return nil
842
+ elsif network_pool_ips.size > 1
843
+ print_red_alert "#{network_pool_ips.size} network pool IPs found by address #{address}"
844
+ columns = [
845
+ {"ID" => lambda {|it| it['id'] } },
846
+ {"IP ADDRESS" => lambda {|it| it['ipAddress'] } },
847
+ {"HOSTNAME" => lambda {|it| it['hostname'] } },
848
+ {"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } }
849
+ ]
850
+ puts as_pretty_table(network_pool_ips, columns, {color:red})
851
+ return nil
852
+ else
853
+ return network_pool_ips[0]
854
+ end
855
+ end
856
+
485
857
  end
@@ -35,9 +35,9 @@ module Morpheus
35
35
  is_hidden = (@hidden_options || []).find { |hidden_switch|
36
36
  # opt_description.include?("--#{hidden_switch}")
37
37
  if hidden_switch.start_with?("-")
38
- opt_description.to_s.strip.start_with?(hidden_switch)
38
+ opt_description.to_s.strip.start_with?("#{hidden_switch} ")
39
39
  else
40
- opt_description.to_s.strip.start_with?("--#{hidden_switch}")
40
+ opt_description.to_s.strip.start_with?("--#{hidden_switch} ")
41
41
  end
42
42
  }
43
43
  if !is_hidden
@@ -92,7 +92,7 @@ class Morpheus::Cli::ReportsCommand
92
92
  options = {}
93
93
  optparse = Morpheus::Cli::OptionParser.new do |opts|
94
94
  opts.banner = subcommand_usage("[id]")
95
- opts.on('--refresh [SECONDS]', String, "Refresh until status is ready,failed. Default interval is 5 seconds.") do |val|
95
+ opts.on('--refresh [SECONDS]', String, "Refresh until status is ready,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
96
96
  options[:refresh_until_status] ||= "ready,failed"
97
97
  if !val.to_s.empty?
98
98
  options[:refresh_interval] = val.to_f
@@ -186,11 +186,11 @@ class Morpheus::Cli::ReportsCommand
186
186
  # refresh until a status is reached
187
187
  if options[:refresh_until_status]
188
188
  if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
189
- options[:refresh_interval] = 5
189
+ options[:refresh_interval] = default_refresh_interval
190
190
  end
191
191
  statuses = options[:refresh_until_status].to_s.downcase.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
192
192
  if !statuses.include?(report_result['status'])
193
- print cyan, "Refreshing in #{options[:refresh_interval]} seconds"
193
+ print cyan, "Refreshing in #{options[:refresh_interval] > 1 ? options[:refresh_interval].to_i : options[:refresh_interval]} seconds"
194
194
  sleep_with_dots(options[:refresh_interval])
195
195
  print "\n"
196
196
  get(original_args)
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "3.6.38"
4
+ VERSION = "4.0.0"
5
5
  end
6
6
  end