morpheus-cli 3.6.38 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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