morpheus-cli 3.6.31 → 3.6.32

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,6 +13,7 @@ class Morpheus::Cli::Groups
13
13
 
14
14
  register_subcommands :list, :get, :add, :update, :use, :unuse, :add_cloud, :remove_cloud, :remove, :current => :print_current
15
15
  alias_subcommand :details, :get
16
+ register_subcommands :wiki, :update_wiki
16
17
  set_default_subcommand :list
17
18
 
18
19
  def initialize()
@@ -480,6 +481,205 @@ class Morpheus::Cli::Groups
480
481
  end
481
482
  end
482
483
 
484
+ def wiki(args)
485
+ options = {}
486
+ params = {}
487
+ open_wiki_link = false
488
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
489
+ opts.banner = subcommand_usage("[group]")
490
+ opts.on('--view', '--view', "View wiki page in web browser.") do
491
+ open_wiki_link = true
492
+ end
493
+ build_common_options(opts, options, [:json, :dry_run, :remote])
494
+ opts.footer = "View wiki page details for an group." + "\n" +
495
+ "[group] is required. This is the name or id of an group."
496
+ end
497
+ optparse.parse!(args)
498
+ if args.count != 1
499
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
500
+ return 1
501
+ end
502
+ connect(options)
503
+
504
+ begin
505
+ group = find_group_by_name_or_id(args[0])
506
+ return 1 if group.nil?
507
+
508
+
509
+ @groups_interface.setopts(options)
510
+ if options[:dry_run]
511
+ print_dry_run @groups_interface.dry.wiki(group["id"], params)
512
+ return
513
+ end
514
+ json_response = @groups_interface.wiki(group["id"], params)
515
+ page = json_response['page']
516
+
517
+ render_result = render_with_format(json_response, options, 'page')
518
+ return 0 if render_result
519
+
520
+ if page
521
+
522
+ # my_terminal.exec("wiki get #{page['id']}")
523
+
524
+ print_h1 "Group Wiki Page: #{group['name']}"
525
+ # print_h1 "Wiki Page Details"
526
+ print cyan
527
+
528
+ print_description_list({
529
+ "Page ID" => 'id',
530
+ "Name" => 'name',
531
+ #"Category" => 'category',
532
+ #"Ref Type" => 'refType',
533
+ #"Ref ID" => 'refId',
534
+ #"Owner" => lambda {|it| it['account'] ? it['account']['name'] : '' },
535
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
536
+ "Created By" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' },
537
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
538
+ "Updated By" => lambda {|it| it['updatedBy'] ? it['updatedBy']['username'] : '' }
539
+ }, page)
540
+ print reset,"\n"
541
+
542
+ print_h2 "Page Content"
543
+ print cyan, page['content'], reset, "\n"
544
+
545
+ else
546
+ print "\n"
547
+ print cyan, "No wiki page found.", reset, "\n"
548
+ end
549
+ print reset,"\n"
550
+
551
+ if open_wiki_link
552
+ return view_wiki([args[0]])
553
+ end
554
+
555
+ return 0
556
+ rescue RestClient::Exception => e
557
+ print_rest_exception(e, options)
558
+ exit 1
559
+ end
560
+ end
561
+
562
+ def view_wiki(args)
563
+ params = {}
564
+ options = {}
565
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
566
+ opts.banner = subcommand_usage("[id]")
567
+ build_common_options(opts, options, [:dry_run, :remote])
568
+ opts.footer = "View group wiki page in a web browser" + "\n" +
569
+ "[group] is required. This is the name or id of an group."
570
+ end
571
+ optparse.parse!(args)
572
+ if args.count != 1
573
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
574
+ end
575
+ connect(options)
576
+ begin
577
+ group = find_group_by_name_or_id(args[0])
578
+ return 1 if group.nil?
579
+
580
+ link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/infrastructure/groups/#{group['id']}#!wiki"
581
+
582
+ open_command = nil
583
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
584
+ open_command = "start #{link}"
585
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
586
+ open_command = "open #{link}"
587
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
588
+ open_command = "xdg-open #{link}"
589
+ end
590
+
591
+ if options[:dry_run]
592
+ puts "system: #{open_command}"
593
+ return 0
594
+ end
595
+
596
+ system(open_command)
597
+
598
+ return 0
599
+ rescue RestClient::Exception => e
600
+ print_rest_exception(e, options)
601
+ exit 1
602
+ end
603
+ end
604
+
605
+ def update_wiki(args)
606
+ options = {}
607
+ params = {}
608
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
609
+ opts.banner = subcommand_usage("[group] [options]")
610
+ build_option_type_options(opts, options, update_wiki_page_option_types)
611
+ opts.on('--file FILE', "File containing the wiki content. This can be used instead of --content") do |filename|
612
+ full_filename = File.expand_path(filename)
613
+ if File.exists?(full_filename)
614
+ params['content'] = File.read(full_filename)
615
+ else
616
+ print_red_alert "File not found: #{full_filename}"
617
+ return 1
618
+ end
619
+ # use the filename as the name by default.
620
+ if !params['name']
621
+ params['name'] = File.basename(full_filename)
622
+ end
623
+ end
624
+ opts.on(nil, '--clear', "Clear current page content") do |val|
625
+ params['content'] = ""
626
+ end
627
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
628
+ end
629
+ optparse.parse!(args)
630
+ if args.count != 1
631
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
632
+ return 1
633
+ end
634
+ connect(options)
635
+
636
+ begin
637
+ group = find_group_by_name_or_id(args[0])
638
+ return 1 if group.nil?
639
+ # construct payload
640
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
641
+ payload = nil
642
+ if options[:payload]
643
+ payload = options[:payload]
644
+ payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
645
+ else
646
+ payload = {
647
+ 'page' => {
648
+ }
649
+ }
650
+ # allow arbitrary -O options
651
+ payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
652
+ # prompt for options
653
+ #params = Morpheus::Cli::OptionTypes.prompt(update_wiki_page_option_types, options[:options], @api_client, options[:params])
654
+ #params = passed_options
655
+ params.deep_merge!(passed_options)
656
+
657
+ if params.empty?
658
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
659
+ end
660
+
661
+ payload.deep_merge!({'page' => params}) unless params.empty?
662
+ end
663
+ @groups_interface.setopts(options)
664
+ if options[:dry_run]
665
+ print_dry_run @groups_interface.dry.update_wiki(group["id"], payload)
666
+ return
667
+ end
668
+ json_response = @groups_interface.update_wiki(group["id"], payload)
669
+
670
+ if options[:json]
671
+ puts as_json(json_response, options)
672
+ else
673
+ print_green_success "Updated wiki page for group #{group['name']}"
674
+ wiki([group['id']])
675
+ end
676
+ return 0
677
+ rescue RestClient::Exception => e
678
+ print_rest_exception(e, options)
679
+ exit 1
680
+ end
681
+ end
682
+
483
683
  protected
484
684
 
485
685
  def print_groups_table(groups, opts={})
@@ -596,4 +796,11 @@ public
596
796
 
597
797
  end
598
798
 
799
+ def update_wiki_page_option_types
800
+ [
801
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1, 'description' => 'The name of the wiki page for this instance. Default is the instance name.'},
802
+ #{'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
803
+ {'fieldName' => 'content', 'fieldLabel' => 'Content', 'type' => 'textarea', 'required' => false, 'displayOrder' => 3, 'description' => 'The content (markdown) of the wiki page.'}
804
+ ]
805
+ end
599
806
  end
@@ -17,6 +17,7 @@ class Morpheus::Cli::Hosts
17
17
  register_subcommands :list, :count, :get, :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
+ register_subcommands :wiki, :update_wiki
20
21
  alias_subcommand :details, :get
21
22
  set_default_subcommand :list
22
23
 
@@ -1409,6 +1410,205 @@ class Morpheus::Cli::Hosts
1409
1410
  end
1410
1411
  end
1411
1412
 
1413
+ def wiki(args)
1414
+ options = {}
1415
+ params = {}
1416
+ open_wiki_link = false
1417
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1418
+ opts.banner = subcommand_usage("[host]")
1419
+ opts.on('--view', '--view', "View wiki page in web browser.") do
1420
+ open_wiki_link = true
1421
+ end
1422
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1423
+ opts.footer = "View wiki page details for a host." + "\n" +
1424
+ "[host] is required. This is the name or id of a host."
1425
+ end
1426
+ optparse.parse!(args)
1427
+ if args.count != 1
1428
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
1429
+ return 1
1430
+ end
1431
+ connect(options)
1432
+
1433
+ begin
1434
+ host = find_host_by_name_or_id(args[0])
1435
+ return 1 if host.nil?
1436
+
1437
+
1438
+ @servers_interface.setopts(options)
1439
+ if options[:dry_run]
1440
+ print_dry_run @servers_interface.dry.wiki(host["id"], params)
1441
+ return
1442
+ end
1443
+ json_response = @servers_interface.wiki(host["id"], params)
1444
+ page = json_response['page']
1445
+
1446
+ render_result = render_with_format(json_response, options, 'page')
1447
+ return 0 if render_result
1448
+
1449
+ if page
1450
+
1451
+ # my_terminal.exec("wiki get #{page['id']}")
1452
+
1453
+ print_h1 "Host Wiki Page: #{host['name']}"
1454
+ # print_h1 "Wiki Page Details"
1455
+ print cyan
1456
+
1457
+ print_description_list({
1458
+ "Page ID" => 'id',
1459
+ "Name" => 'name',
1460
+ #"Category" => 'category',
1461
+ #"Ref Type" => 'refType',
1462
+ #"Ref ID" => 'refId',
1463
+ #"Owner" => lambda {|it| it['account'] ? it['account']['name'] : '' },
1464
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
1465
+ "Created By" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' },
1466
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
1467
+ "Updated By" => lambda {|it| it['updatedBy'] ? it['updatedBy']['username'] : '' }
1468
+ }, page)
1469
+ print reset,"\n"
1470
+
1471
+ print_h2 "Page Content"
1472
+ print cyan, page['content'], reset, "\n"
1473
+
1474
+ else
1475
+ print "\n"
1476
+ print cyan, "No wiki page found.", reset, "\n"
1477
+ end
1478
+ print reset,"\n"
1479
+
1480
+ if open_wiki_link
1481
+ return view_wiki([args[0]])
1482
+ end
1483
+
1484
+ return 0
1485
+ rescue RestClient::Exception => e
1486
+ print_rest_exception(e, options)
1487
+ exit 1
1488
+ end
1489
+ end
1490
+
1491
+ def view_wiki(args)
1492
+ params = {}
1493
+ options = {}
1494
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1495
+ opts.banner = subcommand_usage("[id]")
1496
+ build_common_options(opts, options, [:dry_run, :remote])
1497
+ opts.footer = "View host wiki page in a web browser" + "\n" +
1498
+ "[host] is required. This is the name or id of a host."
1499
+ end
1500
+ optparse.parse!(args)
1501
+ if args.count != 1
1502
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
1503
+ end
1504
+ connect(options)
1505
+ begin
1506
+ host = find_host_by_name_or_id(args[0])
1507
+ return 1 if host.nil?
1508
+
1509
+ link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/infrastructure/servers/#{host['id']}#!wiki"
1510
+
1511
+ open_command = nil
1512
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
1513
+ open_command = "start #{link}"
1514
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
1515
+ open_command = "open #{link}"
1516
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
1517
+ open_command = "xdg-open #{link}"
1518
+ end
1519
+
1520
+ if options[:dry_run]
1521
+ puts "system: #{open_command}"
1522
+ return 0
1523
+ end
1524
+
1525
+ system(open_command)
1526
+
1527
+ return 0
1528
+ rescue RestClient::Exception => e
1529
+ print_rest_exception(e, options)
1530
+ exit 1
1531
+ end
1532
+ end
1533
+
1534
+ def update_wiki(args)
1535
+ options = {}
1536
+ params = {}
1537
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1538
+ opts.banner = subcommand_usage("[host] [options]")
1539
+ build_option_type_options(opts, options, update_wiki_page_option_types)
1540
+ opts.on('--file FILE', "File containing the wiki content. This can be used instead of --content") do |filename|
1541
+ full_filename = File.expand_path(filename)
1542
+ if File.exists?(full_filename)
1543
+ params['content'] = File.read(full_filename)
1544
+ else
1545
+ print_red_alert "File not found: #{full_filename}"
1546
+ return 1
1547
+ end
1548
+ # use the filename as the name by default.
1549
+ if !params['name']
1550
+ params['name'] = File.basename(full_filename)
1551
+ end
1552
+ end
1553
+ opts.on(nil, '--clear', "Clear current page content") do |val|
1554
+ params['content'] = ""
1555
+ end
1556
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
1557
+ end
1558
+ optparse.parse!(args)
1559
+ if args.count != 1
1560
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
1561
+ return 1
1562
+ end
1563
+ connect(options)
1564
+
1565
+ begin
1566
+ host = find_host_by_name_or_id(args[0])
1567
+ return 1 if host.nil?
1568
+ # construct payload
1569
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
1570
+ payload = nil
1571
+ if options[:payload]
1572
+ payload = options[:payload]
1573
+ payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
1574
+ else
1575
+ payload = {
1576
+ 'page' => {
1577
+ }
1578
+ }
1579
+ # allow arbitrary -O options
1580
+ payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
1581
+ # prompt for options
1582
+ #params = Morpheus::Cli::OptionTypes.prompt(update_wiki_page_option_types, options[:options], @api_client, options[:params])
1583
+ #params = passed_options
1584
+ params.deep_merge!(passed_options)
1585
+
1586
+ if params.empty?
1587
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
1588
+ end
1589
+
1590
+ payload.deep_merge!({'page' => params}) unless params.empty?
1591
+ end
1592
+ @servers_interface.setopts(options)
1593
+ if options[:dry_run]
1594
+ print_dry_run @servers_interface.dry.update_wiki(host["id"], payload)
1595
+ return
1596
+ end
1597
+ json_response = @servers_interface.update_wiki(host["id"], payload)
1598
+
1599
+ if options[:json]
1600
+ puts as_json(json_response, options)
1601
+ else
1602
+ print_green_success "Updated wiki page for host #{host['name']}"
1603
+ wiki([host['id']])
1604
+ end
1605
+ return 0
1606
+ rescue RestClient::Exception => e
1607
+ print_rest_exception(e, options)
1608
+ exit 1
1609
+ end
1610
+ end
1611
+
1412
1612
  private
1413
1613
 
1414
1614
  def find_host_by_id(id)
@@ -1550,4 +1750,12 @@ class Morpheus::Cli::Hosts
1550
1750
  ]
1551
1751
  end
1552
1752
 
1753
+ def update_wiki_page_option_types
1754
+ [
1755
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1, 'description' => 'The name of the wiki page for this instance. Default is the instance name.'},
1756
+ #{'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
1757
+ {'fieldName' => 'content', 'fieldLabel' => 'Content', 'type' => 'textarea', 'required' => false, 'displayOrder' => 3, 'description' => 'The content (markdown) of the wiki page.'}
1758
+ ]
1759
+ end
1760
+
1553
1761
  end
@@ -15,8 +15,10 @@ class Morpheus::Cli::Instances
15
15
  include Morpheus::Cli::ProcessesHelper
16
16
  set_command_name :instances
17
17
  set_command_description "View and manage instances."
18
- register_subcommands :list, :count, :get, :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, :firewall_enable, :firewall_disable, :run_workflow, :import_snapshot, :console, :status_check, {:containers => :list_containers}, :scaling, {:'scaling-update' => :scaling_update}
18
+ 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}
19
+ register_subcommands :wiki, :update_wiki
19
20
  register_subcommands :exec => :execution_request
21
+ #register_subcommands :firewall_disable, :firewall_enable
20
22
  # register_subcommands {:'lb-update' => :load_balancer_update}
21
23
  alias_subcommand :details, :get
22
24
  set_default_subcommand :list
@@ -301,6 +303,9 @@ class Morpheus::Cli::Instances
301
303
  opts.on("--description [TEXT]", String, "Description") do |val|
302
304
  options[:description] = val.to_s
303
305
  end
306
+ opts.on("--environment ENV", String, "Environment code") do |val|
307
+ options[:environment] = val.to_s
308
+ end
304
309
  opts.on("--copies NUMBER", Integer, "Number of copies to provision") do |val|
305
310
  options[:copies] = val.to_i
306
311
  end
@@ -380,6 +385,12 @@ class Morpheus::Cli::Instances
380
385
  if options[:instance_name]
381
386
  payload['instance']['name'] = options[:instance_name]
382
387
  end
388
+ if options[:description] && !payload['instance']['description']
389
+ payload['instance']['description'] = options[:description]
390
+ end
391
+ if options[:environment] && !payload['instance']['instanceContext']
392
+ payload['instance']['instanceContext'] = options[:environment]
393
+ end
383
394
  payload[:copies] = options[:copies] if options[:copies] && options[:copies] > 0
384
395
  payload[:layoutSize] = options[:layout_size] if options[:layout_size] && options[:layout_size] > 0 # aka Scale Factor
385
396
  payload[:createBackup] = options[:create_backup] if !options[:create_backup].nil?
@@ -537,6 +548,7 @@ class Morpheus::Cli::Instances
537
548
  end
538
549
 
539
550
  def update_notes(args)
551
+ print_error "#{yellow}DEPRECATION WARNING: `instances update-notes` is deprecated in 4.0, use `instances update-wiki` instead.#{reset}\n"
540
552
  usage = "Usage: morpheus instances update-notes [instance] [options]"
541
553
  options = {}
542
554
  params = {}
@@ -612,6 +624,205 @@ class Morpheus::Cli::Instances
612
624
  end
613
625
  end
614
626
 
627
+ def wiki(args)
628
+ options = {}
629
+ params = {}
630
+ open_wiki_link = false
631
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
632
+ opts.banner = subcommand_usage("[instance]")
633
+ opts.on('--view', '--view', "View wiki page in web browser.") do
634
+ open_wiki_link = true
635
+ end
636
+ build_common_options(opts, options, [:json, :dry_run, :remote])
637
+ opts.footer = "View wiki page details for an instance." + "\n" +
638
+ "[instance] is required. This is the name or id of an instance."
639
+ end
640
+ optparse.parse!(args)
641
+ if args.count != 1
642
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
643
+ return 1
644
+ end
645
+ connect(options)
646
+
647
+ begin
648
+ instance = find_instance_by_name_or_id(args[0])
649
+ return 1 if instance.nil?
650
+
651
+
652
+ @instances_interface.setopts(options)
653
+ if options[:dry_run]
654
+ print_dry_run @instances_interface.dry.wiki(instance["id"], params)
655
+ return
656
+ end
657
+ json_response = @instances_interface.wiki(instance["id"], params)
658
+ page = json_response['page']
659
+
660
+ render_result = render_with_format(json_response, options, 'page')
661
+ return 0 if render_result
662
+
663
+ if page
664
+
665
+ # my_terminal.exec("wiki get #{page['id']}")
666
+
667
+ print_h1 "Instance Wiki Page: #{instance['name']}"
668
+ # print_h1 "Wiki Page Details"
669
+ print cyan
670
+
671
+ print_description_list({
672
+ "Page ID" => 'id',
673
+ "Name" => 'name',
674
+ #"Category" => 'category',
675
+ #"Ref Type" => 'refType',
676
+ #"Ref ID" => 'refId',
677
+ #"Owner" => lambda {|it| it['account'] ? it['account']['name'] : '' },
678
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
679
+ "Created By" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' },
680
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
681
+ "Updated By" => lambda {|it| it['updatedBy'] ? it['updatedBy']['username'] : '' }
682
+ }, page)
683
+ print reset,"\n"
684
+
685
+ print_h2 "Page Content"
686
+ print cyan, page['content'], reset, "\n"
687
+
688
+ else
689
+ print "\n"
690
+ print cyan, "No wiki page found.", reset, "\n"
691
+ end
692
+ print reset,"\n"
693
+
694
+ if open_wiki_link
695
+ return view_wiki([args[0]])
696
+ end
697
+
698
+ return 0
699
+ rescue RestClient::Exception => e
700
+ print_rest_exception(e, options)
701
+ exit 1
702
+ end
703
+ end
704
+
705
+ def view_wiki(args)
706
+ params = {}
707
+ options = {}
708
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
709
+ opts.banner = subcommand_usage("[id]")
710
+ build_common_options(opts, options, [:dry_run, :remote])
711
+ opts.footer = "View instance wiki page in a web browser" + "\n" +
712
+ "[instance] is required. This is the name or id of an instance."
713
+ end
714
+ optparse.parse!(args)
715
+ if args.count != 1
716
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
717
+ end
718
+ connect(options)
719
+ begin
720
+ instance = find_instance_by_name_or_id(args[0])
721
+ return 1 if instance.nil?
722
+
723
+ link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/provisioning/instances/#{instance['id']}#!wiki"
724
+
725
+ open_command = nil
726
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
727
+ open_command = "start #{link}"
728
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
729
+ open_command = "open #{link}"
730
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
731
+ open_command = "xdg-open #{link}"
732
+ end
733
+
734
+ if options[:dry_run]
735
+ puts "system: #{open_command}"
736
+ return 0
737
+ end
738
+
739
+ system(open_command)
740
+
741
+ return 0
742
+ rescue RestClient::Exception => e
743
+ print_rest_exception(e, options)
744
+ exit 1
745
+ end
746
+ end
747
+
748
+ def update_wiki(args)
749
+ options = {}
750
+ params = {}
751
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
752
+ opts.banner = subcommand_usage("[instance] [options]")
753
+ build_option_type_options(opts, options, update_wiki_page_option_types)
754
+ opts.on('--file FILE', "File containing the wiki content. This can be used instead of --content") do |filename|
755
+ full_filename = File.expand_path(filename)
756
+ if File.exists?(full_filename)
757
+ params['content'] = File.read(full_filename)
758
+ else
759
+ print_red_alert "File not found: #{full_filename}"
760
+ return 1
761
+ end
762
+ # use the filename as the name by default.
763
+ if !params['name']
764
+ params['name'] = File.basename(full_filename)
765
+ end
766
+ end
767
+ opts.on(nil, '--clear', "Clear current page content") do |val|
768
+ params['content'] = ""
769
+ end
770
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
771
+ end
772
+ optparse.parse!(args)
773
+ if args.count != 1
774
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
775
+ return 1
776
+ end
777
+ connect(options)
778
+
779
+ begin
780
+ instance = find_instance_by_name_or_id(args[0])
781
+ return 1 if instance.nil?
782
+ # construct payload
783
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
784
+ payload = nil
785
+ if options[:payload]
786
+ payload = options[:payload]
787
+ payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
788
+ else
789
+ payload = {
790
+ 'page' => {
791
+ }
792
+ }
793
+ # allow arbitrary -O options
794
+ payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
795
+ # prompt for options
796
+ #params = Morpheus::Cli::OptionTypes.prompt(update_wiki_page_option_types, options[:options], @api_client, options[:params])
797
+ #params = passed_options
798
+ params.deep_merge!(passed_options)
799
+
800
+ if params.empty?
801
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
802
+ end
803
+
804
+ payload.deep_merge!({'page' => params}) unless params.empty?
805
+ end
806
+ @instances_interface.setopts(options)
807
+ if options[:dry_run]
808
+ print_dry_run @instances_interface.dry.update_wiki(instance["id"], payload)
809
+ return
810
+ end
811
+ json_response = @instances_interface.update_wiki(instance["id"], payload)
812
+
813
+ if options[:json]
814
+ puts as_json(json_response, options)
815
+ else
816
+ print_green_success "Updated wiki page for instance #{instance['name']}"
817
+ wiki([instance['id']])
818
+ end
819
+ return 0
820
+ rescue RestClient::Exception => e
821
+ print_rest_exception(e, options)
822
+ exit 1
823
+ end
824
+ end
825
+
615
826
  def status_check(args)
616
827
  out = ""
617
828
  options = {}
@@ -733,6 +944,65 @@ class Morpheus::Cli::Instances
733
944
  end
734
945
  end
735
946
 
947
+ def view(args)
948
+ options = {}
949
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
950
+ opts.banner = subcommand_usage("[instance]")
951
+ opts.on('-w','--wiki', "Open the wiki tab for this instance") do
952
+ options[:link_tab] = "wiki"
953
+ end
954
+ opts.on('--tab VALUE', String, "Open a specific tab") do |val|
955
+ options[:link_tab] = val.to_s
956
+ end
957
+ build_common_options(opts, options, [:dry_run, :remote])
958
+ opts.footer = "View an instance in a web browser" + "\n" +
959
+ "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
960
+ end
961
+ optparse.parse!(args)
962
+ if args.count != 1
963
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
964
+ end
965
+ connect(options)
966
+ id_list = parse_id_list(args)
967
+ return run_command_for_each_arg(id_list) do |arg|
968
+ _view(arg, options)
969
+ end
970
+ end
971
+
972
+
973
+ def _view(arg, options={})
974
+ begin
975
+ instance = find_instance_by_name_or_id(arg)
976
+ return 1 if instance.nil?
977
+
978
+ link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/provisioning/instances/#{instance['id']}"
979
+ if options[:link_tab]
980
+ link << "#!#{options[:link_tab]}"
981
+ end
982
+
983
+ open_command = nil
984
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
985
+ open_command = "start #{link}"
986
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
987
+ open_command = "open #{link}"
988
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
989
+ open_command = "xdg-open #{link}"
990
+ end
991
+
992
+ if options[:dry_run]
993
+ puts "system: #{open_command}"
994
+ return 0
995
+ end
996
+
997
+ system(open_command)
998
+
999
+ return 0
1000
+ rescue RestClient::Exception => e
1001
+ print_rest_exception(e, options)
1002
+ exit 1
1003
+ end
1004
+ end
1005
+
736
1006
  def logs(args)
737
1007
  options = {}
738
1008
  optparse = Morpheus::Cli::OptionParser.new do |opts|
@@ -953,6 +1223,12 @@ class Morpheus::Cli::Instances
953
1223
  print_h2 "Instance Notes", options
954
1224
  print cyan, instance['notes'], reset, "\n"
955
1225
  end
1226
+ wiki_page = instance['wikiPage']
1227
+ if wiki_page && wiki_page['content']
1228
+ print_h2 "Instance Wiki", options
1229
+ print cyan, truncate_string(wiki_page['content'], 100), reset, "\n"
1230
+ print " Last updated by #{wiki_page['updatedBy'] ? wiki_page['updatedBy']['username'] : ''} on #{format_local_dt(wiki_page['lastUpdated'])}", reset, "\n"
1231
+ end
956
1232
  if stats
957
1233
  print_h2 "Instance Usage", options
958
1234
  print_stats_usage(stats)
@@ -1243,52 +1519,88 @@ class Morpheus::Cli::Instances
1243
1519
  end
1244
1520
 
1245
1521
  def clone(args)
1246
- options = {}
1522
+ options = {:options => {}}
1247
1523
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1248
1524
  opts.banner = subcommand_usage("[instance] -g GROUP")
1249
- build_option_type_options(opts, options, clone_instance_option_types(false))
1525
+ opts.on('--name VALUE', String, "Name") do |val|
1526
+ options[:options]['name'] = val
1527
+ end
1250
1528
  opts.on( '-g', '--group GROUP', "Group Name or ID for the new instance" ) do |val|
1251
1529
  options[:group] = val
1252
1530
  end
1253
1531
  opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID for the new instance" ) do |val|
1254
1532
  options[:cloud] = val
1255
1533
  end
1256
- build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
1534
+ build_common_options(opts, options, [:options, :payload, :auto_confirm, :json, :dry_run, :remote])
1257
1535
  end
1258
1536
  optparse.parse!(args)
1259
- if args.count < 1
1260
- puts optparse
1261
- return 1
1537
+ if args.count < 1 || args.count > 2
1538
+ raise_command_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args}\n#{optparse}"
1262
1539
  end
1263
- # if !options[:group]
1264
- # print_red_alert "GROUP is required."
1265
- # puts optparse
1266
- # exit 1
1267
- # end
1540
+
1268
1541
  connect(options)
1269
1542
  begin
1543
+ instance = find_instance_by_name_or_id(args[0])
1544
+ return 1 if instance.nil?
1545
+
1270
1546
  options[:options] ||= {}
1547
+
1271
1548
  # use the -g GROUP or active group by default
1272
- options[:options]['group'] ||= options[:group] || @active_group_id
1549
+ #options[:options]['group'] ||= (options[:group] || @active_group_id)
1273
1550
  # support [new-name]
1274
- # if args[1]
1275
- # options[:options]['name'] = args[1]
1276
- # end
1277
- payload = {
1551
+ if args[1]
1552
+ options[:options]['name'] = args[1]
1553
+ end
1554
+ passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
1555
+ payload = {}
1556
+ if options[:payload]
1557
+ payload = options[:payload]
1558
+ else
1559
+ payload = {
1278
1560
 
1279
- }
1280
- params = Morpheus::Cli::OptionTypes.prompt(clone_instance_option_types, options[:options], @api_client, options[:params])
1281
- group = find_group_by_name_or_id_for_provisioning(params.delete('group'))
1282
- payload.merge!(params)
1283
- payload['group'] = {id: group['id']}
1561
+ }
1284
1562
 
1285
- cloud = options[:cloud] ? find_zone_by_name_or_id(nil, options[:cloud]) : nil
1286
- if cloud
1287
- payload['cloud'] = {id: cloud['id']}
1563
+ # Name
1564
+ 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])
1565
+ payload['name'] = v_prompt['name'] unless v_prompt['name'].to_s.empty?
1566
+
1567
+ # Group
1568
+ group = nil
1569
+ if options[:group].nil?
1570
+ 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])
1571
+ options[:group] = v_prompt['group'] unless v_prompt['group'].to_s.empty?
1572
+ else
1573
+ #options[:group] = instance['group']['id']
1574
+ end
1575
+ if options[:group]
1576
+ group = find_group_by_name_or_id_for_provisioning(options[:group])
1577
+ return 1 if group.nil?
1578
+ payload['group'] = {id: group['id']}
1579
+ end
1580
+ # Cloud
1581
+ cloud = nil
1582
+ if group
1583
+ if options[:cloud].nil?
1584
+ 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])
1585
+ options[:cloud] = v_prompt['cloud'] unless v_prompt['cloud'].to_s.empty?
1586
+ else
1587
+ #options[:cloud] = instance['cloud']['id']
1588
+ end
1589
+ cloud = find_zone_by_name_or_id(nil, options[:cloud])
1590
+ return 1 if cloud.nil?
1591
+ if cloud
1592
+ payload['cloud'] = {id: cloud['id']}
1593
+ end
1594
+ end
1595
+
1288
1596
  end
1289
- instance = find_instance_by_name_or_id(args[0])
1290
- unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to clone the instance '#{instance['name']}'?", options)
1291
- exit 1
1597
+ unless passed_options.empty?
1598
+ passed_options.delete('cloud')
1599
+ passed_options.delete('group')
1600
+ payload.deep_merge!(passed_options)
1601
+ end
1602
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to clone the instance #{instance['name']} as '#{payload['name']}'?", options)
1603
+ return 9, "aborted command"
1292
1604
  end
1293
1605
  @instances_interface.setopts(options)
1294
1606
  if options[:dry_run]
@@ -2514,7 +2826,7 @@ class Morpheus::Cli::Instances
2514
2826
  params = {}
2515
2827
  optparse = Morpheus::Cli::OptionParser.new do|opts|
2516
2828
  opts.banner = subcommand_usage("[instance]")
2517
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
2829
+ build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
2518
2830
  opts.footer = "Show scaling threshold information for an instance."
2519
2831
  end
2520
2832
  optparse.parse!(args)
@@ -2531,6 +2843,8 @@ class Morpheus::Cli::Instances
2531
2843
  end
2532
2844
 
2533
2845
  def _scaling(arg, options)
2846
+ params = {}
2847
+ params.merge!(parse_list_options(options))
2534
2848
  instance = find_instance_by_name_or_id(arg)
2535
2849
  return 1 if instance.nil?
2536
2850
  @instances_interface.setopts(options)
@@ -3354,13 +3668,6 @@ private
3354
3668
  end
3355
3669
  end
3356
3670
 
3357
- def clone_instance_option_types(connected=true)
3358
- [
3359
- {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for the new instance'},
3360
- {'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'selectOptions' => (connected ? get_available_groups() : []), 'required' => true},
3361
- ]
3362
- end
3363
-
3364
3671
  def instance_scaling_option_types(instance=nil)
3365
3672
 
3366
3673
  # Group
@@ -3512,5 +3819,12 @@ private
3512
3819
  end
3513
3820
  end
3514
3821
 
3822
+ def update_wiki_page_option_types
3823
+ [
3824
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1, 'description' => 'The name of the wiki page for this instance. Default is the instance name.'},
3825
+ #{'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
3826
+ {'fieldName' => 'content', 'fieldLabel' => 'Content', 'type' => 'textarea', 'required' => false, 'displayOrder' => 3, 'description' => 'The content (markdown) of the wiki page.'}
3827
+ ]
3828
+ end
3515
3829
 
3516
3830
  end