morpheus-cli 3.6.31 → 3.6.32

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.
@@ -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